forked from pool/numactl
137 lines
3.1 KiB
Diff
137 lines
3.1 KiB
Diff
|
From: Bernhard Walle <bwalle@suse.de>
|
||
|
Subject: [PATCH] Fix "memset fails with 'mbind: Invalid argument'" on PPC64
|
||
|
References: bnc #455977
|
||
|
|
||
|
Backport of
|
||
|
https://bugzilla.novell.com/attachment.cgi?id=264645
|
||
|
|
||
|
|
||
|
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||
|
|
||
|
---
|
||
|
libnuma.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-----------
|
||
|
numaint.h | 1 +
|
||
|
2 files changed, 46 insertions(+), 11 deletions(-)
|
||
|
|
||
|
--- a/libnuma.c
|
||
|
+++ b/libnuma.c
|
||
|
@@ -69,12 +69,37 @@ static int maxprocnode = -1;
|
||
|
static int maxproccpu = -1;
|
||
|
static int nodemask_sz = 0;
|
||
|
static int cpumask_sz = 0;
|
||
|
+static int is_bigendian_64;
|
||
|
|
||
|
int numa_exit_on_error = 0;
|
||
|
int numa_exit_on_warn = 0;
|
||
|
static void set_sizes(void);
|
||
|
|
||
|
/*
|
||
|
+ * return 1 if this machine is big-endian 64-bit
|
||
|
+ */
|
||
|
+int
|
||
|
+big_endian64()
|
||
|
+{
|
||
|
+ union {
|
||
|
+ struct {
|
||
|
+ int a;
|
||
|
+ int b;
|
||
|
+ } ints;
|
||
|
+ struct {
|
||
|
+ long a;
|
||
|
+ } lng;
|
||
|
+ } ua;
|
||
|
+ if (sizeof(long) != 8)
|
||
|
+ return 0;
|
||
|
+ ua.ints.a = 0;
|
||
|
+ ua.ints.b = 3;
|
||
|
+ if (ua.lng.a == 3)
|
||
|
+ return 1;
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
* There are two special functions, _init(void) and _fini(void), which
|
||
|
* are called automatically by the dynamic loader whenever a library is loaded.
|
||
|
*
|
||
|
@@ -91,6 +116,7 @@ numa_init(void)
|
||
|
for (i = 0; i < max; i++)
|
||
|
nodemask_set_compat((nodemask_t *)&numa_all_nodes, i);
|
||
|
memset(&numa_no_nodes, 0, sizeof(numa_no_nodes));
|
||
|
+ is_bigendian_64 = big_endian64();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
@@ -103,10 +129,18 @@ numa_init(void)
|
||
|
static unsigned int
|
||
|
_getbit(const struct bitmask *bmp, unsigned int n)
|
||
|
{
|
||
|
- if (n < bmp->size)
|
||
|
- return (bmp->maskp[n/bitsperlong] >> (n % bitsperlong)) & 1;
|
||
|
- else
|
||
|
- return 0;
|
||
|
+ unsigned long *ip;
|
||
|
+
|
||
|
+ if (n < bmp->size) {
|
||
|
+ if (is_bigendian_64) {
|
||
|
+ ip = bmp->maskp;
|
||
|
+ return (ip[n/bitsperlong] >>
|
||
|
+ (n % bitsperlong)) & 1;
|
||
|
+ } else
|
||
|
+ return (bmp->maskp[n/bitsperlong] >>
|
||
|
+ (n % bitsperlong)) & 1;
|
||
|
+ } else
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
@@ -372,10 +406,10 @@ read_mask(char *s, struct bitmask *bmp)
|
||
|
{
|
||
|
char *end = s;
|
||
|
char *prevend;
|
||
|
- unsigned int *start = (unsigned int *)bmp->maskp;
|
||
|
- unsigned int *p = start;
|
||
|
- unsigned int *q;
|
||
|
- unsigned int i;
|
||
|
+ unsigned long *start = (unsigned long *)bmp->maskp;
|
||
|
+ unsigned long *p = start;
|
||
|
+ unsigned long *q;
|
||
|
+ unsigned long i;
|
||
|
unsigned int n = 0;
|
||
|
|
||
|
i = strtoul(s, &end, 16);
|
||
|
@@ -404,21 +438,21 @@ read_mask(char *s, struct bitmask *bmp)
|
||
|
* is the highest and we put it first because we read it first.
|
||
|
*/
|
||
|
for (q = start + n, p = start; p < q; q--, p++) {
|
||
|
- unsigned int x = *q;
|
||
|
+ unsigned long x = *q;
|
||
|
|
||
|
*q = *p;
|
||
|
*p = x;
|
||
|
}
|
||
|
|
||
|
/* Poor mans fls() */
|
||
|
- for(i = 31; i >= 0; i--)
|
||
|
+ for(i = sizeof(unsigned long)*8 - 1; i >= 0; i--)
|
||
|
if (test_bit(i, start + n))
|
||
|
break;
|
||
|
|
||
|
/*
|
||
|
* Return the last bit set
|
||
|
*/
|
||
|
- return ((sizeof(unsigned int)*8) * n) + i;
|
||
|
+ return ((sizeof(unsigned long)*8) * n) + i;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
--- a/numaint.h
|
||
|
+++ b/numaint.h
|
||
|
@@ -32,6 +32,7 @@ enum numa_warn {
|
||
|
};
|
||
|
|
||
|
#define howmany(x,y) (((x)+((y)-1))/(y))
|
||
|
+#define bitsperint (8 * sizeof(unsigned int))
|
||
|
#define bitsperlong (8 * sizeof(unsigned long))
|
||
|
#define longsperbits(n) howmany(n, bitsperlong)
|
||
|
#define bytesperbits(x) ((x+7)/8)
|