Previously, bpf_num_possible_cpus() had a bug when calculating a number of possible CPUs in the case of sparse CPU allocations, as it was considering only the first range or element of /sys/devices/system/cpu/possible. E.g. in the case of "0,2-3" (CPU 1 is not available), the function returned 1 instead of 3. This patch fixes the function by making it parse all CPU ranges and elements.
Showing the changes to tools/testing (1 of 1 file). Show all
Unified · Split
| @@ -13,7 +13,7 @@ static inline unsigned int bpf_num_possible_cpus(void) · 12 unmodified lines | ||
| 13 | 13 | unsigned int start, end, possible_cpus = 0; |
| 14 | 14 | char buff[128]; |
| 15 | 15 | FILE *fp; |
| 16 | − int n; | |
| 16 | + int len, n, i, j = 0; | |
| 17 | 17 | |
| 18 | 18 | fp = fopen(fcpu, "r"); |
| 19 | 19 | if (!fp) { |
| @@ -21,17 +21,27 @@ static inline unsigned int bpf_num_possible_cpus(void) · 1 unmodified line | ||
| 21 | 21 | exit(1); |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | − while (fgets(buff, sizeof(buff), fp)) { | |
| 25 | − n = sscanf(buff, "%u-%u", &start, &end); | |
| 26 | − if (n == 0) { | |
| 27 | − printf("Failed to retrieve # possible CPUs!\n"); | |
| 28 | − exit(1); | |
| 29 | − } else if (n == 1) { | |
| 30 | − end = start; | |
| 24 | + if (!fgets(buff, sizeof(buff), fp)) { | |
| 25 | + printf("Failed to read %s!\n", fcpu); | |
| 26 | + exit(1); | |
| 27 | + } | |
| 28 | + | |
| 29 | + len = strlen(buff); | |
| 30 | + for (i = 0; i <= len; i++) { | |
| 31 | + if (buff[i] == ',' || buff[i] == '\0') { | |
| 32 | + buff[i] = '\0'; | |
| 33 | + n = sscanf(&buff[j], "%u-%u", &start, &end); | |
| 34 | + if (n <= 0) { | |
| 35 | + printf("Failed to retrieve # possible CPUs!\n"); | |
| 36 | + exit(1); | |
| 37 | + } else if (n == 1) { | |
| 38 | + end = start; | |
| 39 | + } | |
| 40 | + possible_cpus += end - start + 1; | |
| 41 | + j = i + 1; | |
| 31 | 42 | } |
| 32 | − possible_cpus = start == 0 ? end + 1 : 0; | |
| 33 | − break; | |
| 34 | 43 | } |
| 44 | + | |
| 35 | 45 | fclose(fp); |
| 36 | 46 | |
| 37 | 47 | return possible_cpus; |