| From: Sander Vanheule <sander@svanheule.net> |
| Subject: x86/cacheinfo: move shared cache map definitions |
| Date: Sat, 2 Jul 2022 18:08:24 +0200 |
| |
| Patch series "cpumask: Fix invalid uniprocessor assumptions", v4. |
| |
| On uniprocessor builds, it is currently assumed that any cpumask will |
| contain the single CPU: cpu0. This assumption is used to provide |
| optimised implementations. |
| |
| The current assumption also appears to be wrong, by ignoring the fact that |
| users can provide empty cpumasks. This can result in bugs as explained in |
| [1] - for_each_cpu() will run one iteration of the loop even when passed |
| an empty cpumask. |
| |
| This series introduces some basic tests, and updates the optimisations for |
| uniprocessor builds. |
| |
| The x86 patch was written after the kernel test robot [2] ran into a |
| failed build. I have tried to list the files potentially affected by the |
| changes to cpumask.h, in an attempt to find any other cases that fail on |
| !SMP. I've gone through some of the files manually, and ran a few cross |
| builds, but nothing else popped up. I (build) checked about half of the |
| potientally affected files, but I do not have the resources to do them |
| all. I hope we can fix other issues if/when they pop up later. |
| |
| [1] https://lore.kernel.org/all/20220530082552.46113-1-sander@svanheule.net/ |
| [2] https://lore.kernel.org/all/202206060858.wA0FOzRy-lkp@intel.com/ |
| |
| |
| This patch (of 5): |
| |
| The maps to keep track of shared caches between CPUs on SMP systems are |
| declared in asm/smp.h, among them specifically cpu_llc_shared_map. These |
| maps are externally defined in cpu/smpboot.c. The latter is only compiled |
| on CONFIG_SMP=y, which means the declared extern symbols from asm/smp.h do |
| not have a corresponding definition on uniprocessor builds. |
| |
| The inline cpu_llc_shared_mask() function from asm/smp.h refers to the map |
| declaration mentioned above. This function is referenced in cacheinfo.c |
| inside for_each_cpu() loop macros, to provide cpumask for the loop. On |
| uniprocessor builds, the symbol for the cpu_llc_shared_map does not exist. |
| However, the current implementation of for_each_cpu() also (wrongly) |
| ignores the provided mask. |
| |
| By sheer luck, the compiler thus optimises out this unused reference to |
| cpu_llc_shared_map, and the linker therefore does not require the |
| cpu_llc_shared_mask to actually exist on uniprocessor builds. Only on SMP |
| bulids does smpboot.o exist to provide the required symbols. |
| |
| To no longer rely on compiler optimisations for successful uniprocessor |
| builds, move the definitions of cpu_llc_shared_map and cpu_l2c_shared_map |
| from smpboot.c to cacheinfo.c. |
| |
| Link: https://lkml.kernel.org/r/cover.1656777646.git.sander@svanheule.net |
| Link: https://lkml.kernel.org/r/e8167ddb570f56744a3dc12c2149a660a324d969.1656777646.git.sander@svanheule.net |
| Signed-off-by: Sander Vanheule <sander@svanheule.net> |
| Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Cc: Marco Elver <elver@google.com> |
| Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Valentin Schneider <vschneid@redhat.com> |
| Cc: Yury Norov <yury.norov@gmail.com> |
| Cc: Ingo Molnar <mingo@redhat.com> |
| Cc: Borislav Petkov <bp@alien8.de> |
| Cc: Dave Hansen <dave.hansen@linux.intel.com> |
| Cc: "H. Peter Anvin" <hpa@zytor.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| arch/x86/kernel/cpu/cacheinfo.c | 6 ++++++ |
| arch/x86/kernel/smpboot.c | 4 ---- |
| 2 files changed, 6 insertions(+), 4 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/cacheinfo.c~x86-cacheinfo-move-shared-cache-map-definitions |
| +++ a/arch/x86/kernel/cpu/cacheinfo.c |
| @@ -29,6 +29,12 @@ |
| #define LVL_3 4 |
| #define LVL_TRACE 5 |
| |
| +/* Shared last level cache maps */ |
| +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); |
| + |
| +/* Shared L2 cache maps */ |
| +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); |
| + |
| struct _cache_table { |
| unsigned char descriptor; |
| char cache_type; |
| --- a/arch/x86/kernel/smpboot.c~x86-cacheinfo-move-shared-cache-map-definitions |
| +++ a/arch/x86/kernel/smpboot.c |
| @@ -95,10 +95,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); |
| DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map); |
| EXPORT_PER_CPU_SYMBOL(cpu_die_map); |
| |
| -DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); |
| - |
| -DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); |
| - |
| /* Per CPU bogomips and other parameters */ |
| DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); |
| EXPORT_PER_CPU_SYMBOL(cpu_info); |
| _ |