Commit bbb65d2d365e ("x86: use cpuid vector 0xb when available for
detecting cpu topology") changed the value of smp_num_siblings from the
active number of threads in a core to the maximum number threads in a
core.  e.g.) On Intel Haswell and newer systems smp_num_siblings is
two even if SMT is disabled.

topology_max_smt_threads() already returns the active number of threads.
Introduce topology_hw_smt_threads() which returns the maximum number of
threads.  These are used to fix and replace references to smp_num_siblings.

Signed-off-by: Prarit Bhargava <pra...@redhat.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: "H. Peter Anvin" <h...@zytor.com>
Cc: x...@kernel.org
Cc: Jonathan Corbet <cor...@lwn.net>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Vitaly Kuznetsov <vkuzn...@redhat.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-e...@vger.kernel.org
Cc: oprofile-l...@lists.sf.net
---
 Documentation/x86/topology.txt          | 13 +++++++++----
 arch/x86/include/asm/perf_event_p4.h    |  4 ++--
 arch/x86/include/asm/smp.h              |  2 --
 arch/x86/include/asm/topology.h         | 10 +++++-----
 arch/x86/kernel/cpu/amd.c               |  6 ++----
 arch/x86/kernel/cpu/common.c            | 18 +++++++++++-------
 arch/x86/kernel/cpu/mcheck/mce-inject.c |  3 ++-
 arch/x86/kernel/cpu/topology.c          |  4 ++--
 arch/x86/kernel/itmt.c                  |  2 +-
 arch/x86/kernel/process.c               |  3 ++-
 arch/x86/kernel/smpboot.c               | 22 ++++++++--------------
 arch/x86/oprofile/nmi_int.c             |  2 +-
 arch/x86/oprofile/op_model_p4.c         |  4 ++--
 13 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/Documentation/x86/topology.txt b/Documentation/x86/topology.txt
index f3e9d7e9ed6c..9fa07a4460df 100644
--- a/Documentation/x86/topology.txt
+++ b/Documentation/x86/topology.txt
@@ -83,13 +83,18 @@ The topology of a system is described in the units of:
 
   Core-related topology information in the kernel:
 
-  - smp_num_siblings:
+  - topology_hw_smt_threads:
 
-    The number of threads in a core. The number of threads in a package can be
-    calculated by:
+    The maximum number of threads that a core's hardware supports.  For
+    example, on Intel Haswell and newer systems this is 2 even if SMT is
+    disabled.
 
-       threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings
+  - topology_max_smt_threads:
 
+    The number of threads/core available at runtime.  The number of threads in
+    a package can be calculated by:
+
+    threads_per_package = cpuinfo_x86.x86_max_cores * topology_max_smt_threads
 
 * Threads:
 
diff --git a/arch/x86/include/asm/perf_event_p4.h 
b/arch/x86/include/asm/perf_event_p4.h
index 94de1a05aeba..11afdadce9c2 100644
--- a/arch/x86/include/asm/perf_event_p4.h
+++ b/arch/x86/include/asm/perf_event_p4.h
@@ -181,7 +181,7 @@ static inline u64 p4_clear_ht_bit(u64 config)
 static inline int p4_ht_active(void)
 {
 #ifdef CONFIG_SMP
-       return smp_num_siblings > 1;
+       return topology_max_smt_threads() > 1;
 #endif
        return 0;
 }
@@ -189,7 +189,7 @@ static inline int p4_ht_active(void)
 static inline int p4_ht_thread(int cpu)
 {
 #ifdef CONFIG_SMP
-       if (smp_num_siblings == 2)
+       if (topology_max_smt_threads() == 2)
                return cpu != 
cpumask_first(this_cpu_cpumask_var_ptr(cpu_sibling_map));
 #endif
        return 0;
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 461f53d27708..cf28a3932917 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -18,7 +18,6 @@
 #include <asm/thread_info.h>
 #include <asm/cpumask.h>
 
-extern int smp_num_siblings;
 extern unsigned int num_processors;
 
 DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
@@ -170,7 +169,6 @@ static inline int wbinvd_on_all_cpus(void)
        wbinvd();
        return 0;
 }
-#define smp_num_siblings       1
 #endif /* CONFIG_SMP */
 
 extern unsigned disabled_cpus;
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index c1d2a9892352..b5ff1c784eef 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -116,16 +116,16 @@ extern unsigned int __max_logical_packages;
 #define topology_max_packages()                        (__max_logical_packages)
 
 extern int __max_smt_threads;
-
-static inline int topology_max_smt_threads(void)
-{
-       return __max_smt_threads;
-}
+#define topology_max_smt_threads()             (__max_smt_threads)
+extern int __hw_smt_threads;
+#define topology_hw_smt_threads()              (__hw_smt_threads)
 
 int topology_update_package_map(unsigned int apicid, unsigned int cpu);
 extern int topology_phys_to_logical_pkg(unsigned int pkg);
 #else
 #define topology_max_packages()                        (1)
+#define topology_max_smt_threads()             (1)
+#define topology_hw_smt_threads()              (1)
 static inline int
 topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; 
}
 static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bcb75dc97d44..f2582505e2f9 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -332,16 +332,14 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
                cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 
                node_id  = ecx & 0xff;
-               smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+               __hw_smt_threads = ((ebx >> 8) & 0xff) + 1;
 
                if (c->x86 == 0x15)
                        c->cu_id = ebx & 0xff;
 
                if (c->x86 >= 0x17) {
                        c->cpu_core_id = ebx & 0xff;
-
-                       if (smp_num_siblings > 1)
-                               c->x86_max_cores /= smp_num_siblings;
+                       c->x86_max_cores /= topology_hw_smt_threads();
                }
 
                /*
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c47de4ebf63a..1070e2832ca3 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -654,22 +654,22 @@ void detect_ht(struct cpuinfo_x86 *c)
 
        cpuid(1, &eax, &ebx, &ecx, &edx);
 
-       smp_num_siblings = (ebx & 0xff0000) >> 16;
+       __hw_smt_threads = (ebx & 0xff0000) >> 16;
 
-       if (smp_num_siblings == 1) {
+       if (topology_hw_smt_threads() == 1) {
                pr_info_once("CPU0: Hyper-Threading is disabled\n");
                goto out;
        }
 
-       if (smp_num_siblings <= 1)
+       if (topology_hw_smt_threads() <= 1)
                goto out;
 
-       index_msb = get_count_order(smp_num_siblings);
+       index_msb = get_count_order(topology_hw_smt_threads());
        c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
 
-       smp_num_siblings = smp_num_siblings / c->x86_max_cores;
+       __hw_smt_threads = topology_hw_smt_threads() / c->x86_max_cores;
 
-       index_msb = get_count_order(smp_num_siblings);
+       index_msb = get_count_order(topology_hw_smt_threads());
 
        core_bits = get_count_order(c->x86_max_cores);
 
@@ -677,7 +677,7 @@ void detect_ht(struct cpuinfo_x86 *c)
                                       ((1 << core_bits) - 1);
 
 out:
-       if (!printed && (c->x86_max_cores * smp_num_siblings) > 1) {
+       if (!printed && (c->x86_max_cores * topology_hw_smt_threads()) > 1) {
                pr_info("CPU: Physical Processor ID: %d\n",
                        c->phys_proc_id);
                pr_info("CPU: Processor Core ID: %d\n",
@@ -1228,6 +1228,10 @@ static void identify_cpu(struct cpuinfo_x86 *c)
        /* Init Machine Check Exception if available. */
        mcheck_cpu_init(c);
 
+       /* Must be called before select_idle_routine */
+       if (c != &boot_cpu_data)
+               set_cpu_sibling_map(raw_smp_processor_id());
+
        select_idle_routine(c);
 
 #ifdef CONFIG_NUMA
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c 
b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 231ad23b24a9..3785929d11af 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -420,7 +420,8 @@ static u32 get_nbc_for_node(int node_id)
        struct cpuinfo_x86 *c = &boot_cpu_data;
        u32 cores_per_node;
 
-       cores_per_node = (c->x86_max_cores * smp_num_siblings) / 
amd_get_nodes_per_socket();
+       cores_per_node = (c->x86_max_cores * topology_hw_smt_threads()) /
+                        amd_get_nodes_per_socket();
 
        return cores_per_node * node_id;
 }
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index b099024d339c..8cf2927c73ec 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -56,7 +56,7 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
        /*
         * Populate HT related information from sub-leaf level 0.
         */
-       core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
+       core_level_siblings = __hw_smt_threads = LEVEL_MAX_SIBLINGS(ebx);
        core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
 
        sub_index = 1;
@@ -85,7 +85,7 @@ void detect_extended_topology(struct cpuinfo_x86 *c)
         */
        c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
 
-       c->x86_max_cores = (core_level_siblings / smp_num_siblings);
+       c->x86_max_cores = (core_level_siblings / topology_hw_smt_threads());
 
        if (!printed) {
                pr_info("CPU: Physical Processor ID: %d\n",
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index f73f475d0573..4b887d3f79ed 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -206,7 +206,7 @@ void sched_set_itmt_core_prio(int prio, int core_cpu)
                 * of the priority chain and only used when
                 * all other high priority cpus are out of capacity.
                 */
-               smt_prio = prio * smp_num_siblings / i;
+               smt_prio = prio * topology_hw_smt_threads() / i;
                per_cpu(sched_core_priority, cpu) = smt_prio;
                i++;
        }
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index aed9d94bd46f..67575faee8dd 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -476,7 +476,8 @@ static __cpuidle void mwait_idle(void)
 void select_idle_routine(const struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
-       if (boot_option_idle_override == IDLE_POLL && smp_num_siblings > 1)
+       if (boot_option_idle_override == IDLE_POLL &&
+           topology_hw_smt_threads() > 1)
                pr_warn_once("WARNING: polling idle and HT enabled, performance 
may degrade\n");
 #endif
        if (x86_idle || boot_option_idle_override == IDLE_POLL)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ed556d50d7ed..56bdcdba006f 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -79,10 +79,6 @@
 #include <asm/misc.h>
 #include <asm/qspinlock.h>
 
-/* Number of siblings per CPU package */
-int smp_num_siblings = 1;
-EXPORT_SYMBOL(smp_num_siblings);
-
 /* Last level cache ID of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id) = BAD_APICID;
 
@@ -105,8 +101,11 @@ unsigned int __max_logical_packages __read_mostly;
 EXPORT_SYMBOL(__max_logical_packages);
 static unsigned int logical_packages __read_mostly;
 
-/* Maximum number of SMT threads on any online core */
+/* Maximum number of SMT threads on any online core determined by topology */
 int __read_mostly __max_smt_threads = 1;
+/* Maximum number of SMT threads read from hardware */
+int __read_mostly __hw_smt_threads = 1;
+EXPORT_SYMBOL(__hw_smt_threads);
 
 /* Flag to indicate if a complete sched domain rebuild is required */
 bool x86_topology_update;
@@ -177,16 +176,11 @@ static void smp_callin(void)
        apic_ap_setup();
 
        /*
-        * Save our processor parameters. Note: this information
-        * is needed for clock calibration.
-        */
-       smp_store_cpu_info(cpuid);
-
-       /*
-        * The topology information must be up to date before
+        * Save CPU parameters and topology.  This information is needed for
+        * clock calibration, and must be update to date before calling
         * calibrate_delay() and notify_cpu_starting().
         */
-       set_cpu_sibling_map(raw_smp_processor_id());
+       smp_store_cpu_info(cpuid);
 
        /*
         * Get our bogomips.
@@ -463,7 +457,7 @@ static bool x86_has_numa_in_package;
 
 void set_cpu_sibling_map(int cpu)
 {
-       bool has_smt = smp_num_siblings > 1;
+       bool has_smt = topology_hw_smt_threads() > 1;
        bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1;
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct cpuinfo_x86 *o;
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 174c59774cc9..8029db4c4d3b 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -566,7 +566,7 @@ static int __init p4_init(char **cpu_type)
        model = &op_p4_spec;
        return 1;
 #else
-       switch (smp_num_siblings) {
+       switch (topology_hw_smt_threads()) {
        case 1:
                *cpu_type = "i386/p4";
                model = &op_p4_spec;
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index ad1d91f475ab..7bebd042df15 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -43,7 +43,7 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT;
 static inline void setup_num_counters(void)
 {
 #ifdef CONFIG_SMP
-       if (smp_num_siblings == 2) {
+       if (topology_hw_smt_threads() == 2) {
                num_counters = NUM_COUNTERS_HT2;
                num_controls = NUM_CONTROLS_HT2;
        }
@@ -53,7 +53,7 @@ static inline void setup_num_counters(void)
 static inline int addr_increment(void)
 {
 #ifdef CONFIG_SMP
-       return smp_num_siblings == 2 ? 2 : 1;
+       return topology_hw_smt_threads() == 2 ? 2 : 1;
 #else
        return 1;
 #endif
-- 
2.15.0.rc0.39.g2f0e14e64

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to