Messages in this thread Patch in this message | | | Subject | [PATCH RFC] x86 / CPU: Add cpu isolation flag for avoiding disturbance from aperfmperf IPI | From | Konstantin Khlebnikov <> | Date | Thu, 25 Apr 2019 13:46:51 +0300 |
| |
Sensitive workloads like DPDK polling do not like any interrupts.
This patch adds flag 'freq' for boot option 'isolcpu': isolcpu=freq,<cpus>.
Users like show_cpuinfo() fallback to frequency from generic cpufreq policy if arch-specific requesting method returns 0.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> --- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/x86/kernel/cpu/aperfmperf.c | 12 +++++++++++- include/linux/sched/isolation.h | 1 + kernel/sched/isolation.c | 6 ++++++ 4 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 2b8ee90bb644..3797cd5c2b2e 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1900,6 +1900,9 @@ <cpu number> begins at 0 and the maximum value is "number of CPUs in system - 1". + freq + Do not request current cpu frequency via IPI. + The format of <cpu-list> is described above. diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index 804c49493938..e8fb917980a8 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -14,6 +14,7 @@ #include <linux/percpu.h> #include <linux/cpufreq.h> #include <linux/smp.h> +#include <linux/sched/isolation.h> #include "cpu.h" @@ -86,6 +87,9 @@ unsigned int aperfmperf_get_khz(int cpu) if (!static_cpu_has(X86_FEATURE_APERFMPERF)) return 0; + if (!housekeeping_cpu(cpu, HK_FLAG_FREQ)) + return 0; + aperfmperf_snapshot_cpu(cpu, ktime_get(), true); return per_cpu(samples.khz, cpu); } @@ -102,9 +106,12 @@ void arch_freq_prepare_all(void) if (!static_cpu_has(X86_FEATURE_APERFMPERF)) return; - for_each_online_cpu(cpu) + for_each_online_cpu(cpu) { + if (!housekeeping_cpu(cpu, HK_FLAG_FREQ)) + continue; if (!aperfmperf_snapshot_cpu(cpu, now, false)) wait = true; + } if (wait) msleep(APERFMPERF_REFRESH_DELAY_MS); @@ -118,6 +125,9 @@ unsigned int arch_freq_get_on_cpu(int cpu) if (!static_cpu_has(X86_FEATURE_APERFMPERF)) return 0; + if (!housekeeping_cpu(cpu, HK_FLAG_FREQ)) + return 0; + if (aperfmperf_snapshot_cpu(cpu, ktime_get(), true)) return per_cpu(samples.khz, cpu); diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h index b0fb1446fe04..88e6013ac8a9 100644 --- a/include/linux/sched/isolation.h +++ b/include/linux/sched/isolation.h @@ -13,6 +13,7 @@ enum hk_flags { HK_FLAG_TICK = (1 << 4), HK_FLAG_DOMAIN = (1 << 5), HK_FLAG_WQ = (1 << 6), + HK_FLAG_FREQ = (1 << 7), }; #ifdef CONFIG_CPU_ISOLATION diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index b02d148e7672..456b5f1dfa11 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c @@ -140,6 +140,12 @@ static int __init housekeeping_isolcpus_setup(char *str) continue; } + if (!strncmp(str, "freq,", 5)) { + str += 5; + flags |= HK_FLAG_FREQ; + continue; + } + pr_warn("isolcpus: Error, unknown flag\n"); return 0; }
| |