

This patch moves some LRU list handling code out of the swap-code.
These can be used by memory-migration code.

Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug-dave/include/linux/mm_inline.h |   58 ++++++++++++++++++++++++++++++
 memhotplug-dave/mm/vmscan.c               |   39 ++------------------
 2 files changed, 63 insertions(+), 34 deletions(-)

diff -puN include/linux/mm_inline.h~AA-PM-01-steal_page_from_lru include/linux/mm_inline.h
--- memhotplug/include/linux/mm_inline.h~AA-PM-01-steal_page_from_lru	2005-03-28 16:38:08.000000000 -0800
+++ memhotplug-dave/include/linux/mm_inline.h	2005-03-28 16:38:08.000000000 -0800
@@ -38,3 +38,61 @@ del_page_from_lru(struct zone *zone, str
 		zone->nr_inactive--;
 	}
 }
+
+static inline int
+__steal_page_from_lru(struct zone *zone, struct page *page)
+{
+	if (!TestClearPageLRU(page))
+		BUG();
+	list_del(&page->lru);
+	if (get_page_testone(page)) {
+		/*
+		 * It was already free!  release_pages() or put_page()
+		 * are about to remove it from the LRU and free it. So
+		 * put the refcount back and put the page back on the
+		 * LRU
+		 */
+		__put_page(page);
+		SetPageLRU(page);
+		if (PageActive(page))
+			list_add(&page->lru, &zone->active_list);
+		else
+			list_add(&page->lru, &zone->inactive_list);
+		return 0;
+	}
+	if (PageActive(page))
+		zone->nr_active--;
+	else
+		zone->nr_inactive--;
+	return 1;
+}
+
+static inline int
+steal_page_from_lru(struct zone *zone, struct page *page)
+{
+	int ret;
+	spin_lock_irq(&zone->lru_lock);
+	ret = __steal_page_from_lru(zone, page);
+	spin_unlock_irq(&zone->lru_lock);
+	return ret;
+}
+
+static inline void
+__putback_page_to_lru(struct zone *zone, struct page *page)
+{
+	if (TestSetPageLRU(page))
+		BUG();
+	if (PageActive(page))
+		add_page_to_active_list(zone, page);
+	else
+		add_page_to_inactive_list(zone, page);
+}
+
+static inline void
+putback_page_to_lru(struct zone *zone, struct page *page)
+{
+	spin_lock_irq(&zone->lru_lock);
+	__putback_page_to_lru(zone, page);
+	spin_unlock_irq(&zone->lru_lock);
+}
+
diff -puN mm/vmscan.c~AA-PM-01-steal_page_from_lru mm/vmscan.c
--- memhotplug/mm/vmscan.c~AA-PM-01-steal_page_from_lru	2005-03-28 16:38:08.000000000 -0800
+++ memhotplug-dave/mm/vmscan.c	2005-03-28 16:38:08.000000000 -0800
@@ -577,23 +577,11 @@ static void shrink_cache(struct zone *zo
 
 			prefetchw_prev_lru_page(page,
 						&zone->inactive_list, flags);
-
-			if (!TestClearPageLRU(page))
-				BUG();
-			list_del(&page->lru);
-			if (get_page_testone(page)) {
-				/*
-				 * It is being freed elsewhere
-				 */
-				__put_page(page);
-				SetPageLRU(page);
-				list_add(&page->lru, &zone->inactive_list);
+			if (!__steal_page_from_lru(zone, page))
 				continue;
-			}
 			list_add(&page->lru, &page_list);
 			nr_taken++;
 		}
-		zone->nr_inactive -= nr_taken;
 		zone->pages_scanned += nr_scan;
 		spin_unlock_irq(&zone->lru_lock);
 
@@ -617,13 +605,10 @@ static void shrink_cache(struct zone *zo
 		 */
 		while (!list_empty(&page_list)) {
 			page = lru_to_page(&page_list);
-			if (TestSetPageLRU(page))
-				BUG();
 			list_del(&page->lru);
-			if (PageActive(page))
-				add_page_to_active_list(zone, page);
-			else
-				add_page_to_inactive_list(zone, page);
+ 			if (PageActive(page) && page_under_capture(page))
+ 				ClearPageActive(page);
+ 			__putback_page_to_lru(zone, page);
 			if (!pagevec_add(&pvec, page)) {
 				spin_unlock_irq(&zone->lru_lock);
 				__pagevec_release(&pvec);
@@ -676,27 +661,13 @@ refill_inactive_zone(struct zone *zone, 
 	while (pgscanned < nr_pages && !list_empty(&zone->active_list)) {
 		page = lru_to_page(&zone->active_list);
 		prefetchw_prev_lru_page(page, &zone->active_list, flags);
-		if (!TestClearPageLRU(page))
-			BUG();
-		list_del(&page->lru);
-		if (get_page_testone(page)) {
-			/*
-			 * It was already free!  release_pages() or put_page()
-			 * are about to remove it from the LRU and free it. So
-			 * put the refcount back and put the page back on the
-			 * LRU
-			 */
-			__put_page(page);
-			SetPageLRU(page);
-			list_add(&page->lru, &zone->active_list);
-		} else {
+		if (__steal_page_from_lru(zone, page)) {
 			list_add(&page->lru, &l_hold);
 			pgmoved++;
 		}
 		pgscanned++;
 	}
 	zone->pages_scanned += pgscanned;
-	zone->nr_active -= pgmoved;
 	spin_unlock_irq(&zone->lru_lock);
 
 	/*
_
