From: Matthew Dobson This patch is in regard to bugme.osdl.org bug 619, link here: http://bugme.osdl.org/show_bug.cgi?id=619 This is the second of two patches to fix this bug. This patch fills in include/linux/topology.h (created in the last patch) with a couple #defines. The patch also creates a generic_hweight64() in include/linux/bitops.h, which we've been lacking for a while. It then uses these new macros in sched.c to ensure that if a node has no CPUs, it is not used in scheduling decisions. include/linux/bitops.h | 27 +++++++++++++++++++++++++++ include/linux/topology.h | 7 +++++++ kernel/sched.c | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) diff -puN include/linux/bitops.h~sched_best_cpu-fix-2 include/linux/bitops.h --- 25/include/linux/bitops.h~sched_best_cpu-fix-2 2003-05-05 19:12:14.000000000 -0700 +++ 25-akpm/include/linux/bitops.h 2003-05-05 19:12:14.000000000 -0700 @@ -107,6 +107,33 @@ static inline unsigned int generic_hweig return (res & 0x0F) + ((res >> 4) & 0x0F); } +#if (BITS_PER_LONG == 64) + +static inline unsigned int generic_hweight64(unsigned int w) +{ + unsigned int res = (w & 0x5555555555555555) + ((w >> 1) & 0x5555555555555555); + res = (res & 0x3333333333333333) + ((res >> 2) & 0x3333333333333333); + res = (res & 0x0F0F0F0F0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F0F0F0F0F); + res = (res & 0x00FF00FF00FF00FF) + ((res >> 8) & 0x00FF00FF00FF00FF); + res = (res & 0x0000FFFF0000FFFF) + ((res >> 16) & 0x0000FFFF0000FFFF); + return (res & 0x00000000FFFFFFFF) + ((res >> 32) & 0x00000000FFFFFFFF); +} + +#define hweight_long(w) generic_hweight64(w) + +#endif /* BITS_PER_LONG == 64 */ + +#if (BITS_PER_LONG == 32) + +static inline unsigned int generic_hweight64(unsigned int *w) +{ + return generic_hweight32(w[0]) + generic_hweight32(w[1]); +} + +#define hweight_long(w) generic_hweight32(w) + +#endif /* BITS_PER_LONG == 32 */ + #include diff -puN include/linux/topology.h~sched_best_cpu-fix-2 include/linux/topology.h --- 25/include/linux/topology.h~sched_best_cpu-fix-2 2003-05-05 19:12:14.000000000 -0700 +++ 25-akpm/include/linux/topology.h 2003-05-05 19:12:14.000000000 -0700 @@ -27,6 +27,13 @@ #ifndef _LINUX_TOPOLOGY_H #define _LINUX_TOPOLOGY_H +#include #include +#define nr_cpus_node(node) (hweight_long(node_to_cpumask(node))) + +#define for_each_node_with_cpus(node) \ + for (node = 0; node < numnodes; node++) \ + if (nr_cpus_node(node) + #endif /* _LINUX_TOPOLOGY_H */ diff -puN kernel/sched.c~sched_best_cpu-fix-2 kernel/sched.c --- 25/kernel/sched.c~sched_best_cpu-fix-2 2003-05-05 19:12:14.000000000 -0700 +++ 25-akpm/kernel/sched.c 2003-05-05 19:12:14.000000000 -0700 @@ -911,7 +911,7 @@ static int sched_best_cpu(struct task_st return best_cpu; minload = 10000000; - for (i = 0; i < numnodes; i++) { + for_each_node_with_cpus(i) { load = atomic_read(&node_nr_running[i]); if (load < minload) { minload = load; _