Skip to content

Commit

Permalink
drivers/net/b44: Change to non-atomic bit operations on pwol_mask
Browse files Browse the repository at this point in the history
Atomic operations that span cache lines are super-expensive on x86
(not just to the current processor, but also to other processes as all
memory operations are blocked until the operation completes). Upcoming
x86 processors have a switch to cause such operations to generate a #AC
trap. It is expected that some real time systems will enable this mode
in BIOS.

In preparation for this, it is necessary to fix code that may execute
atomic instructions with operands that cross cachelines because the #AC
trap will crash the kernel.

Since "pwol_mask" is local and never exposed to concurrency, there is
no need to set bits in pwol_mask using atomic operations.

Directly operate on the byte which contains the bit instead of using
__set_bit() to avoid any big endian concern due to type cast to
unsigned long in __set_bit().

Suggested-by: Peter Zijlstra <[email protected]>
Signed-off-by: Fenghua Yu <[email protected]>
Signed-off-by: Tony Luck <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
fyu1 authored and davem330 committed Jan 5, 2020
1 parent b54ef37 commit f11421b
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/net/ethernet/broadcom/b44.c
Original file line number Diff line number Diff line change
Expand Up @@ -1516,8 +1516,10 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
int ethaddr_bytes = ETH_ALEN;

memset(ppattern + offset, 0xff, magicsync);
for (j = 0; j < magicsync; j++)
set_bit(len++, (unsigned long *) pmask);
for (j = 0; j < magicsync; j++) {
pmask[len >> 3] |= BIT(len & 7);
len++;
}

for (j = 0; j < B44_MAX_PATTERNS; j++) {
if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
Expand All @@ -1529,7 +1531,8 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
for (k = 0; k< ethaddr_bytes; k++) {
ppattern[offset + magicsync +
(j * ETH_ALEN) + k] = macaddr[k];
set_bit(len++, (unsigned long *) pmask);
pmask[len >> 3] |= BIT(len & 7);
len++;
}
}
return len - 1;
Expand Down

0 comments on commit f11421b

Please sign in to comment.