Skip to content

Commit f11421b

Browse files
Fenghua Yudavem330
authored andcommitted
drivers/net/b44: Change to non-atomic bit operations on pwol_mask
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]>
1 parent b54ef37 commit f11421b

File tree

1 file changed

+6
-3
lines changed
  • drivers/net/ethernet/broadcom

1 file changed

+6
-3
lines changed

drivers/net/ethernet/broadcom/b44.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,8 +1516,10 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
15161516
int ethaddr_bytes = ETH_ALEN;
15171517

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

15221524
for (j = 0; j < B44_MAX_PATTERNS; j++) {
15231525
if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
@@ -1529,7 +1531,8 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
15291531
for (k = 0; k< ethaddr_bytes; k++) {
15301532
ppattern[offset + magicsync +
15311533
(j * ETH_ALEN) + k] = macaddr[k];
1532-
set_bit(len++, (unsigned long *) pmask);
1534+
pmask[len >> 3] |= BIT(len & 7);
1535+
len++;
15331536
}
15341537
}
15351538
return len - 1;

0 commit comments

Comments
 (0)