From: Christoph Lameter <clameter@sgi.com>
Subject: Page allocator: Optimize move_freepages() a bit

Move freepages has a strange loop without an increment and a bit of a complicated
control flow with two branches doing the same.

Make it more readable by specifying an increment. Also the skipping over pages is
improved if we use compound_order() to determine the order of allocated page.
Its likely helpful in particular if we have some huge pages around.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

---
 mm/page_alloc.c |   23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c	2007-11-14 20:17:47.000000000 -0800
+++ linux-2.6/mm/page_alloc.c	2007-11-14 20:20:48.000000000 -0800
@@ -707,22 +707,17 @@ int move_freepages(struct zone *zone,
 	BUG_ON(page_zone(start_page) != page_zone(end_page));
 #endif
 
-	for (page = start_page; page <= end_page;) {
-		if (!pfn_valid_within(page_to_pfn(page))) {
-			page++;
-			continue;
-		}
+	for (page = start_page; page <= end_page; page += (1 << order)) {
 
-		if (!PageBuddy(page)) {
-			page++;
-			continue;
-		}
+		if (pfn_valid_within(page_to_pfn(page)) && PageBuddy(page)) {
 
-		order = page_order(page);
-		list_move(&page->lru,
-			&zone->free_area[order].free_list[migratetype]);
-		page += 1 << order;
-		pages_moved += 1 << order;
+			order = page_order(page);
+			list_move(&page->lru,
+				&zone->free_area[order].free_list[migratetype]);
+			pages_moved += 1 << order;
+
+		} else
+			order = compound_order(page);
 	}
 
 	return pages_moved;