^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include "api/fs/fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "smt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) int smt_on(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static bool cached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static int cached_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) int ncpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) if (cached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return cached_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) ncpu = sysconf(_SC_NPROCESSORS_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) for (cpu = 0; cpu < ncpu; cpu++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) unsigned long long siblings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) size_t strlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) char fn[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) snprintf(fn, sizeof fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) "devices/system/cpu/cpu%d/topology/core_cpus", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (sysfs__read_str(fn, &str, &strlen) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) snprintf(fn, sizeof fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) "devices/system/cpu/cpu%d/topology/thread_siblings",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (sysfs__read_str(fn, &str, &strlen) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Entry is hex, but does not have 0x, so need custom parser */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) siblings = strtoull(str, NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (hweight64(siblings) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) cached_result = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) cached = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!cached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) cached_result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) cached = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return cached_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }