Skip to content

Commit 0ce0578

Browse files
captain5050acmel
authored andcommitted
perf tools: Fix SMT fallback with large core counts
strtoull can only read a 64-bit bitmap. On an AMD EPYC core_cpus may look like: 00000000,00000000,00000000,00000001,00000000,00000000,00000000,00000001 and so the sibling wasn't spotted. Fix by writing a simple hweight string parser. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: John Garry <john.garry@huawei.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Clarke <pc@us.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: https://lore.kernel.org/r/20211124001231.3277836-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 6d18804 commit 0ce0578

1 file changed

Lines changed: 58 additions & 10 deletions

File tree

tools/perf/util/smt.c

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,56 @@
55
#include "api/fs/fs.h"
66
#include "smt.h"
77

8+
/**
9+
* hweight_str - Returns the number of bits set in str. Stops at first non-hex
10+
* or ',' character.
11+
*/
12+
static int hweight_str(char *str)
13+
{
14+
int result = 0;
15+
16+
while (*str) {
17+
switch (*str++) {
18+
case '0':
19+
case ',':
20+
break;
21+
case '1':
22+
case '2':
23+
case '4':
24+
case '8':
25+
result++;
26+
break;
27+
case '3':
28+
case '5':
29+
case '6':
30+
case '9':
31+
case 'a':
32+
case 'A':
33+
case 'c':
34+
case 'C':
35+
result += 2;
36+
break;
37+
case '7':
38+
case 'b':
39+
case 'B':
40+
case 'd':
41+
case 'D':
42+
case 'e':
43+
case 'E':
44+
result += 3;
45+
break;
46+
case 'f':
47+
case 'F':
48+
result += 4;
49+
break;
50+
default:
51+
goto done;
52+
}
53+
}
54+
done:
55+
return result;
56+
}
57+
858
int smt_on(void)
959
{
1060
static bool cached;
@@ -15,9 +65,12 @@ int smt_on(void)
1565
if (cached)
1666
return cached_result;
1767

18-
if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0)
19-
goto done;
68+
if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0) {
69+
cached = true;
70+
return cached_result;
71+
}
2072

73+
cached_result = 0;
2174
ncpu = sysconf(_SC_NPROCESSORS_CONF);
2275
for (cpu = 0; cpu < ncpu; cpu++) {
2376
unsigned long long siblings;
@@ -35,18 +88,13 @@ int smt_on(void)
3588
continue;
3689
}
3790
/* Entry is hex, but does not have 0x, so need custom parser */
38-
siblings = strtoull(str, NULL, 16);
91+
siblings = hweight_str(str);
3992
free(str);
40-
if (hweight64(siblings) > 1) {
93+
if (siblings > 1) {
4194
cached_result = 1;
42-
cached = true;
4395
break;
4496
}
4597
}
46-
if (!cached) {
47-
cached_result = 0;
48-
done:
49-
cached = true;
50-
}
98+
cached = true;
5199
return cached_result;
52100
}

0 commit comments

Comments
 (0)