Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'linux-kselftest-next-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kselftest updates from Shuah Khan:
"Fixes and new tests:

- Add an amd-pstate-ut test module, used by kselftest to unit test
amd-pstate functionality

- Fixes and cleanups to to cpu-hotplug to delete the fault injection
test code

- Improvements to vm test to use top_srcdir for builds"

* tag 'linux-kselftest-next-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
docs:kselftest: fix kselftest_module.h path of example module
cpufreq: amd-pstate: Add explanation for X86_AMD_PSTATE_UT
selftests/cpu-hotplug: Add log info when test success
selftests/cpu-hotplug: Reserve one cpu online at least
selftests/cpu-hotplug: Delete fault injection related code
selftests/cpu-hotplug: Use return instead of exit
selftests/cpu-hotplug: Correct log info
cpufreq: amd-pstate: modify type in argument 2 for filp_open
Documentation: amd-pstate: Add unit test introduction
selftests: amd-pstate: Add test trigger for amd-pstate driver
cpufreq: amd-pstate: Add test module for amd-pstate driver
cpufreq: amd-pstate: Expose struct amd_cpudata
selftests/vm: use top_srcdir instead of recomputing relative paths

+574 -171
+76
Documentation/admin-guide/pm/amd-pstate.rst
··· 182 182 Then, ``amd-pstate`` updates the desired performance according to the CPU 183 183 scheduler assigned. 184 184 185 + .. _processor_support: 185 186 186 187 Processor Support 187 188 ======================= ··· 282 281 283 282 Kernel Module Options for ``amd-pstate`` 284 283 ========================================= 284 + 285 + .. _shared_mem: 285 286 286 287 ``shared_mem`` 287 288 Use a module param (shared_mem) to enable related processors manually with ··· 396 393 CPU_005 712 116384 39 49 166 0.7565 9645075 2214891 38431470 25.1 11.646 469 2.496 kworker/5:0-40 397 394 CPU_006 712 116408 39 49 166 0.6769 8950227 1839034 37192089 24.06 11.272 470 2.496 kworker/6:0-1264 398 395 396 + Unit Tests for amd-pstate 397 + ------------------------- 398 + 399 + ``amd-pstate-ut`` is a test module for testing the ``amd-pstate`` driver. 400 + 401 + * It can help all users to verify their processor support (SBIOS/Firmware or Hardware). 402 + 403 + * Kernel can have a basic function test to avoid the kernel regression during the update. 404 + 405 + * We can introduce more functional or performance tests to align the result together, it will benefit power and performance scale optimization. 406 + 407 + 1. Test case decriptions 408 + 409 + +---------+--------------------------------+------------------------------------------------------------------------------------+ 410 + | Index | Functions | Description | 411 + +=========+================================+====================================================================================+ 412 + | 0 | amd_pstate_ut_acpi_cpc_valid || Check whether the _CPC object is present in SBIOS. | 413 + | | || | 414 + | | || The detail refer to `Processor Support <processor_support_>`_. | 415 + +---------+--------------------------------+------------------------------------------------------------------------------------+ 416 + | 1 | amd_pstate_ut_check_enabled || Check whether AMD P-State is enabled. | 417 + | | || | 418 + | | || AMD P-States and ACPI hardware P-States always can be supported in one processor. | 419 + | | | But AMD P-States has the higher priority and if it is enabled with | 420 + | | | :c:macro:`MSR_AMD_CPPC_ENABLE` or ``cppc_set_enable``, it will respond to the | 421 + | | | request from AMD P-States. | 422 + +---------+--------------------------------+------------------------------------------------------------------------------------+ 423 + | 2 | amd_pstate_ut_check_perf || Check if the each performance values are reasonable. | 424 + | | || highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0. | 425 + +---------+--------------------------------+------------------------------------------------------------------------------------+ 426 + | 3 | amd_pstate_ut_check_freq || Check if the each frequency values and max freq when set support boost mode | 427 + | | | are reasonable. | 428 + | | || max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 | 429 + | | || If boost is not active but supported, this maximum frequency will be larger than | 430 + | | | the one in ``cpuinfo``. | 431 + +---------+--------------------------------+------------------------------------------------------------------------------------+ 432 + 433 + #. How to execute the tests 434 + 435 + We use test module in the kselftest frameworks to implement it. 436 + We create amd-pstate-ut module and tie it into kselftest.(for 437 + details refer to Linux Kernel Selftests [4]_). 438 + 439 + 1. Build 440 + 441 + + open the :c:macro:`CONFIG_X86_AMD_PSTATE` configuration option. 442 + + set the :c:macro:`CONFIG_X86_AMD_PSTATE_UT` configuration option to M. 443 + + make project 444 + + make selftest :: 445 + 446 + $ cd linux 447 + $ make -C tools/testing/selftests 448 + 449 + #. Installation & Steps :: 450 + 451 + $ make -C tools/testing/selftests install INSTALL_PATH=~/kselftest 452 + $ sudo ./kselftest/run_kselftest.sh -c amd-pstate 453 + TAP version 13 454 + 1..1 455 + # selftests: amd-pstate: amd-pstate-ut.sh 456 + # amd-pstate-ut: ok 457 + ok 1 selftests: amd-pstate: amd-pstate-ut.sh 458 + 459 + #. Results :: 460 + 461 + $ dmesg | grep "amd_pstate_ut" | tee log.txt 462 + [12977.570663] amd_pstate_ut: 1 amd_pstate_ut_acpi_cpc_valid success! 463 + [12977.570673] amd_pstate_ut: 2 amd_pstate_ut_check_enabled success! 464 + [12977.571207] amd_pstate_ut: 3 amd_pstate_ut_check_perf success! 465 + [12977.571212] amd_pstate_ut: 4 amd_pstate_ut_check_freq success! 399 466 400 467 Reference 401 468 =========== ··· 478 405 479 406 .. [3] Processor Programming Reference (PPR) for AMD Family 19h Model 51h, Revision A1 Processors 480 407 https://www.amd.com/system/files/TechDocs/56569-A1-PUB.zip 408 + 409 + .. [4] Linux Kernel Selftests, 410 + https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html
+1 -1
Documentation/dev-tools/kselftest.rst
··· 320 320 321 321 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 322 322 323 - #include "../tools/testing/selftests/kselftest/module.h" 323 + #include "../tools/testing/selftests/kselftest_module.h" 324 324 325 325 KSTM_MODULE_GLOBALS(); 326 326
+1
MAINTAINERS
··· 1070 1070 S: Supported 1071 1071 F: Documentation/admin-guide/pm/amd-pstate.rst 1072 1072 F: drivers/cpufreq/amd-pstate* 1073 + F: include/linux/amd-pstate.h 1073 1074 F: tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py 1074 1075 1075 1076 AMD PTDMA DRIVER
+15
drivers/cpufreq/Kconfig.x86
··· 51 51 52 52 If in doubt, say N. 53 53 54 + config X86_AMD_PSTATE_UT 55 + tristate "selftest for AMD Processor P-State driver" 56 + depends on X86 && ACPI_PROCESSOR 57 + default n 58 + help 59 + This kernel module is used for testing. It's safe to say M here. 60 + 61 + It can also be built-in without X86_AMD_PSTATE enabled. 62 + Currently, only tests for amd-pstate are supported. If X86_AMD_PSTATE 63 + is set disabled, it can tell the users test can only run on amd-pstate 64 + driver, please set X86_AMD_PSTATE enabled. 65 + In the future, comparison tests will be added. It can set amd-pstate 66 + disabled and set acpi-cpufreq enabled to run test cases, then compare 67 + the test results. 68 + 54 69 config X86_ACPI_CPUFREQ 55 70 tristate "ACPI Processor P-States driver" 56 71 depends on ACPI_PROCESSOR
+1
drivers/cpufreq/Makefile
··· 30 30 31 31 obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o 32 32 obj-$(CONFIG_X86_AMD_PSTATE) += amd_pstate.o 33 + obj-$(CONFIG_X86_AMD_PSTATE_UT) += amd-pstate-ut.o 33 34 obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o 34 35 obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o 35 36 obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
+293
drivers/cpufreq/amd-pstate-ut.c
··· 1 + // SPDX-License-Identifier: GPL-1.0-or-later 2 + /* 3 + * AMD Processor P-state Frequency Driver Unit Test 4 + * 5 + * Copyright (C) 2022 Advanced Micro Devices, Inc. All Rights Reserved. 6 + * 7 + * Author: Meng Li <li.meng@amd.com> 8 + * 9 + * The AMD P-State Unit Test is a test module for testing the amd-pstate 10 + * driver. 1) It can help all users to verify their processor support 11 + * (SBIOS/Firmware or Hardware). 2) Kernel can have a basic function 12 + * test to avoid the kernel regression during the update. 3) We can 13 + * introduce more functional or performance tests to align the result 14 + * together, it will benefit power and performance scale optimization. 15 + * 16 + * This driver implements basic framework with plans to enhance it with 17 + * additional test cases to improve the depth and coverage of the test. 18 + * 19 + * See Documentation/admin-guide/pm/amd-pstate.rst Unit Tests for 20 + * amd-pstate to get more detail. 21 + */ 22 + 23 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 + 25 + #include <linux/kernel.h> 26 + #include <linux/module.h> 27 + #include <linux/moduleparam.h> 28 + #include <linux/fs.h> 29 + #include <linux/amd-pstate.h> 30 + 31 + #include <acpi/cppc_acpi.h> 32 + 33 + /* 34 + * Abbreviations: 35 + * amd_pstate_ut: used as a shortform for AMD P-State unit test. 36 + * It helps to keep variable names smaller, simpler 37 + */ 38 + enum amd_pstate_ut_result { 39 + AMD_PSTATE_UT_RESULT_PASS, 40 + AMD_PSTATE_UT_RESULT_FAIL, 41 + }; 42 + 43 + struct amd_pstate_ut_struct { 44 + const char *name; 45 + void (*func)(u32 index); 46 + enum amd_pstate_ut_result result; 47 + }; 48 + 49 + /* 50 + * Kernel module for testing the AMD P-State unit test 51 + */ 52 + static void amd_pstate_ut_acpi_cpc_valid(u32 index); 53 + static void amd_pstate_ut_check_enabled(u32 index); 54 + static void amd_pstate_ut_check_perf(u32 index); 55 + static void amd_pstate_ut_check_freq(u32 index); 56 + 57 + static struct amd_pstate_ut_struct amd_pstate_ut_cases[] = { 58 + {"amd_pstate_ut_acpi_cpc_valid", amd_pstate_ut_acpi_cpc_valid }, 59 + {"amd_pstate_ut_check_enabled", amd_pstate_ut_check_enabled }, 60 + {"amd_pstate_ut_check_perf", amd_pstate_ut_check_perf }, 61 + {"amd_pstate_ut_check_freq", amd_pstate_ut_check_freq } 62 + }; 63 + 64 + static bool get_shared_mem(void) 65 + { 66 + bool result = false; 67 + char path[] = "/sys/module/amd_pstate/parameters/shared_mem"; 68 + char buf[5] = {0}; 69 + struct file *filp = NULL; 70 + loff_t pos = 0; 71 + ssize_t ret; 72 + 73 + if (!boot_cpu_has(X86_FEATURE_CPPC)) { 74 + filp = filp_open(path, O_RDONLY, 0); 75 + if (IS_ERR(filp)) 76 + pr_err("%s unable to open %s file!\n", __func__, path); 77 + else { 78 + ret = kernel_read(filp, &buf, sizeof(buf), &pos); 79 + if (ret < 0) 80 + pr_err("%s read %s file fail ret=%ld!\n", 81 + __func__, path, (long)ret); 82 + filp_close(filp, NULL); 83 + } 84 + 85 + if ('Y' == *buf) 86 + result = true; 87 + } 88 + 89 + return result; 90 + } 91 + 92 + /* 93 + * check the _CPC object is present in SBIOS. 94 + */ 95 + static void amd_pstate_ut_acpi_cpc_valid(u32 index) 96 + { 97 + if (acpi_cpc_valid()) 98 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 99 + else { 100 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 101 + pr_err("%s the _CPC object is not present in SBIOS!\n", __func__); 102 + } 103 + } 104 + 105 + static void amd_pstate_ut_pstate_enable(u32 index) 106 + { 107 + int ret = 0; 108 + u64 cppc_enable = 0; 109 + 110 + ret = rdmsrl_safe(MSR_AMD_CPPC_ENABLE, &cppc_enable); 111 + if (ret) { 112 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 113 + pr_err("%s rdmsrl_safe MSR_AMD_CPPC_ENABLE ret=%d error!\n", __func__, ret); 114 + return; 115 + } 116 + if (cppc_enable) 117 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 118 + else { 119 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 120 + pr_err("%s amd pstate must be enabled!\n", __func__); 121 + } 122 + } 123 + 124 + /* 125 + * check if amd pstate is enabled 126 + */ 127 + static void amd_pstate_ut_check_enabled(u32 index) 128 + { 129 + if (get_shared_mem()) 130 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 131 + else 132 + amd_pstate_ut_pstate_enable(index); 133 + } 134 + 135 + /* 136 + * check if performance values are reasonable. 137 + * highest_perf >= nominal_perf > lowest_nonlinear_perf > lowest_perf > 0 138 + */ 139 + static void amd_pstate_ut_check_perf(u32 index) 140 + { 141 + int cpu = 0, ret = 0; 142 + u32 highest_perf = 0, nominal_perf = 0, lowest_nonlinear_perf = 0, lowest_perf = 0; 143 + u64 cap1 = 0; 144 + struct cppc_perf_caps cppc_perf; 145 + struct cpufreq_policy *policy = NULL; 146 + struct amd_cpudata *cpudata = NULL; 147 + 148 + highest_perf = amd_get_highest_perf(); 149 + 150 + for_each_possible_cpu(cpu) { 151 + policy = cpufreq_cpu_get(cpu); 152 + if (!policy) 153 + break; 154 + cpudata = policy->driver_data; 155 + 156 + if (get_shared_mem()) { 157 + ret = cppc_get_perf_caps(cpu, &cppc_perf); 158 + if (ret) { 159 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 160 + pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret); 161 + return; 162 + } 163 + 164 + nominal_perf = cppc_perf.nominal_perf; 165 + lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf; 166 + lowest_perf = cppc_perf.lowest_perf; 167 + } else { 168 + ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1); 169 + if (ret) { 170 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 171 + pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret); 172 + return; 173 + } 174 + 175 + nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1); 176 + lowest_nonlinear_perf = AMD_CPPC_LOWNONLIN_PERF(cap1); 177 + lowest_perf = AMD_CPPC_LOWEST_PERF(cap1); 178 + } 179 + 180 + if ((highest_perf != READ_ONCE(cpudata->highest_perf)) || 181 + (nominal_perf != READ_ONCE(cpudata->nominal_perf)) || 182 + (lowest_nonlinear_perf != READ_ONCE(cpudata->lowest_nonlinear_perf)) || 183 + (lowest_perf != READ_ONCE(cpudata->lowest_perf))) { 184 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 185 + pr_err("%s cpu%d highest=%d %d nominal=%d %d lowest_nonlinear=%d %d lowest=%d %d, they should be equal!\n", 186 + __func__, cpu, highest_perf, cpudata->highest_perf, 187 + nominal_perf, cpudata->nominal_perf, 188 + lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf, 189 + lowest_perf, cpudata->lowest_perf); 190 + return; 191 + } 192 + 193 + if (!((highest_perf >= nominal_perf) && 194 + (nominal_perf > lowest_nonlinear_perf) && 195 + (lowest_nonlinear_perf > lowest_perf) && 196 + (lowest_perf > 0))) { 197 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 198 + pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n", 199 + __func__, cpu, highest_perf, nominal_perf, 200 + lowest_nonlinear_perf, lowest_perf); 201 + return; 202 + } 203 + } 204 + 205 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 206 + } 207 + 208 + /* 209 + * Check if frequency values are reasonable. 210 + * max_freq >= nominal_freq > lowest_nonlinear_freq > min_freq > 0 211 + * check max freq when set support boost mode. 212 + */ 213 + static void amd_pstate_ut_check_freq(u32 index) 214 + { 215 + int cpu = 0; 216 + struct cpufreq_policy *policy = NULL; 217 + struct amd_cpudata *cpudata = NULL; 218 + 219 + for_each_possible_cpu(cpu) { 220 + policy = cpufreq_cpu_get(cpu); 221 + if (!policy) 222 + break; 223 + cpudata = policy->driver_data; 224 + 225 + if (!((cpudata->max_freq >= cpudata->nominal_freq) && 226 + (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) && 227 + (cpudata->lowest_nonlinear_freq > cpudata->min_freq) && 228 + (cpudata->min_freq > 0))) { 229 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 230 + pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", 231 + __func__, cpu, cpudata->max_freq, cpudata->nominal_freq, 232 + cpudata->lowest_nonlinear_freq, cpudata->min_freq); 233 + return; 234 + } 235 + 236 + if (cpudata->min_freq != policy->min) { 237 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 238 + pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n", 239 + __func__, cpu, cpudata->min_freq, policy->min); 240 + return; 241 + } 242 + 243 + if (cpudata->boost_supported) { 244 + if ((policy->max == cpudata->max_freq) || 245 + (policy->max == cpudata->nominal_freq)) 246 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 247 + else { 248 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 249 + pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", 250 + __func__, cpu, policy->max, cpudata->max_freq, 251 + cpudata->nominal_freq); 252 + return; 253 + } 254 + } else { 255 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; 256 + pr_err("%s cpu%d must support boost!\n", __func__, cpu); 257 + return; 258 + } 259 + } 260 + 261 + amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; 262 + } 263 + 264 + static int __init amd_pstate_ut_init(void) 265 + { 266 + u32 i = 0, arr_size = ARRAY_SIZE(amd_pstate_ut_cases); 267 + 268 + for (i = 0; i < arr_size; i++) { 269 + amd_pstate_ut_cases[i].func(i); 270 + switch (amd_pstate_ut_cases[i].result) { 271 + case AMD_PSTATE_UT_RESULT_PASS: 272 + pr_info("%-4d %-20s\t success!\n", i+1, amd_pstate_ut_cases[i].name); 273 + break; 274 + case AMD_PSTATE_UT_RESULT_FAIL: 275 + default: 276 + pr_info("%-4d %-20s\t fail!\n", i+1, amd_pstate_ut_cases[i].name); 277 + break; 278 + } 279 + } 280 + 281 + return 0; 282 + } 283 + 284 + static void __exit amd_pstate_ut_exit(void) 285 + { 286 + } 287 + 288 + module_init(amd_pstate_ut_init); 289 + module_exit(amd_pstate_ut_exit); 290 + 291 + MODULE_AUTHOR("Meng Li <li.meng@amd.com>"); 292 + MODULE_DESCRIPTION("AMD P-state driver Test module"); 293 + MODULE_LICENSE("GPL");
+1 -59
drivers/cpufreq/amd-pstate.c
··· 36 36 #include <linux/delay.h> 37 37 #include <linux/uaccess.h> 38 38 #include <linux/static_call.h> 39 + #include <linux/amd-pstate.h> 39 40 40 41 #include <acpi/processor.h> 41 42 #include <acpi/cppc_acpi.h> ··· 65 64 "enable amd-pstate on processors with shared memory solution (false = disabled (default), true = enabled)"); 66 65 67 66 static struct cpufreq_driver amd_pstate_driver; 68 - 69 - /** 70 - * struct amd_aperf_mperf 71 - * @aperf: actual performance frequency clock count 72 - * @mperf: maximum performance frequency clock count 73 - * @tsc: time stamp counter 74 - */ 75 - struct amd_aperf_mperf { 76 - u64 aperf; 77 - u64 mperf; 78 - u64 tsc; 79 - }; 80 - 81 - /** 82 - * struct amd_cpudata - private CPU data for AMD P-State 83 - * @cpu: CPU number 84 - * @req: constraint request to apply 85 - * @cppc_req_cached: cached performance request hints 86 - * @highest_perf: the maximum performance an individual processor may reach, 87 - * assuming ideal conditions 88 - * @nominal_perf: the maximum sustained performance level of the processor, 89 - * assuming ideal operating conditions 90 - * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power 91 - * savings are achieved 92 - * @lowest_perf: the absolute lowest performance level of the processor 93 - * @max_freq: the frequency that mapped to highest_perf 94 - * @min_freq: the frequency that mapped to lowest_perf 95 - * @nominal_freq: the frequency that mapped to nominal_perf 96 - * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf 97 - * @cur: Difference of Aperf/Mperf/tsc count between last and current sample 98 - * @prev: Last Aperf/Mperf/tsc count value read from register 99 - * @freq: current cpu frequency value 100 - * @boost_supported: check whether the Processor or SBIOS supports boost mode 101 - * 102 - * The amd_cpudata is key private data for each CPU thread in AMD P-State, and 103 - * represents all the attributes and goals that AMD P-State requests at runtime. 104 - */ 105 - struct amd_cpudata { 106 - int cpu; 107 - 108 - struct freq_qos_request req[2]; 109 - u64 cppc_req_cached; 110 - 111 - u32 highest_perf; 112 - u32 nominal_perf; 113 - u32 lowest_nonlinear_perf; 114 - u32 lowest_perf; 115 - 116 - u32 max_freq; 117 - u32 min_freq; 118 - u32 nominal_freq; 119 - u32 lowest_nonlinear_freq; 120 - 121 - struct amd_aperf_mperf cur; 122 - struct amd_aperf_mperf prev; 123 - 124 - u64 freq; 125 - bool boost_supported; 126 - }; 127 67 128 68 static inline int pstate_enable(bool enable) 129 69 {
+77
include/linux/amd-pstate.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * linux/include/linux/amd-pstate.h 4 + * 5 + * Copyright (C) 2022 Advanced Micro Devices, Inc. 6 + * 7 + * Author: Meng Li <li.meng@amd.com> 8 + */ 9 + 10 + #ifndef _LINUX_AMD_PSTATE_H 11 + #define _LINUX_AMD_PSTATE_H 12 + 13 + #include <linux/pm_qos.h> 14 + 15 + /********************************************************************* 16 + * AMD P-state INTERFACE * 17 + *********************************************************************/ 18 + /** 19 + * struct amd_aperf_mperf 20 + * @aperf: actual performance frequency clock count 21 + * @mperf: maximum performance frequency clock count 22 + * @tsc: time stamp counter 23 + */ 24 + struct amd_aperf_mperf { 25 + u64 aperf; 26 + u64 mperf; 27 + u64 tsc; 28 + }; 29 + 30 + /** 31 + * struct amd_cpudata - private CPU data for AMD P-State 32 + * @cpu: CPU number 33 + * @req: constraint request to apply 34 + * @cppc_req_cached: cached performance request hints 35 + * @highest_perf: the maximum performance an individual processor may reach, 36 + * assuming ideal conditions 37 + * @nominal_perf: the maximum sustained performance level of the processor, 38 + * assuming ideal operating conditions 39 + * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power 40 + * savings are achieved 41 + * @lowest_perf: the absolute lowest performance level of the processor 42 + * @max_freq: the frequency that mapped to highest_perf 43 + * @min_freq: the frequency that mapped to lowest_perf 44 + * @nominal_freq: the frequency that mapped to nominal_perf 45 + * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf 46 + * @cur: Difference of Aperf/Mperf/tsc count between last and current sample 47 + * @prev: Last Aperf/Mperf/tsc count value read from register 48 + * @freq: current cpu frequency value 49 + * @boost_supported: check whether the Processor or SBIOS supports boost mode 50 + * 51 + * The amd_cpudata is key private data for each CPU thread in AMD P-State, and 52 + * represents all the attributes and goals that AMD P-State requests at runtime. 53 + */ 54 + struct amd_cpudata { 55 + int cpu; 56 + 57 + struct freq_qos_request req[2]; 58 + u64 cppc_req_cached; 59 + 60 + u32 highest_perf; 61 + u32 nominal_perf; 62 + u32 lowest_nonlinear_perf; 63 + u32 lowest_perf; 64 + 65 + u32 max_freq; 66 + u32 min_freq; 67 + u32 nominal_freq; 68 + u32 lowest_nonlinear_freq; 69 + 70 + struct amd_aperf_mperf cur; 71 + struct amd_aperf_mperf prev; 72 + 73 + u64 freq; 74 + bool boost_supported; 75 + }; 76 + 77 + #endif /* _LINUX_AMD_PSTATE_H */
+1
tools/testing/selftests/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 TARGETS += alsa 3 + TARGETS += amd-pstate 3 4 TARGETS += arm64 4 5 TARGETS += bpf 5 6 TARGETS += breakpoints
+9
tools/testing/selftests/amd-pstate/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # Makefile for amd-pstate/ function selftests 3 + 4 + # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 5 + all: 6 + 7 + TEST_PROGS := amd-pstate-ut.sh 8 + 9 + include ../lib.mk
+56
tools/testing/selftests/amd-pstate/amd-pstate-ut.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # amd-pstate-ut is a test module for testing the amd-pstate driver. 5 + # It can only run on x86 architectures and current cpufreq driver 6 + # must be amd-pstate. 7 + # (1) It can help all users to verify their processor support 8 + # (SBIOS/Firmware or Hardware). 9 + # (2) Kernel can have a basic function test to avoid the kernel 10 + # regression during the update. 11 + # (3) We can introduce more functional or performance tests to align 12 + # the result together, it will benefit power and performance scale optimization. 13 + 14 + # Kselftest framework requirement - SKIP code is 4. 15 + ksft_skip=4 16 + 17 + # amd-pstate-ut only run on x86/x86_64 AMD systems. 18 + ARCH=$(uname -m 2>/dev/null | sed -e 's/i.86/x86/' -e 's/x86_64/x86/') 19 + VENDOR=$(cat /proc/cpuinfo | grep -m 1 'vendor_id' | awk '{print $NF}') 20 + 21 + if ! echo "$ARCH" | grep -q x86; then 22 + echo "$0 # Skipped: Test can only run on x86 architectures." 23 + exit $ksft_skip 24 + fi 25 + 26 + if ! echo "$VENDOR" | grep -iq amd; then 27 + echo "$0 # Skipped: Test can only run on AMD CPU." 28 + echo "$0 # Current cpu vendor is $VENDOR." 29 + exit $ksft_skip 30 + fi 31 + 32 + scaling_driver=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_driver) 33 + if [ "$scaling_driver" != "amd-pstate" ]; then 34 + echo "$0 # Skipped: Test can only run on amd-pstate driver." 35 + echo "$0 # Please set X86_AMD_PSTATE enabled." 36 + echo "$0 # Current cpufreq scaling drvier is $scaling_driver." 37 + exit $ksft_skip 38 + fi 39 + 40 + msg="Skip all tests:" 41 + if [ ! -w /dev ]; then 42 + echo $msg please run this as root >&2 43 + exit $ksft_skip 44 + fi 45 + 46 + if ! /sbin/modprobe -q -n amd-pstate-ut; then 47 + echo "amd-pstate-ut: module amd-pstate-ut is not found [SKIP]" 48 + exit $ksft_skip 49 + fi 50 + if /sbin/modprobe -q amd-pstate-ut; then 51 + /sbin/modprobe -q -r amd-pstate-ut 52 + echo "amd-pstate-ut: ok" 53 + else 54 + echo "amd-pstate-ut: [FAIL]" 55 + exit 1 56 + fi
+1
tools/testing/selftests/amd-pstate/config
··· 1 + CONFIG_X86_AMD_PSTATE_UT=m
+1 -1
tools/testing/selftests/cpu-hotplug/Makefile
··· 6 6 include ../lib.mk 7 7 8 8 run_full_test: 9 - @/bin/bash ./cpu-on-off-test.sh -a || echo "cpu-hotplug selftests: [FAIL]" 9 + @/bin/bash ./cpu-on-off-test.sh -a && echo "cpu-hotplug selftests: [PASS]" || echo "cpu-hotplug selftests: [FAIL]" 10 10 11 11 clean:
-1
tools/testing/selftests/cpu-hotplug/config
··· 1 - CONFIG_NOTIFIER_ERROR_INJECTION=y
+36 -104
tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
··· 4 4 SYSFS= 5 5 # Kselftest framework requirement - SKIP code is 4. 6 6 ksft_skip=4 7 + retval=0 7 8 8 9 prerequisite() 9 10 { ··· 103 102 104 103 if ! online_cpu $cpu; then 105 104 echo $FUNCNAME $cpu: unexpected fail >&2 106 - exit 1 105 + retval=1 107 106 elif ! cpu_is_online $cpu; then 108 107 echo $FUNCNAME $cpu: unexpected offline >&2 109 - exit 1 108 + retval=1 110 109 fi 111 110 } 112 111 ··· 116 115 117 116 if online_cpu $cpu 2> /dev/null; then 118 117 echo $FUNCNAME $cpu: unexpected success >&2 119 - exit 1 118 + retval=1 120 119 elif ! cpu_is_offline $cpu; then 121 120 echo $FUNCNAME $cpu: unexpected online >&2 122 - exit 1 121 + retval=1 123 122 fi 124 123 } 125 124 ··· 129 128 130 129 if ! offline_cpu $cpu; then 131 130 echo $FUNCNAME $cpu: unexpected fail >&2 132 - exit 1 131 + retval=1 133 132 elif ! cpu_is_offline $cpu; then 134 133 echo $FUNCNAME $cpu: unexpected offline >&2 135 - exit 1 134 + retval=1 136 135 fi 137 136 } 138 137 ··· 142 141 143 142 if offline_cpu $cpu 2> /dev/null; then 144 143 echo $FUNCNAME $cpu: unexpected success >&2 145 - exit 1 144 + retval=1 146 145 elif ! cpu_is_online $cpu; then 147 146 echo $FUNCNAME $cpu: unexpected offline >&2 148 - exit 1 147 + retval=1 149 148 fi 150 149 } 151 150 152 - error=-12 151 + online_all_hot_pluggable_cpus() 152 + { 153 + for cpu in `hotplaggable_offline_cpus`; do 154 + online_cpu_expect_success $cpu 155 + done 156 + } 157 + 158 + offline_all_hot_pluggable_cpus() 159 + { 160 + local reserve_cpu=$online_max 161 + for cpu in `hotpluggable_online_cpus`; do 162 + # Reserve one cpu oneline at least. 163 + if [ $cpu -eq $reserve_cpu ];then 164 + continue 165 + fi 166 + offline_cpu_expect_success $cpu 167 + done 168 + } 169 + 153 170 allcpus=0 154 - priority=0 155 171 online_cpus=0 156 172 online_max=0 157 173 offline_cpus=0 ··· 176 158 present_cpus=0 177 159 present_max=0 178 160 179 - while getopts e:ahp: opt; do 161 + while getopts ah opt; do 180 162 case $opt in 181 - e) 182 - error=$OPTARG 183 - ;; 184 163 a) 185 164 allcpus=1 186 165 ;; 187 166 h) 188 - echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]" 167 + echo "Usage $0 [ -a ]" 189 168 echo -e "\t default offline one cpu" 190 169 echo -e "\t run with -a option to offline all cpus" 191 170 exit 192 171 ;; 193 - p) 194 - priority=$OPTARG 195 - ;; 196 172 esac 197 173 done 198 - 199 - if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then 200 - echo "error code must be -4095 <= errno < 0" >&2 201 - exit 1 202 - fi 203 174 204 175 prerequisite 205 176 ··· 203 196 online_cpu_expect_success $online_max 204 197 205 198 if [[ $offline_cpus -gt 0 ]]; then 206 - echo -e "\t offline to online to offline: cpu $present_max" 199 + echo -e "\t online to offline to online: cpu $present_max" 207 200 online_cpu_expect_success $present_max 208 201 offline_cpu_expect_success $present_max 209 202 online_cpu $present_max 210 203 fi 211 - exit 0 204 + exit $retval 212 205 else 213 206 echo "Full scope test: all hotplug cpus" 214 207 echo -e "\t online all offline cpus" ··· 216 209 echo -e "\t online all offline cpus" 217 210 fi 218 211 219 - # 220 - # Online all hot-pluggable CPUs 221 - # 222 - for cpu in `hotplaggable_offline_cpus`; do 223 - online_cpu_expect_success $cpu 224 - done 212 + online_all_hot_pluggable_cpus 225 213 226 - # 227 - # Offline all hot-pluggable CPUs 228 - # 229 - for cpu in `hotpluggable_online_cpus`; do 230 - offline_cpu_expect_success $cpu 231 - done 214 + offline_all_hot_pluggable_cpus 232 215 233 - # 234 - # Online all hot-pluggable CPUs again 235 - # 236 - for cpu in `hotplaggable_offline_cpus`; do 237 - online_cpu_expect_success $cpu 238 - done 216 + online_all_hot_pluggable_cpus 239 217 240 - # 241 - # Test with cpu notifier error injection 242 - # 243 - 244 - DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'` 245 - NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu 246 - 247 - prerequisite_extra() 248 - { 249 - msg="skip extra tests:" 250 - 251 - /sbin/modprobe -q -r cpu-notifier-error-inject 252 - /sbin/modprobe -q cpu-notifier-error-inject priority=$priority 253 - 254 - if [ ! -d "$DEBUGFS" ]; then 255 - echo $msg debugfs is not mounted >&2 256 - exit $ksft_skip 257 - fi 258 - 259 - if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then 260 - echo $msg cpu-notifier-error-inject module is not available >&2 261 - exit $ksft_skip 262 - fi 263 - } 264 - 265 - prerequisite_extra 266 - 267 - # 268 - # Offline all hot-pluggable CPUs 269 - # 270 - echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 271 - for cpu in `hotpluggable_online_cpus`; do 272 - offline_cpu_expect_success $cpu 273 - done 274 - 275 - # 276 - # Test CPU hot-add error handling (offline => online) 277 - # 278 - echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 279 - for cpu in `hotplaggable_offline_cpus`; do 280 - online_cpu_expect_fail $cpu 281 - done 282 - 283 - # 284 - # Online all hot-pluggable CPUs 285 - # 286 - echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error 287 - for cpu in `hotplaggable_offline_cpus`; do 288 - online_cpu_expect_success $cpu 289 - done 290 - 291 - # 292 - # Test CPU hot-remove error handling (online => offline) 293 - # 294 - echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 295 - for cpu in `hotpluggable_online_cpus`; do 296 - offline_cpu_expect_fail $cpu 297 - done 298 - 299 - echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error 300 - /sbin/modprobe -q -r cpu-notifier-error-inject 218 + exit $retval
+1 -1
tools/testing/selftests/vm/Makefile
··· 25 25 # LDLIBS. 26 26 MAKEFLAGS += --no-builtin-rules 27 27 28 - CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) $(KHDR_INCLUDES) 28 + CFLAGS = -Wall -I $(top_srcdir) -I $(top_srcdir)/usr/include $(EXTRA_CFLAGS) $(KHDR_INCLUDES) 29 29 LDLIBS = -lrt -lpthread 30 30 TEST_GEN_FILES = compaction_test 31 31 TEST_GEN_FILES += gup_test
+1 -1
tools/testing/selftests/vm/gup_test.c
··· 10 10 #include <sys/types.h> 11 11 #include <pthread.h> 12 12 #include <assert.h> 13 - #include "../../../../mm/gup_test.h" 13 + #include <mm/gup_test.h> 14 14 #include "../kselftest.h" 15 15 16 16 #include "util.h"
+2 -2
tools/testing/selftests/vm/hmm-tests.c
··· 35 35 * This is a private UAPI to the kernel test module so it isn't exported 36 36 * in the usual include/uapi/... directory. 37 37 */ 38 - #include "../../../../lib/test_hmm_uapi.h" 39 - #include "../../../../mm/gup_test.h" 38 + #include <lib/test_hmm_uapi.h> 39 + #include <mm/gup_test.h> 40 40 41 41 struct hmm_buffer { 42 42 void *ptr;
+1 -1
tools/testing/selftests/vm/ksm_tests.c
··· 11 11 #include <err.h> 12 12 13 13 #include "../kselftest.h" 14 - #include "../../../../include/vdso/time64.h" 14 + #include <include/vdso/time64.h> 15 15 #include "util.h" 16 16 17 17 #define KSM_SYSFS_PATH "/sys/kernel/mm/ksm/"