diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-07-13 13:16:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-07-14 03:34:35 -0400 |
commit | 77c34ef1c3194bfac65883af75baf7dec9fa0d77 (patch) | |
tree | f2c56d255b7047402f9e67cba6901df3f91f51ef | |
parent | f07048270423622a2428a9b90929c76e92777caa (diff) |
perf/x86/intel/cstate: Convert Intel CSTATE to hotplug state machine
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: kbuild test robot <fengguang.wu@intel.com>
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160713153334.184061086@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/events/intel/cstate.c | 51 | ||||
-rw-r--r-- | include/linux/cpuhotplug.h | 2 |
2 files changed, 17 insertions, 36 deletions
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 9ba4e4136a15..d6d7be0b3495 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c | |||
@@ -365,7 +365,7 @@ static int cstate_pmu_event_add(struct perf_event *event, int mode) | |||
365 | * Check if exiting cpu is the designated reader. If so migrate the | 365 | * Check if exiting cpu is the designated reader. If so migrate the |
366 | * events when there is a valid target available | 366 | * events when there is a valid target available |
367 | */ | 367 | */ |
368 | static void cstate_cpu_exit(int cpu) | 368 | static int cstate_cpu_exit(unsigned int cpu) |
369 | { | 369 | { |
370 | unsigned int target; | 370 | unsigned int target; |
371 | 371 | ||
@@ -390,9 +390,10 @@ static void cstate_cpu_exit(int cpu) | |||
390 | perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target); | 390 | perf_pmu_migrate_context(&cstate_pkg_pmu, cpu, target); |
391 | } | 391 | } |
392 | } | 392 | } |
393 | return 0; | ||
393 | } | 394 | } |
394 | 395 | ||
395 | static void cstate_cpu_init(int cpu) | 396 | static int cstate_cpu_init(unsigned int cpu) |
396 | { | 397 | { |
397 | unsigned int target; | 398 | unsigned int target; |
398 | 399 | ||
@@ -414,31 +415,10 @@ static void cstate_cpu_init(int cpu) | |||
414 | topology_core_cpumask(cpu)); | 415 | topology_core_cpumask(cpu)); |
415 | if (has_cstate_pkg && target >= nr_cpu_ids) | 416 | if (has_cstate_pkg && target >= nr_cpu_ids) |
416 | cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask); | 417 | cpumask_set_cpu(cpu, &cstate_pkg_cpu_mask); |
417 | } | ||
418 | 418 | ||
419 | static int cstate_cpu_notifier(struct notifier_block *self, | 419 | return 0; |
420 | unsigned long action, void *hcpu) | ||
421 | { | ||
422 | unsigned int cpu = (long)hcpu; | ||
423 | |||
424 | switch (action & ~CPU_TASKS_FROZEN) { | ||
425 | case CPU_STARTING: | ||
426 | cstate_cpu_init(cpu); | ||
427 | break; | ||
428 | case CPU_DOWN_PREPARE: | ||
429 | cstate_cpu_exit(cpu); | ||
430 | break; | ||
431 | default: | ||
432 | break; | ||
433 | } | ||
434 | return NOTIFY_OK; | ||
435 | } | 420 | } |
436 | 421 | ||
437 | static struct notifier_block cstate_cpu_nb = { | ||
438 | .notifier_call = cstate_cpu_notifier, | ||
439 | .priority = CPU_PRI_PERF + 1, | ||
440 | }; | ||
441 | |||
442 | static struct pmu cstate_core_pmu = { | 422 | static struct pmu cstate_core_pmu = { |
443 | .attr_groups = core_attr_groups, | 423 | .attr_groups = core_attr_groups, |
444 | .name = "cstate_core", | 424 | .name = "cstate_core", |
@@ -599,18 +579,20 @@ static inline void cstate_cleanup(void) | |||
599 | 579 | ||
600 | static int __init cstate_init(void) | 580 | static int __init cstate_init(void) |
601 | { | 581 | { |
602 | int cpu, err; | 582 | int err; |
603 | 583 | ||
604 | cpu_notifier_register_begin(); | 584 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_STARTING, |
605 | for_each_online_cpu(cpu) | 585 | "AP_PERF_X86_CSTATE_STARTING", cstate_cpu_init, |
606 | cstate_cpu_init(cpu); | 586 | NULL); |
587 | cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_ONLINE, | ||
588 | "AP_PERF_X86_CSTATE_ONLINE", NULL, cstate_cpu_exit); | ||
607 | 589 | ||
608 | if (has_cstate_core) { | 590 | if (has_cstate_core) { |
609 | err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1); | 591 | err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1); |
610 | if (err) { | 592 | if (err) { |
611 | has_cstate_core = false; | 593 | has_cstate_core = false; |
612 | pr_info("Failed to register cstate core pmu\n"); | 594 | pr_info("Failed to register cstate core pmu\n"); |
613 | goto out; | 595 | return err; |
614 | } | 596 | } |
615 | } | 597 | } |
616 | 598 | ||
@@ -620,12 +602,10 @@ static int __init cstate_init(void) | |||
620 | has_cstate_pkg = false; | 602 | has_cstate_pkg = false; |
621 | pr_info("Failed to register cstate pkg pmu\n"); | 603 | pr_info("Failed to register cstate pkg pmu\n"); |
622 | cstate_cleanup(); | 604 | cstate_cleanup(); |
623 | goto out; | 605 | return err; |
624 | } | 606 | } |
625 | } | 607 | } |
626 | __register_cpu_notifier(&cstate_cpu_nb); | 608 | |
627 | out: | ||
628 | cpu_notifier_register_done(); | ||
629 | return err; | 609 | return err; |
630 | } | 610 | } |
631 | 611 | ||
@@ -651,9 +631,8 @@ module_init(cstate_pmu_init); | |||
651 | 631 | ||
652 | static void __exit cstate_pmu_exit(void) | 632 | static void __exit cstate_pmu_exit(void) |
653 | { | 633 | { |
654 | cpu_notifier_register_begin(); | 634 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_ONLINE); |
655 | __unregister_cpu_notifier(&cstate_cpu_nb); | 635 | cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_STARTING); |
656 | cstate_cleanup(); | 636 | cstate_cleanup(); |
657 | cpu_notifier_register_done(); | ||
658 | } | 637 | } |
659 | module_exit(cstate_pmu_exit); | 638 | module_exit(cstate_pmu_exit); |
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index f9399eeba263..68f4495f4988 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h | |||
@@ -26,6 +26,7 @@ enum cpuhp_state { | |||
26 | CPUHP_AP_PERF_X86_STARTING, | 26 | CPUHP_AP_PERF_X86_STARTING, |
27 | CPUHP_AP_PERF_X86_AMD_IBS_STARTING, | 27 | CPUHP_AP_PERF_X86_AMD_IBS_STARTING, |
28 | CPUHP_AP_PERF_X86_CQM_STARTING, | 28 | CPUHP_AP_PERF_X86_CQM_STARTING, |
29 | CPUHP_AP_PERF_X86_CSTATE_STARTING, | ||
29 | CPUHP_AP_NOTIFY_STARTING, | 30 | CPUHP_AP_NOTIFY_STARTING, |
30 | CPUHP_AP_ONLINE, | 31 | CPUHP_AP_ONLINE, |
31 | CPUHP_TEARDOWN_CPU, | 32 | CPUHP_TEARDOWN_CPU, |
@@ -38,6 +39,7 @@ enum cpuhp_state { | |||
38 | CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE, | 39 | CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE, |
39 | CPUHP_AP_PERF_X86_RAPL_ONLINE, | 40 | CPUHP_AP_PERF_X86_RAPL_ONLINE, |
40 | CPUHP_AP_PERF_X86_CQM_ONLINE, | 41 | CPUHP_AP_PERF_X86_CQM_ONLINE, |
42 | CPUHP_AP_PERF_X86_CSTATE_ONLINE, | ||
41 | CPUHP_AP_NOTIFY_ONLINE, | 43 | CPUHP_AP_NOTIFY_ONLINE, |
42 | CPUHP_AP_ONLINE_DYN, | 44 | CPUHP_AP_ONLINE_DYN, |
43 | CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, | 45 | CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, |