aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-06-06 13:23:37 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2014-06-06 13:23:37 -0400
commitaabfa10d86f2be6416eabedd03f52b548379f2d6 (patch)
tree34e7263a5e4dbb8f76549adc8f3ab01b0700052b
parentcb9e8e3a4e12150ae0d746dffff5ce0aa4a2daab (diff)
read_mapping() breaks on NR_CPUS not div by 32
This patch fixes a bug in read_mapping(), which is used for reading CPU and cluster (domain) mappings. read_mapping() did not account for the case when NR_CPUS is not evenly divisible by 32 (quite common when NR_CPUS < 32).
-rw-r--r--src/migration.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/src/migration.c b/src/migration.c
index ae7761b..1316d4c 100644
--- a/src/migration.c
+++ b/src/migration.c
@@ -48,14 +48,16 @@ static int read_mapping(int idx, const char* which, cpu_set_t** set, size_t *sz)
48 if (num_online_cpus() > 4096) 48 if (num_online_cpus() > 4096)
49 goto out; 49 goto out;
50 50
51 /* Read string is in the format of <mask>[,<mask>]*. All <mask>s following
52 a comma are 8 chars (representing a 32-bit mask). The first <mask> may
53 have fewer chars. Bits are MSB to LSB, left to right. */
51 snprintf(fname, sizeof(fname), "/proc/litmus/%s/%d", which, idx); 54 snprintf(fname, sizeof(fname), "/proc/litmus/%s/%d", which, idx);
52
53 ret = read_file(fname, &buf, sizeof(buf)-1); 55 ret = read_file(fname, &buf, sizeof(buf)-1);
54 if (ret <= 0) 56 if (ret <= 0)
55 goto out; 57 goto out;
56 58
57 len = strnlen(buf, sizeof(buf)); 59 len = strnlen(buf, sizeof(buf));
58 nbits = 32*(len/9 + 1); /* buf is a series of comma + 32-bits as hex */ 60 nbits = 32*(len/9) + 4*(len%9); /* compute bits, accounting for commas */
59 61
60 *set = CPU_ALLOC(nbits); 62 *set = CPU_ALLOC(nbits);
61 *sz = CPU_ALLOC_SIZE(nbits); 63 *sz = CPU_ALLOC_SIZE(nbits);
@@ -64,17 +66,21 @@ static int read_mapping(int idx, const char* which, cpu_set_t** set, size_t *sz)
64 /* process LSB chunks first (at the end of the str) and move backward */ 66 /* process LSB chunks first (at the end of the str) and move backward */
65 chunk_str = buf + len - 8; 67 chunk_str = buf + len - 8;
66 i = 0; 68 i = 0;
67 while (chunk_str >= buf) { 69 do
68 unsigned long chunk = strtoul(chunk_str, NULL, 16); 70 {
71 unsigned long chunk;
72 if(chunk_str < buf)
73 chunk_str = buf; /* when MSB mask is less than 8 chars */
74 chunk = strtoul(chunk_str, NULL, 16);
69 while (chunk) { 75 while (chunk) {
70 int j = ffsl(chunk) - 1; 76 int j = ffsl(chunk) - 1;
71 CPU_SET_S(i*32 + j, *sz, *set); 77 int x = i*32 + j;
78 CPU_SET_S(x, *sz, *set);
72 chunk &= ~(1ul << j); 79 chunk &= ~(1ul << j);
73 } 80 }
74
75 chunk_str -= 9; 81 chunk_str -= 9;
76 i += 1; 82 i += 1;
77 } 83 } while(chunk_str >= buf - 8);
78 84
79 ret = 0; 85 ret = 0;
80 86