Re: OOPS: 2.6.16-rc6 cpufreq_conservative

From: Linus Torvalds
Date: Sun Mar 19 2006 - 13:44:24 EST




On Sat, 18 Mar 2006, Linus Torvalds wrote:
>
> The thing is, we could do _so_ much better if we just fixed the "calling
> convention" for that loop.

Actually, looking at it a bit more, I think we can do better even
_without_ fixing the "calling convention".

Namely like this.

This should make the "NR_CPUS <= 16" case have a _much_ simpler loop.

I picked "16" at random. The loop is much faster and much simpler (it
doesn't use complex instructions like "find first bit", but the downside
is that if the CPU mask is very sparse, it will take more of those (very
simple) iterations to figure out that it's empty.

I suspect the "16" could be raised to 32 (at which point it would cover
all the default vaules), but somebody should probably take a look at
how much this shrinks the kernel.

I have to admit that it's a bit evil to leave a dangling "else" in a
macro, but it beautifully handles the "must be followed by exactly one C
statement" requirement of the old macro ;)

So instead of calling it "evil", let's just say that it's "creative
macro-writing".

(Btw, we could make this even cleaner by making the non-SMP case define
"cpu_isset()" to 1 - at that point the UP and the "low CPU count" #defines
could be merged into one).

Linus

--
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 60e56c6..a659f42 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -313,11 +313,17 @@ static inline void __cpus_remap(cpumask_
bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
}

-#if NR_CPUS > 1
+#if NR_CPUS > 16
#define for_each_cpu_mask(cpu, mask) \
for ((cpu) = first_cpu(mask); \
(cpu) < NR_CPUS; \
(cpu) = next_cpu((cpu), (mask)))
+#elif NR_CPUS > 1
+#define for_each_cpu_mask(cpu, mask) \
+ for ((cpu) = 0; (cpu) < NR_CPUS; (cpu)++) \
+ if (!cpu_isset(cpu, mask)) \
+ continue; \
+ else
#else /* NR_CPUS == 1 */
#define for_each_cpu_mask(cpu, mask) for ((cpu) = 0; (cpu) < 1; (cpu)++)
#endif /* NR_CPUS */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/