Date:	Tue, 22 Jun 2010 08:02:43 +0100
From:	"Jan Beulich" <JBeulich@novell.com>
To:	<linux-numa@vger.kernel.org>
Cc:	<trenn@suse.de>
Subject: [PATCH] libnuma: enumerate CPUs correctly

Just matching the first three characters of the directory entries under
/sys/devices/system/cpu/ isn't sufficient, as that also include items
like "cpuidle" and "cpufreq".

Further, just counting entries isn't right, since there may be holes in
the numbering, but the code really is after obtaining the highest
possible CPU number.

(discussion started by (Martin Vogt <martin.vogt@itwm.fraunhofer.de>
 Wed, 10 Mar 2010 and Andi Kleen)

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Thomas Renninger <trenn@suse.de>

---
 libnuma.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

Index: numactl-test/libnuma.c
===================================================================
--- numactl-test.orig/libnuma.c
+++ numactl-test/libnuma.c
@@ -533,7 +533,6 @@ set_numa_max_cpu(void)
 static void
 set_configured_cpus(void)
 {
-	int		filecount=0;
 	char		*dirnamep = "/sys/devices/system/cpu";
 	struct dirent	*dirent;
 	DIR		*dir;
@@ -545,15 +544,19 @@ set_configured_cpus(void)
 		return;
 	}
 	while ((dirent = readdir(dir)) != 0) {
-		if (!strncmp("cpu", dirent->d_name, 3)) {
-			filecount++;
-		} else {
-			continue;
+		if (dirent->d_type == DT_DIR
+		    && !strncmp("cpu", dirent->d_name, 3)) {
+			long cpu = strtol(dirent->d_name + 3, NULL, 10);
+
+			if (cpu < INT_MAX && cpu > maxconfiguredcpu)
+				maxconfiguredcpu = cpu;
 		}
 	}
 	closedir(dir);
-	maxconfiguredcpu = filecount-1; /* high cpu number */
-	return;
+	if (maxconfiguredcpu < 0) {
+		/* fall back to using the online cpu count */
+		maxconfiguredcpu = sysconf(_SC_NPROCESSORS_CONF) - 1;
+	}
 }
 
 /*
