From 4bb0c1315fd51e62d9e9351731f4ce473b227762 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Thu, 28 Nov 2024 14:42:18 +0000 Subject: [PATCH] Sysfeatures: ARM support, CPPC cpufreq driver support and enhanced NUMA balancing --- src/sysFeatures.c | 8 +++- src/sysFeatures_cpufreq.c | 41 +++++++++++++++++++ src/sysFeatures_linux_numa_balancing.c | 54 ++++++++++++++++++++++++-- 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/src/sysFeatures.c b/src/sysFeatures.c index 3dae27b7c..94bf8aab7 100644 --- a/src/sysFeatures.c +++ b/src/sysFeatures.c @@ -70,6 +70,7 @@ static int get_device_access(LikwidDevice_t device) { return -EINVAL; } + switch (device->type) { case DEVICE_TYPE_HWTHREAD: if (device->id.simple.id >= 0 && device->id.simple.id < (int)topo->numHWThreads) @@ -122,11 +123,15 @@ static int get_device_access(LikwidDevice_t device) ERROR_PRINT(get_device_access: Unimplemented device type: %d\n, device->type); return -EPERM; } +#if defined(__x86_64) || defined(__i386__) if (hwt >= 0) { return HPMaddThread(hwt); } return -EINVAL; +#else + return (hwt >= 0 ? 0 : -EINVAL); +#endif } @@ -136,6 +141,7 @@ int likwid_sysft_init(void) topology_init(); CpuInfo_t cpuinfo = get_cpuInfo(); +#if defined(__x86_64) || defined(__i386__) if (!HPMinitialized()) { err = HPMinit(); @@ -163,7 +169,7 @@ int likwid_sysft_init(void) return err; } } - +#endif err = likwid_sysft_init_cpufreq(&_feature_list); if (err < 0) { diff --git a/src/sysFeatures_cpufreq.c b/src/sysFeatures_cpufreq.c index e70e4c3f6..29756c914 100644 --- a/src/sysFeatures_cpufreq.c +++ b/src/sysFeatures_cpufreq.c @@ -301,6 +301,38 @@ static const _SysFeatureList cpufreq_intel_cpufreq_feature_list = { .features = cpufreq_intel_cpufreq_features, }; +/* cppc driver */ + +static int cpufreq_cppc_boost_getter(const LikwidDevice_t device, char** value) +{ + return cpufreq_sysfs_getter(device, value, "boost"); +} + +static int cpufreq_cppc_boost_setter(const LikwidDevice_t device, const char* value) +{ + return cpufreq_sysfs_setter(device, value, "boost"); +} + +static int cpufreq_cppc_test(void) +{ + return cpufreq_driver_test("cppc_cpufreq"); +} + +static _SysFeature cpufreq_cppc_features[] = { + {"cur_cpu_freq", "cpu_freq", "Current CPU frequency", cpufreq_intel_pstate_cur_cpu_freq_getter, NULL, DEVICE_TYPE_HWTHREAD}, + {"min_cpu_freq", "cpu_freq", "Minimal CPU frequency", cpufreq_intel_pstate_min_cpu_freq_getter, cpufreq_intel_pstate_min_cpu_freq_setter, DEVICE_TYPE_HWTHREAD}, + {"max_cpu_freq", "cpu_freq", "Maximal CPU frequency", cpufreq_intel_pstate_max_cpu_freq_getter, cpufreq_intel_pstate_max_cpu_freq_setter, DEVICE_TYPE_HWTHREAD}, + {"boost", "cpu_freq", "Turbo boost", cpufreq_cppc_boost_getter, cpufreq_cppc_boost_setter, DEVICE_TYPE_HWTHREAD}, + {"governor", "cpu_freq", "CPU frequency governor", cpufreq_intel_pstate_governor_getter, cpufreq_intel_pstate_governor_setter, DEVICE_TYPE_HWTHREAD}, + {"avail_governors", "cpu_freq", "Available CPU frequencies", cpufreq_intel_pstate_avail_governors_getter, NULL, DEVICE_TYPE_HWTHREAD}, +}; + +static const _SysFeatureList cpufreq_cppc_feature_list = { + .num_features = ARRAY_COUNT(cpufreq_cppc_features), + .tester = cpufreq_cppc_test, + .features = cpufreq_cppc_features, +}; + /* Energy Performance Preference */ static int cpufreq_epp_test(void) @@ -388,6 +420,15 @@ int likwid_sysft_init_cpufreq(_SysFeatureList* out) return err; } } + else if (cpufreq_cppc_test()) + { + DEBUG_PRINT(DEBUGLEV_DEVELOP, Registering CPPC cpufreq knobs for cpufreq) + likwid_sysft_register_features(out, &cpufreq_cppc_feature_list); + if (err < 0) + { + return err; + } + } if (cpufreq_epp_test()) { diff --git a/src/sysFeatures_linux_numa_balancing.c b/src/sysFeatures_linux_numa_balancing.c index 665f8061a..4ec86420e 100644 --- a/src/sysFeatures_linux_numa_balancing.c +++ b/src/sysFeatures_linux_numa_balancing.c @@ -52,6 +52,7 @@ static int numa_balancing_procfs_getter(const LikwidDevice_t device, char** valu return -EINVAL; } bstring filename = bformat("/proc/sys/kernel/%s", sysfsfile); + DEBUG_PRINT(DEBUGLEV_DEVELOP, Reading file %s, bdata(filename)); #pragma GCC diagnostic ignored "-Wnonnull" if (!access(bdata(filename), R_OK)) { @@ -68,6 +69,20 @@ static int numa_balancing_procfs_getter(const LikwidDevice_t device, char** valu return err; } +static int numa_balancing_procfs_tester(const char* sysfsfile) +{ + int ret = 1; + if (!sysfsfile) + { + return -EINVAL; + } + bstring filename = bformat("/proc/sys/kernel/%s", sysfsfile); +#pragma GCC diagnostic ignored "-Wnonnull" + ret = access(bdata(filename), R_OK); + bdestroy(filename); + return (ret == 0); +} + static int numa_balancing_test(void) { int err = access("/proc/sys/kernel/numa_balancing", F_OK); @@ -98,32 +113,63 @@ static int numa_balancing_state_getter(const LikwidDevice_t device, char** value return numa_balancing_procfs_getter(device, value, "numa_balancing"); } +static int numa_balancing_scan_delay_test() +{ + return numa_balancing_procfs_tester("numa_balancing_scan_delay_ms"); +} + static int numa_balancing_scan_delay_getter(const LikwidDevice_t device, char** value) { return numa_balancing_procfs_getter(device, value, "numa_balancing_scan_delay_ms"); } +static int numa_balancing_scan_period_min_test() +{ + return numa_balancing_procfs_tester("numa_balancing_scan_period_min_ms"); +} + static int numa_balancing_scan_period_min_getter(const LikwidDevice_t device, char** value) { return numa_balancing_procfs_getter(device, value, "numa_balancing_scan_period_min_ms"); } +static int numa_balancing_scan_period_max_test() +{ + return numa_balancing_procfs_tester("numa_balancing_scan_period_max_ms"); +} + static int numa_balancing_scan_period_max_getter(const LikwidDevice_t device, char** value) { return numa_balancing_procfs_getter(device, value, "numa_balancing_scan_period_max_ms"); } +static int numa_balancing_scan_size_test() +{ + return numa_balancing_procfs_tester("numa_balancing_scan_size_mb"); +} + static int numa_balancing_scan_size_getter(const LikwidDevice_t device, char** value) { return numa_balancing_procfs_getter(device, value, "numa_balancing_scan_size_mb"); } +static int numa_balancing_rate_limit_test() +{ + return numa_balancing_procfs_tester("numa_balancing_promote_rate_limit_MBps"); +} + +static int numa_balancing_rate_limit_getter(const LikwidDevice_t device, char** value) +{ + return numa_balancing_procfs_getter(device, value, "numa_balancing_promote_rate_limit_MBps"); +} + static _SysFeature numa_balancing_features[] = { {"numa_balancing", "os", "Current state of NUMA balancing", numa_balancing_state_getter, NULL, DEVICE_TYPE_NODE}, - {"numa_balancing_scan_delay_ms", "os", "Time between page scans", numa_balancing_scan_delay_getter, NULL, DEVICE_TYPE_NODE}, - {"numa_balancing_scan_period_min_ms", "os", "Minimal time for scan period", numa_balancing_scan_period_min_getter, NULL, DEVICE_TYPE_NODE}, - {"numa_balancing_scan_period_max_ms", "os", "Maximal time for scan period", numa_balancing_scan_period_max_getter, NULL, DEVICE_TYPE_NODE}, - {"numa_balancing_scan_size_mb", "os", "Scan size for NUMA balancing", numa_balancing_scan_size_getter, NULL, DEVICE_TYPE_NODE}, + {"numa_balancing_scan_delay_ms", "os", "Time between page scans", numa_balancing_scan_delay_getter, NULL, DEVICE_TYPE_NODE, numa_balancing_scan_delay_test}, + {"numa_balancing_scan_period_min_ms", "os", "Minimal time for scan period", numa_balancing_scan_period_min_getter, NULL, DEVICE_TYPE_NODE, numa_balancing_scan_period_min_test}, + {"numa_balancing_scan_period_max_ms", "os", "Maximal time for scan period", numa_balancing_scan_period_max_getter, NULL, DEVICE_TYPE_NODE, numa_balancing_scan_period_max_test}, + {"numa_balancing_scan_size_mb", "os", "Scan size for NUMA balancing", numa_balancing_scan_size_getter, NULL, DEVICE_TYPE_NODE, numa_balancing_scan_size_test}, + {"numa_balancing_promote_rate_limit", "os", "Rate limit for NUMA balancing", numa_balancing_rate_limit_getter, NULL, DEVICE_TYPE_NODE, numa_balancing_rate_limit_test, "MB/s"}, }; static const _SysFeatureList numa_balancing_feature_list = {