Resolves: bz 418551

This commit is contained in:
Neil Horman 2007-12-20 15:13:33 +00:00
parent 3ef07b76b0
commit 9451822cab
4 changed files with 30 additions and 304 deletions

View File

@ -0,0 +1,24 @@
diff -up numactl-1.0.2/syscall.c.orig numactl-1.0.2/syscall.c
--- numactl-1.0.2/syscall.c.orig 2007-12-20 10:07:04.000000000 -0500
+++ numactl-1.0.2/syscall.c 2007-12-20 10:07:28.000000000 -0500
@@ -127,7 +127,7 @@ long syscall6(long call, long a, long b,
#endif
long WEAK get_mempolicy(int *policy,
- const unsigned long *nmask, unsigned long maxnode,
+ unsigned long *nmask, unsigned long maxnode,
void *addr, int flags)
{
return syscall(__NR_get_mempolicy, policy, nmask, maxnode, addr, flags);
diff -up numactl-1.0.2/numaif.h.orig numactl-1.0.2/numaif.h
--- numactl-1.0.2/numaif.h.orig 2007-12-20 10:07:51.000000000 -0500
+++ numactl-1.0.2/numaif.h 2007-12-20 10:07:56.000000000 -0500
@@ -9,7 +9,7 @@ extern "C" {
/* System calls */
extern long get_mempolicy(int *policy,
- const unsigned long *nmask, unsigned long maxnode,
+ unsigned long *nmask, unsigned long maxnode,
void *addr, int flags);
extern long mbind(void *start, unsigned long len, int mode,
const unsigned long *nmask, unsigned long maxnode, unsigned flags);

View File

@ -1,292 +0,0 @@
--- numactl-0.9.8/libnuma.c.orig 2006-08-14 14:14:31.000000000 -0400
+++ numactl-0.9.8/libnuma.c 2006-08-14 14:14:37.000000000 -0400
@@ -118,58 +118,28 @@
static int maxnode = -1;
static int maxcpus = -1;
-static int number_of_cpus(void)
+static int number_of_configured_cpus(void)
{
- char *line = NULL;
- size_t len = 0;
- char *s;
- FILE *f;
- int cpu;
-
+ int len = 16;
+ int n;
+ int olde = errno;
+
if (maxcpus >= 0)
return maxcpus + 1;
- f = fopen("/proc/cpuinfo","r");
- if (!f) {
- int n;
- int len = 8192;
- for (;;) {
- unsigned long buffer[CPU_LONGS(len)];
- memset(buffer, 0, sizeof(buffer));
- n = numa_sched_getaffinity_int(0, CPU_BYTES(len),
- buffer);
- if (n < 0 && errno == EINVAL && len < 1024*1024) {
- len *= 2;
- continue;
- }
- if (n >= 0) {
- int i, k;
- for (i = 0; i < n / sizeof(long); i++) {
- if (!buffer[i])
- continue;
- for (k = 0; k< 8; k++)
- if (buffer[i] & (1<<k))
- maxcpus = i*sizeof(long)+k;
- }
- return maxcpus;
- }
- break;
- }
- numa_warn(W_noproc, "/proc not mounted. Assuming zero nodes: %s",
- strerror(errno));
- return 0;
- }
- maxcpus = 0;
- while (getdelim(&line, &len, '\n', f) > 0) {
- if (strncmp(line,"processor",9))
+ do {
+ unsigned long buffer[CPU_LONGS(len)];
+ memset(buffer, 0, sizeof(buffer));
+ n = numa_sched_getaffinity_int(0, CPU_BYTES(len), buffer);
+ if (n < 0 && errno == EINVAL) {
+ if (len >= 1024*1024)
+ break;
+ len *= 2;
continue;
- s = line + strcspn(line, "0123456789");
- if (sscanf(s, "%d", &cpu) == 1 && cpu > maxcpus)
- maxcpus = cpu;
- }
- free(line);
- fclose(f);
- return maxcpus + 1;
+ }
+ } while (n < 0);
+ errno = olde;
+ return len;
}
static int fallback_max_node(void)
@@ -428,32 +398,67 @@
static unsigned long *node_cpu_mask[NUMA_NUM_NODES];
+static void bad_cpumap(int ncpus, unsigned long *mask)
+{
+ int n;
+ for (n = 0; n < ncpus; n++)
+ set_bit(n, mask);
+}
+
+int numa_parse_bitmap(char *line, unsigned long *mask, int ncpus)
+{
+ int i;
+ char *p = strchr(line, '\n');
+ if (!p)
+ return -1;
+
+ for (i = 0; p > line;i++) {
+ char *oldp, *endp;
+ oldp = p;
+ if (*p == ',')
+ --p;
+ while (p > line && *p != ',')
+ --p;
+ /* Eat two 32bit fields at a time to get longs */
+ if (sizeof(unsigned long) == 8) {
+ oldp--;
+ memmove(p, p+1, oldp-p+1);
+ while (p > line && *p != ',')
+ --p;
+ }
+ if (*p == ',')
+ p++;
+ if (i >= CPU_LONGS(ncpus))
+ return -1;
+ mask[i] = strtoul(p, &endp, 16);
+ if (endp != oldp)
+ return -1;
+ p--;
+ }
+ return 0;
+}
+
/* This would be better with some locking, but I don't want to make libnuma
dependent on pthreads right now. The races are relatively harmless. */
int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen)
{
+ int err = 0;
char fn[64];
FILE *f;
char *line = NULL;
size_t len = 0;
- char *s;
- int n;
int buflen_needed;
- unsigned long *mask, prev;
- int ncpus = number_of_cpus();
- int i;
- int mask_words;
- int bits_in_mask_0;
+ unsigned long *mask;
+ int ncpus = number_of_configured_cpus();
buflen_needed = CPU_BYTES(ncpus);
if ((unsigned)node > maxnode || bufferlen < buflen_needed) {
errno = ERANGE;
return -1;
}
-
+ if (bufferlen > buflen_needed)
+ memset(buffer, 0, bufferlen);
if (node_cpu_mask[node]) {
- if (bufferlen > buflen_needed)
- memset(buffer, 0, bufferlen);
memcpy(buffer, node_cpu_mask[node], buflen_needed);
return 0;
}
@@ -462,73 +467,43 @@
if (!mask)
mask = (unsigned long *)buffer;
memset(mask, 0, buflen_needed);
-
+
sprintf(fn, "/sys/devices/system/node/node%d/cpumap", node);
f = fopen(fn, "r");
if (!f || getdelim(&line, &len, '\n', f) < 1) {
numa_warn(W_nosysfs2,
"/sys not mounted or invalid. Assuming one node: %s",
strerror(errno));
- for (n = 0; n < ncpus; n++)
- set_bit(n, (unsigned long *)mask);
- goto out;
+ bad_cpumap(ncpus, mask);
+ err = -1;
}
- mask_words = 0;
- bits_in_mask_0 = 0;
- n = 0;
- s = line;
- prev = 0;
- for (i = 0; s[i]; i++) {
- static const char hexdigits[] = "0123456789abcdef";
- char *w = strchr(hexdigits, tolower(s[i]));
- if (!w) {
- if (isspace(s[i]) || s[i] == ',')
- continue;
- numa_warn(W_cpumap,
- "Unexpected character `%c' in sysfs cpumap",
- s[i]);
- set_bit(node, mask);
- goto out;
- }
+ if (f)
+ fclose(f);
- /* if mask[0] is full shift left before adding another */
- if (bits_in_mask_0 >= sizeof(mask[0])*8) {
- /* skip any leading zeros */
- if (prev || mask[0]){
- /* shift over any previously loaded masks */
- memmove(mask+mask_words+1, mask+mask_words,
- sizeof(mask[0]) * mask_words);
- mask_words++;
- bits_in_mask_0 = 0;
- mask[0] = 0;
- prev = 1;
- }
- }
-
- mask[0] = (mask[0]*16) + (w - hexdigits);
- bits_in_mask_0 += 4; /* 4 bits per hex char */
+ if (line && numa_parse_bitmap(line, mask, ncpus) < 0) {
+ numa_warn(W_cpumap, "Cannot parse cpumap. Assuming one node");
+ bad_cpumap(ncpus, mask);
+ err = -1;
}
- out:
- free(line);
- if (f)
- fclose(f);
+
+ free(line);
memcpy(buffer, mask, buflen_needed);
/* slightly racy, see above */
if (node_cpu_mask[node]) {
- if (mask != (unsigned long *)buffer)
+ if (mask != buffer)
free(mask);
} else {
- node_cpu_mask[node] = (unsigned long *)mask;
+ node_cpu_mask[node] = mask;
}
- return 0;
+ return err;
}
make_internal_alias(numa_node_to_cpus);
int numa_run_on_node_mask(const nodemask_t *mask)
{
- int ncpus = number_of_cpus();
+ int ncpus = number_of_configured_cpus();
int i, k, err;
unsigned long cpus[CPU_LONGS(ncpus)], nodecpus[CPU_LONGS(ncpus)];
memset(cpus, 0, CPU_BYTES(ncpus));
@@ -582,7 +557,7 @@
nodemask_t numa_get_run_node_mask(void)
{
- int ncpus = number_of_cpus();
+ int ncpus = number_of_configured_cpus();
nodemask_t mask;
int i, k;
int max = numa_max_node_int();
@@ -594,7 +569,7 @@
return numa_no_nodes;
for (i = 0; i <= max; i++) {
if (numa_node_to_cpus_int(i, nodecpus, CPU_BYTES(ncpus)) < 0) {
- numa_warn(W_noderunmask, "Cannot read node cpumask from sysfs");
+ /* It's possible for the node to not exist */
continue;
}
for (k = 0; k < CPU_LONGS(ncpus); k++) {
@@ -612,12 +587,15 @@
int numa_run_on_node(int node)
{
- int ncpus = number_of_cpus();
+ int ncpus = number_of_configured_cpus();
unsigned long cpus[CPU_LONGS(ncpus)];
- if (node == -1)
- memset(cpus, 0xff, CPU_BYTES(ncpus));
- else if (node < NUMA_NUM_NODES) {
+ if (node == -1) {
+ int i;
+ memset(cpus, 0, CPU_BYTES(ncpus));
+ for (i = 0; i < ncpus; i++)
+ cpus[i / BITS_PER_LONG] |= 1UL << (i%BITS_PER_LONG);
+ } else if (node < NUMA_NUM_NODES) {
if (numa_node_to_cpus_int(node, cpus, CPU_BYTES(ncpus)) < 0) {
numa_warn(W_noderunmask, "Cannot read node cpumask from sysfs");
return -1;
@@ -649,7 +627,7 @@
void numa_set_preferred(int node)
{
nodemask_t n;
- if (node == -1) {
+ if (node < 0) {
nodemask_t empty;
nodemask_zero(&empty);
setpol(MPOL_DEFAULT, empty);

View File

@ -1,11 +0,0 @@
--- numactl-0.9.8/numactl-0.9.8/libnuma.c.orig 2006-09-21 12:26:52.000000000 -0400
+++ numactl-0.9.8/numactl-0.9.8/libnuma.c 2006-09-21 12:27:14.000000000 -0400
@@ -420,7 +420,7 @@ int numa_parse_bitmap(char *line, unsign
while (p > line && *p != ',')
--p;
/* Eat two 32bit fields at a time to get longs */
- if (sizeof(unsigned long) == 8) {
+ if (p > line && sizeof(unsigned long) == 8) {
oldp--;
memmove(p, p+1, oldp-p+1);
while (p > line && *p != ',')

View File

@ -1,7 +1,7 @@
Name: numactl
Summary: Library for tuning for Non Uniform Memory Access machines
Version: 1.0.2
Release: 1%{dist}
Release: 2%{dist}
License: LGPLv2/GPLv2
Group: System Environment/Base
URL: ftp://ftp.suse.com/pub/people/ak/numa/
@ -9,6 +9,7 @@ Source0: ftp://ftp.suse.com/pub/people/ak/numa/numactl-%{version}.tar.gz
Buildroot: %{_tmppath}/%{name}-buildroot
ExcludeArch: s390 s390x
Patch0: numactl-1.0.2-get_mempolicy-const.patch
%description
@ -26,6 +27,7 @@ Provides development headers for numa library calls
%prep
%setup -q
%patch0 -p1
%build
make CFLAGS="$RPM_OPT_FLAGS -I. -fPIC"
@ -67,6 +69,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man3/*.3*
%changelog
* Thu Dec 20 2007 Neil Horman <nhorman@redhat.com> - 1.0.2-1
- Update numactl to fix get_mempolicy signature (bz 418551)
* Fri Dec 14 2007 Neil Horman <nhorman@redhat.com> - 1.0.2-1
- Update numactl to latest version (bz 425281)