Skip to content

Commit db8c33f

Browse files
Fenghua YuKAGA-KOKO
authored andcommitted
x86/cpu: Align the x86_capability array to size of unsigned long
The x86_capability array in cpuinfo_x86 is of type u32 and thus is naturally aligned to 4 bytes. But, set_bit() and clear_bit() require the array to be aligned to size of unsigned long (i.e. 8 bytes on 64-bit systems). The array pointer is handed into atomic bit operations. If the access is 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 the array 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 so it contains information WHY this is required ] Suggested-by: David Laight <[email protected]> Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Fenghua Yu <[email protected]> Signed-off-by: Tony Luck <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent f6a892d commit db8c33f

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

arch/x86/include/asm/processor.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,15 @@ struct cpuinfo_x86 {
9393
__u32 extended_cpuid_level;
9494
/* Maximum supported CPUID level, -1=no CPUID: */
9595
int cpuid_level;
96-
__u32 x86_capability[NCAPINTS + NBUGINTS];
96+
/*
97+
* Align to size of unsigned long because the x86_capability array
98+
* is passed to bitops which require the alignment. Use unnamed
99+
* union to enforce the array is aligned to size of unsigned long.
100+
*/
101+
union {
102+
__u32 x86_capability[NCAPINTS + NBUGINTS];
103+
unsigned long x86_capability_alignment;
104+
};
97105
char x86_vendor_id[16];
98106
char x86_model_id[64];
99107
/* in KB - valid for CPUS which support this call: */

0 commit comments

Comments
 (0)