[PATCH] __get_page_state() cpumask cleanup and fix
authorAndrew Morton <akpm@osdl.org>
Wed, 22 Mar 2006 08:07:39 +0000 (00:07 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 22 Mar 2006 15:53:55 +0000 (07:53 -0800)
__get_page_state() has an open-coded for_each_cpu_mask() loop in it.

Tidy that up, then notice that the code was buggy:

while (cpu < NR_CPUS) {
unsigned long *in, *out, off;

if (!cpu_isset(cpu, *cpumask))
continue;

an obvious infinite loop.  I guess we just never call it with a holey cpu
mask.

Even after my cpumask size-reduction work, this patch increases code size :(

Cc: Paul Jackson <pj@sgi.com>
Cc: Christoph Lameter <clameter@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
mm/page_alloc.c

index 234bd48..6177586 100644 (file)
@@ -1214,24 +1214,22 @@ DEFINE_PER_CPU(long, nr_pagecache_local) = 0;
 
 static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
 {
-       int cpu = 0;
+       unsigned cpu;
 
        memset(ret, 0, nr * sizeof(unsigned long));
        cpus_and(*cpumask, *cpumask, cpu_online_map);
 
-       cpu = first_cpu(*cpumask);
-       while (cpu < NR_CPUS) {
-               unsigned long *in, *out, off;
-
-               if (!cpu_isset(cpu, *cpumask))
-                       continue;
+       for_each_cpu_mask(cpu, *cpumask) {
+               unsigned long *in;
+               unsigned long *out;
+               unsigned off;
+               unsigned next_cpu;
 
                in = (unsigned long *)&per_cpu(page_states, cpu);
 
-               cpu = next_cpu(cpu, *cpumask);
-
-               if (likely(cpu < NR_CPUS))
-                       prefetch(&per_cpu(page_states, cpu));
+               next_cpu = next_cpu(cpu, *cpumask);
+               if (likely(next_cpu < NR_CPUS))
+                       prefetch(&per_cpu(page_states, next_cpu));
 
                out = (unsigned long *)ret;
                for (off = 0; off < nr; off++)