---
 mm/cpu_alloc.c |   40 +++++++++++++++-------------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

Index: linux-2.6/mm/cpu_alloc.c
===================================================================
--- linux-2.6.orig/mm/cpu_alloc.c	2007-11-03 22:18:12.000000000 -0700
+++ linux-2.6/mm/cpu_alloc.c	2007-11-03 23:11:49.000000000 -0700
@@ -235,6 +235,7 @@ out:
 u8 cpu_area[NR_CPUS * BLOCK_SIZE];
 static DECLARE_BITMAP(cpu_alloc_map, UNITS_PER_BLOCK);
 static int units_free = UNITS_PER_BLOCK;
+#define cpu_alloc_map_order CONFIG_CPU_AREA_ORDER
 #define units_total UNITS_PER_BLOCK
 
 static inline int expand_cpu_area(gfp_t flags)
@@ -243,8 +244,7 @@ static inline int expand_cpu_area(gfp_t 
 }
 #endif
 
-static int end_full_alloc;	/* 0 .. end_full_alloc are all allocated */
-static int begin_all_free;	/* begin_all_free .. units_total are all free */
+static int first_free;		/* First known free unit */
 
 /*
  * How many units are needed for an object of a given size
@@ -285,49 +285,39 @@ void *cpu_alloc(unsigned long size, gfp_
 {
 	unsigned long start;
 	int units = size_to_units(size);
-	unsigned end;
 	void *ptr;
 	int first;
+	unsigned long map_size;
 
 	BUG_ON(gfpflags & ~(GFP_RECLAIM_MASK | __GFP_ZERO));
 	spin_lock(&cpu_alloc_map_lock);
 restart:
+	map_size = PAGE_SIZE << cpu_alloc_map_order;
 	first = 1;
-	start = end_full_alloc;
+	start = first_free;
 	for ( ; ; ) {
-		while (start < units_total &&
-				test_bit(start, cpu_alloc_map))
-			start++;
-
+		start = find_next_zero_bit(cpu_alloc_map, map_size, start);
 		if (first)
-			end_full_alloc = start;
+			first_free = start;
 
-		if (start == units_total) {
+		if (start >= units_total) {
 			if (!expand_cpu_area(gfpflags))
 				goto restart;
 			spin_unlock(&cpu_alloc_map_lock);
 			return NULL;
 		}
 
-		/* Ok we found a free cell */
-		end = start + 1;
 		/* Alignment okay ? */
-		if (start % (align / UNIT_SIZE) == 0) {
-			/* See if we can find enough units for the object */
-			while (end < units_total && end - start < units &&
-					!test_bit(end, cpu_alloc_map))
-				end++;
-			if (end - start == units)
+		if (start % (align / UNIT_SIZE) == 0 &&
+			find_next_bit(cpu_alloc_map, map_size, start + 1)
+							>= start + units);
 				break;
-		}
-		start = end;
+		start++;
 		first = 0;
 	};
 
 	if (first)
-		end_full_alloc = end;
-	if (end > begin_all_free)
-		begin_all_free = end;
+		first_free = start + units;
 
 	set_map(start, units);
 	units_free -= units;
@@ -364,8 +354,8 @@ void cpu_free(void *start, unsigned long
 	clear_map(index, units);
 	units_free += units;
 	__count_vm_events(CPU_BYTES, -units * UNIT_SIZE);
-	if (index < end_full_alloc)
-		end_full_alloc = index;
+	if (index < first_free)
+		first_free = index;
 	spin_unlock(&cpu_alloc_map_lock);
 }
 EXPORT_SYMBOL(cpu_free);