Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: dlink: add synchronization for stats update

This patch synchronizes code that accesses from both user-space
and IRQ contexts. The `get_stats()` function can be called from both
context.

`dev->stats.tx_errors` and `dev->stats.collisions` are also updated
in the `tx_errors()` function. Therefore, these fields must also be
protected by synchronized.

There is no code that accessses `dev->stats.tx_errors` between the
previous and updated lines, so the updating point can be moved.

Signed-off-by: Moon Yeounsu <yyyynoom@gmail.com>
Link: https://patch.msgid.link/20250515075333.48290-1-yyyynoom@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Moon Yeounsu and committed by
Jakub Kicinski
12889ce9 b66b76a8

+15 -1
+13 -1
drivers/net/ethernet/dlink/dl2k.c
··· 146 146 np->ioaddr = ioaddr; 147 147 np->chip_id = chip_idx; 148 148 np->pdev = pdev; 149 + 150 + spin_lock_init(&np->stats_lock); 149 151 spin_lock_init (&np->tx_lock); 150 152 spin_lock_init (&np->rx_lock); 151 153 ··· 867 865 frame_id = (tx_status & 0xffff0000); 868 866 printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n", 869 867 dev->name, tx_status, frame_id); 870 - dev->stats.tx_errors++; 871 868 /* Ttransmit Underrun */ 872 869 if (tx_status & 0x10) { 873 870 dev->stats.tx_fifo_errors++; ··· 903 902 rio_set_led_mode(dev); 904 903 /* Let TxStartThresh stay default value */ 905 904 } 905 + 906 + spin_lock(&np->stats_lock); 906 907 /* Maximum Collisions */ 907 908 if (tx_status & 0x08) 908 909 dev->stats.collisions++; 910 + 911 + dev->stats.tx_errors++; 912 + spin_unlock(&np->stats_lock); 913 + 909 914 /* Restart the Tx */ 910 915 dw32(MACCtrl, dr16(MACCtrl) | TxEnable); 911 916 } ··· 1080 1073 int i; 1081 1074 #endif 1082 1075 unsigned int stat_reg; 1076 + unsigned long flags; 1083 1077 1078 + spin_lock_irqsave(&np->stats_lock, flags); 1084 1079 /* All statistics registers need to be acknowledged, 1085 1080 else statistic overflow could cause problems */ 1086 1081 ··· 1132 1123 dr16(TCPCheckSumErrors); 1133 1124 dr16(UDPCheckSumErrors); 1134 1125 dr16(IPCheckSumErrors); 1126 + 1127 + spin_unlock_irqrestore(&np->stats_lock, flags); 1128 + 1135 1129 return &dev->stats; 1136 1130 } 1137 1131
+2
drivers/net/ethernet/dlink/dl2k.h
··· 372 372 struct pci_dev *pdev; 373 373 void __iomem *ioaddr; 374 374 void __iomem *eeprom_addr; 375 + // To ensure synchronization when stats are updated. 376 + spinlock_t stats_lock; 375 377 spinlock_t tx_lock; 376 378 spinlock_t rx_lock; 377 379 unsigned int rx_buf_sz; /* Based on MTU+slack. */