aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Cochran <rcochran@linutronix.de>2016-07-13 13:16:16 -0400
committerIngo Molnar <mingo@kernel.org>2016-07-14 03:34:35 -0400
commitf07048270423622a2428a9b90929c76e92777caa (patch)
treeecc2b95abda9fd5645b277842d4491115f15f0cf
parent8b5b773d6245138c461b3a3e242339fa50fa9c58 (diff)
perf/x86/intel/cqm: Convert Intel CQM 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: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@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: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Fleming <matt.fleming@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160713153334.096956222@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/events/intel/cqm.c49
-rw-r--r--include/linux/cpuhotplug.h2
2 files changed, 20 insertions, 31 deletions
diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c
index 7b5fd811ef45..783c49ddef29 100644
--- a/arch/x86/events/intel/cqm.c
+++ b/arch/x86/events/intel/cqm.c
@@ -1577,7 +1577,7 @@ static inline void cqm_pick_event_reader(int cpu)
1577 cpumask_set_cpu(cpu, &cqm_cpumask); 1577 cpumask_set_cpu(cpu, &cqm_cpumask);
1578} 1578}
1579 1579
1580static void intel_cqm_cpu_starting(unsigned int cpu) 1580static int intel_cqm_cpu_starting(unsigned int cpu)
1581{ 1581{
1582 struct intel_pqr_state *state = &per_cpu(pqr_state, cpu); 1582 struct intel_pqr_state *state = &per_cpu(pqr_state, cpu);
1583 struct cpuinfo_x86 *c = &cpu_data(cpu); 1583 struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -1588,39 +1588,26 @@ static void intel_cqm_cpu_starting(unsigned int cpu)
1588 1588
1589 WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid); 1589 WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid);
1590 WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale); 1590 WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale);
1591
1592 cqm_pick_event_reader(cpu);
1593 return 0;
1591} 1594}
1592 1595
1593static void intel_cqm_cpu_exit(unsigned int cpu) 1596static int intel_cqm_cpu_exit(unsigned int cpu)
1594{ 1597{
1595 int target; 1598 int target;
1596 1599
1597 /* Is @cpu the current cqm reader for this package ? */ 1600 /* Is @cpu the current cqm reader for this package ? */
1598 if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask)) 1601 if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask))
1599 return; 1602 return 0;
1600 1603
1601 /* Find another online reader in this package */ 1604 /* Find another online reader in this package */
1602 target = cpumask_any_but(topology_core_cpumask(cpu), cpu); 1605 target = cpumask_any_but(topology_core_cpumask(cpu), cpu);
1603 1606
1604 if (target < nr_cpu_ids) 1607 if (target < nr_cpu_ids)
1605 cpumask_set_cpu(target, &cqm_cpumask); 1608 cpumask_set_cpu(target, &cqm_cpumask);
1606}
1607
1608static int intel_cqm_cpu_notifier(struct notifier_block *nb,
1609 unsigned long action, void *hcpu)
1610{
1611 unsigned int cpu = (unsigned long)hcpu;
1612
1613 switch (action & ~CPU_TASKS_FROZEN) {
1614 case CPU_DOWN_PREPARE:
1615 intel_cqm_cpu_exit(cpu);
1616 break;
1617 case CPU_STARTING:
1618 intel_cqm_cpu_starting(cpu);
1619 cqm_pick_event_reader(cpu);
1620 break;
1621 }
1622 1609
1623 return NOTIFY_OK; 1610 return 0;
1624} 1611}
1625 1612
1626static const struct x86_cpu_id intel_cqm_match[] = { 1613static const struct x86_cpu_id intel_cqm_match[] = {
@@ -1682,7 +1669,7 @@ out:
1682static int __init intel_cqm_init(void) 1669static int __init intel_cqm_init(void)
1683{ 1670{
1684 char *str = NULL, scale[20]; 1671 char *str = NULL, scale[20];
1685 int i, cpu, ret; 1672 int cpu, ret;
1686 1673
1687 if (x86_match_cpu(intel_cqm_match)) 1674 if (x86_match_cpu(intel_cqm_match))
1688 cqm_enabled = true; 1675 cqm_enabled = true;
@@ -1705,8 +1692,7 @@ static int __init intel_cqm_init(void)
1705 * 1692 *
1706 * Also, check that the scales match on all cpus. 1693 * Also, check that the scales match on all cpus.
1707 */ 1694 */
1708 cpu_notifier_register_begin(); 1695 get_online_cpus();
1709
1710 for_each_online_cpu(cpu) { 1696 for_each_online_cpu(cpu) {
1711 struct cpuinfo_x86 *c = &cpu_data(cpu); 1697 struct cpuinfo_x86 *c = &cpu_data(cpu);
1712 1698
@@ -1743,11 +1729,6 @@ static int __init intel_cqm_init(void)
1743 if (ret) 1729 if (ret)
1744 goto out; 1730 goto out;
1745 1731
1746 for_each_online_cpu(i) {
1747 intel_cqm_cpu_starting(i);
1748 cqm_pick_event_reader(i);
1749 }
1750
1751 if (mbm_enabled) 1732 if (mbm_enabled)
1752 ret = intel_mbm_init(); 1733 ret = intel_mbm_init();
1753 if (ret && !cqm_enabled) 1734 if (ret && !cqm_enabled)
@@ -1772,12 +1753,18 @@ static int __init intel_cqm_init(void)
1772 pr_info("Intel MBM enabled\n"); 1753 pr_info("Intel MBM enabled\n");
1773 1754
1774 /* 1755 /*
1775 * Register the hot cpu notifier once we are sure cqm 1756 * Setup the hot cpu notifier once we are sure cqm
1776 * is enabled to avoid notifier leak. 1757 * is enabled to avoid notifier leak.
1777 */ 1758 */
1778 __perf_cpu_notifier(intel_cqm_cpu_notifier); 1759 cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_STARTING,
1760 "AP_PERF_X86_CQM_STARTING",
1761 intel_cqm_cpu_starting, NULL);
1762 cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_ONLINE, "AP_PERF_X86_CQM_ONLINE",
1763 NULL, intel_cqm_cpu_exit);
1764
1779out: 1765out:
1780 cpu_notifier_register_done(); 1766 put_online_cpus();
1767
1781 if (ret) { 1768 if (ret) {
1782 kfree(str); 1769 kfree(str);
1783 cqm_cleanup(); 1770 cqm_cleanup();
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 06d77fd0fda3..f9399eeba263 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -25,6 +25,7 @@ enum cpuhp_state {
25 CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING, 25 CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
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_NOTIFY_STARTING, 29 CPUHP_AP_NOTIFY_STARTING,
29 CPUHP_AP_ONLINE, 30 CPUHP_AP_ONLINE,
30 CPUHP_TEARDOWN_CPU, 31 CPUHP_TEARDOWN_CPU,
@@ -36,6 +37,7 @@ enum cpuhp_state {
36 CPUHP_AP_PERF_X86_UNCORE_ONLINE, 37 CPUHP_AP_PERF_X86_UNCORE_ONLINE,
37 CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE, 38 CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
38 CPUHP_AP_PERF_X86_RAPL_ONLINE, 39 CPUHP_AP_PERF_X86_RAPL_ONLINE,
40 CPUHP_AP_PERF_X86_CQM_ONLINE,
39 CPUHP_AP_NOTIFY_ONLINE, 41 CPUHP_AP_NOTIFY_ONLINE,
40 CPUHP_AP_ONLINE_DYN, 42 CPUHP_AP_ONLINE_DYN,
41 CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30, 43 CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30,