Hi
We have observed that numactl comes out with error message when we execute
numactl --physcpubind=6 ./myprogram
It comes out with error message : "cpu argument 6 is out of range"
where myprogram is any program
============================================================
Configuration:
It is a 4 core system and CPU topolgy is as follows:--
[root@p6perfhv4b ~]# cat /proc/cpuinfo
processor : 0
cpu : POWER6 (architected), altivec supported
clock : 4204.000000MHz
revision : 3.1 (pvr 003e 0301)
processor : 2
cpu : POWER6 (architected), altivec supported
clock : 4204.000000MHz
revision : 3.1 (pvr 003e 0301)
processor : 4
cpu : POWER6 (architected), altivec supported
clock : 4204.000000MHz
revision : 3.1 (pvr 003e 0301)
processor : 6
cpu : POWER6 (architected), altivec supported
clock : 4204.000000MHz
revision : 3.1 (pvr 003e 0301)
timebase : 512000000
platform : pSeries
machine : CHRP IBM,8203-E4A
============================================================
Problem Analysis:
when we looked into the code
The problem is noticed as the application(numactl) make as call to glibc
API to get the cpu ID, it returns total number of cores instead of
returning maximum cpu id
numcpus = sysconf(_SC_NPROCESSORS_CONF);
if (arg > numcpus)
complain("cpu argument %d is out of range\n", arg);
============================================================
I am attaching the fix, please review and let me know your thoughts and
suggestions
Thanks
Yeehaw
Index: numactl-0.9.8/Makefile
===================================================================
--- numactl-0.9.8.orig/Makefile 2008-04-22 14:46:54.000000000 +0530
+++ numactl-0.9.8/Makefile 2008-04-22 14:47:22.000000000 +0530
@@ -1,6 +1,6 @@
# these can (and should) be overridden on the make command line for production
# use
-CFLAGS := -g -Wall -O0
+CFLAGS := -g -Wall -O0 -D_GNU_SOURCE
# these are used for the benchmarks in addition to the normal CFLAGS.
# Normally no need to overwrite unless you find a new magic flag to make
# STREAM run faster.
Index: numactl-0.9.8/util.c
===================================================================
--- numactl-0.9.8.orig/util.c 2006-04-04 09:22:26.000000000 +0530
+++ numactl-0.9.8/util.c 2008-04-22 14:48:28.000000000 +0530
@@ -24,7 +24,8 @@
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
-
+#include <sched.h>
+#define GNU_SOURCE
void printmask(char *name, nodemask_t *mask)
{
int i;
@@ -58,7 +59,7 @@
char *end;
if (!numcpus)
- numcpus = sysconf(_SC_NPROCESSORS_CONF);
+ numcpus = get_max_cpu();
int cpubufsize = round_up(numcpus, BITS_PER_LONG) / BYTES_PER_LONG;
unsigned long *cpubuf = calloc(cpubufsize,1);
@@ -114,6 +115,22 @@
return cpubuf;
}
+#define BITS_PER_BYTE 8
+int get_max_cpu(void)
+{
+ int max = 0;
+ int index;
+ cpu_set_t mask;
+ if( numa_sched_getaffinity(0, sizeof(cpu_set_t), &mask) < 0 ){
+ perror("numa_sched_getaffinity:");
+ exit(1);
+ }
+ for(index = 0; index < sizeof(mask) * BITS_PER_BYTE; index++){
+ if(CPU_ISSET(index,&mask)) max = index;
+ }
+ return max;
+}
+
void printcpumask(char *name, unsigned long *mask, int size)
{
int i;
Index: numactl-0.9.8/util.h
===================================================================
--- numactl-0.9.8.orig/util.h 2006-04-04 09:22:26.000000000 +0530
+++ numactl-0.9.8/util.h 2008-04-22 13:57:58.000000000 +0530
@@ -5,6 +5,7 @@
extern int read_sysctl(char *name);
extern void complain(char *fmt, ...);
extern void nerror(char *fmt, ...);
+extern int get_max_cpu(void);
/* defined in main module, but called by util.c */
extern void usage(void);