Skip to content

Commit f6a892d

Browse files
Fenghua YuKAGA-KOKO
authored andcommitted
x86/cpu: Align cpu_caps_cleared and cpu_caps_set to unsigned long
cpu_caps_cleared[] and cpu_caps_set[] are arrays of type u32 and therefore naturally aligned to 4 bytes, which is also unsigned long aligned on 32-bit, but not on 64-bit. The array pointer is handed into atomic bit operations. If the access not aligned to unsigned long then the atomic bit operations can end up crossing a cache line boundary, which causes the CPU to do a full bus lock as it can't lock both cache lines at once. The bus lock operation is heavy weight and can cause severe performance degradation. The upcoming #AC split lock detection mechanism will issue warnings for this kind of access. Force the alignment of these arrays to unsigned long. This avoids the massive code changes which would be required when converting the array data type to unsigned long. [ tglx: Rewrote changelog ] Signed-off-by: Fenghua Yu <[email protected]> Signed-off-by: Tony Luck <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 9774a96 commit f6a892d

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

arch/x86/kernel/cpu/common.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,9 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)
565565
return NULL; /* Not found */
566566
}
567567

568-
__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
569-
__u32 cpu_caps_set[NCAPINTS + NBUGINTS];
568+
/* Aligned to unsigned long to avoid split lock in atomic bitmap ops */
569+
__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
570+
__u32 cpu_caps_set[NCAPINTS + NBUGINTS] __aligned(sizeof(unsigned long));
570571

571572
void load_percpu_segment(int cpu)
572573
{

0 commit comments

Comments
 (0)