• Sander Vanheule's avatar
    x86/cacheinfo: move shared cache map definitions · adbcaef8
    Sander Vanheule authored
    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.netSigned-off-by: default avatarSander 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: default avatarAndrew Morton <akpm@linux-foundation.org>
    adbcaef8
smpboot.c 45.6 KB