
From: Matthew Dobson <colpatch@us.ibm.com>

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 <asm/bitops.h>
 
 
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 <linux/bitops.h>
 #include <asm/topology.h>
 
+#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;

_
