diff options
author | Andi Kleen <ak@linux.intel.com> | 2016-05-19 20:09:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-06-03 03:41:21 -0400 |
commit | 70b8301f6b8f7bc053377a9cbd0c4e42e29d9807 (patch) | |
tree | d29e04218ccc32b9e7da313c398a86a4c3b52c50 /arch/x86/kernel/smpboot.c | |
parent | dc89e75a9412db5b1105a140182ec1e35a8351b4 (diff) |
x86/topology: Add topology_max_smt_threads()
For SMT specific workarounds it is useful to know if SMT is active
on any online CPU in the system. This currently requires a loop
over all online CPUs.
Add a global variable that is updated with the maximum number
of smt threads on any CPU on online/offline, and use it for
topology_max_smt_threads()
The single call is easier to use than a loop.
Not exported to user space because user space already can use
the existing sibling interfaces to find this out.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.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: acme@kernel.org
Cc: jolsa@kernel.org
Link: http://lkml.kernel.org/r/1463703002-19686-2-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index fafe8b923cac..2ed0ec1353f8 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -105,6 +105,9 @@ static unsigned int max_physical_pkg_id __read_mostly; | |||
105 | unsigned int __max_logical_packages __read_mostly; | 105 | unsigned int __max_logical_packages __read_mostly; |
106 | EXPORT_SYMBOL(__max_logical_packages); | 106 | EXPORT_SYMBOL(__max_logical_packages); |
107 | 107 | ||
108 | /* Maximum number of SMT threads on any online core */ | ||
109 | int __max_smt_threads __read_mostly; | ||
110 | |||
108 | static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) | 111 | static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) |
109 | { | 112 | { |
110 | unsigned long flags; | 113 | unsigned long flags; |
@@ -493,7 +496,7 @@ void set_cpu_sibling_map(int cpu) | |||
493 | bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1; | 496 | bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1; |
494 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 497 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
495 | struct cpuinfo_x86 *o; | 498 | struct cpuinfo_x86 *o; |
496 | int i; | 499 | int i, threads; |
497 | 500 | ||
498 | cpumask_set_cpu(cpu, cpu_sibling_setup_mask); | 501 | cpumask_set_cpu(cpu, cpu_sibling_setup_mask); |
499 | 502 | ||
@@ -550,6 +553,10 @@ void set_cpu_sibling_map(int cpu) | |||
550 | if (match_die(c, o) && !topology_same_node(c, o)) | 553 | if (match_die(c, o) && !topology_same_node(c, o)) |
551 | primarily_use_numa_for_topology(); | 554 | primarily_use_numa_for_topology(); |
552 | } | 555 | } |
556 | |||
557 | threads = cpumask_weight(topology_sibling_cpumask(cpu)); | ||
558 | if (threads > __max_smt_threads) | ||
559 | __max_smt_threads = threads; | ||
553 | } | 560 | } |
554 | 561 | ||
555 | /* maps the cpu to the sched domain representing multi-core */ | 562 | /* maps the cpu to the sched domain representing multi-core */ |
@@ -1441,6 +1448,21 @@ __init void prefill_possible_map(void) | |||
1441 | 1448 | ||
1442 | #ifdef CONFIG_HOTPLUG_CPU | 1449 | #ifdef CONFIG_HOTPLUG_CPU |
1443 | 1450 | ||
1451 | /* Recompute SMT state for all CPUs on offline */ | ||
1452 | static void recompute_smt_state(void) | ||
1453 | { | ||
1454 | int max_threads, cpu; | ||
1455 | |||
1456 | max_threads = 0; | ||
1457 | for_each_online_cpu (cpu) { | ||
1458 | int threads = cpumask_weight(topology_sibling_cpumask(cpu)); | ||
1459 | |||
1460 | if (threads > max_threads) | ||
1461 | max_threads = threads; | ||
1462 | } | ||
1463 | __max_smt_threads = max_threads; | ||
1464 | } | ||
1465 | |||
1444 | static void remove_siblinginfo(int cpu) | 1466 | static void remove_siblinginfo(int cpu) |
1445 | { | 1467 | { |
1446 | int sibling; | 1468 | int sibling; |
@@ -1465,6 +1487,7 @@ static void remove_siblinginfo(int cpu) | |||
1465 | c->phys_proc_id = 0; | 1487 | c->phys_proc_id = 0; |
1466 | c->cpu_core_id = 0; | 1488 | c->cpu_core_id = 0; |
1467 | cpumask_clear_cpu(cpu, cpu_sibling_setup_mask); | 1489 | cpumask_clear_cpu(cpu, cpu_sibling_setup_mask); |
1490 | recompute_smt_state(); | ||
1468 | } | 1491 | } |
1469 | 1492 | ||
1470 | static void remove_cpu_from_maps(int cpu) | 1493 | static void remove_cpu_from_maps(int cpu) |