[v2,1/2] smp: Add helper function to mark possible bad package number
Commit Message
For some architecture like x86, it calculates processor package number
in the process of bringing up all CPUs. The 'nr_cpus=' and 'maxcpus='
cmdline parameter setup may reduce the number of CPUs which actually
get brought up, and make the package number inaccurate (less than the
real number).
Add a general helper function arch_mark_bad_package_count() to enable
affected architectures to mark the possible unreliable package
estimation. Also implement the support in x86 to leverage it.
Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Feng Tang <feng.tang@intel.com>
---
arch/x86/kernel/smpboot.c | 9 +++++++++
include/linux/smp.h | 13 +++++++++++++
kernel/smp.c | 10 +++++++++-
3 files changed, 31 insertions(+), 1 deletion(-)
@@ -1274,6 +1274,15 @@ void arch_disable_smp_support(void)
disable_ioapic_support();
}
+void arch_mark_bad_package_count(char *reason)
+{
+ if (package_count_unreliable)
+ return;
+
+ package_count_unreliable = true;
+ pr_warn("Processor package count may be unreliable due to: %s\n", reason);
+}
+
/*
* Fall back to non SMP mode after errors.
*
@@ -188,6 +188,13 @@ static inline int get_boot_cpu_id(void)
return __boot_cpu_id;
}
+extern bool package_count_unreliable;
+
+static inline bool is_package_count_reliable(void)
+{
+ return !package_count_unreliable;
+}
+
#else /* !SMP */
static inline void smp_send_stop(void) { }
@@ -230,6 +237,10 @@ static inline int get_boot_cpu_id(void)
return 0;
}
+static inline bool is_package_count_reliable(void)
+{
+ return true;
+}
#endif /* !SMP */
/**
@@ -283,6 +294,8 @@ extern void arch_disable_smp_support(void);
extern void arch_thaw_secondary_cpus_begin(void);
extern void arch_thaw_secondary_cpus_end(void);
+extern void arch_mark_bad_package_count(char *reason);
+
void smp_setup_processor_id(void);
int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par,
@@ -904,13 +904,20 @@ static int __init nosmp(char *str)
early_param("nosmp", nosmp);
+bool package_count_unreliable;
+
+void __weak arch_mark_bad_package_count(char *reason) { }
+
/* this is hard limit */
static int __init nrcpus(char *str)
{
int nr_cpus;
- if (get_option(&str, &nr_cpus) && nr_cpus > 0 && nr_cpus < nr_cpu_ids)
+ if (get_option(&str, &nr_cpus) && nr_cpus > 0 &&
+ nr_cpus < nr_cpu_ids) {
set_nr_cpu_ids(nr_cpus);
+ arch_mark_bad_package_count("'nr_cpus' setup");
+ }
return 0;
}
@@ -923,6 +930,7 @@ static int __init maxcpus(char *str)
if (setup_max_cpus == 0)
arch_disable_smp_support();
+ arch_mark_bad_package_count("'maxcpus' setup");
return 0;
}