Skip to content

Commit fa52f15

Browse files
Sean Andersonkuba-moo
authored andcommitted
net: cadence: macb: Synchronize stats calculations
Stats calculations involve a RMW to add the stat update to the existing value. This is currently not protected by any synchronization mechanism, so data races are possible. Add a spinlock to protect the update. The reader side could be protected using u64_stats, but we would still need a spinlock for the update side anyway. And we always do an update immediately before reading the stats anyway. Fixes: 89e5785 ("[PATCH] Atmel MACB ethernet driver") Signed-off-by: Sean Anderson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 27843ce commit fa52f15

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

drivers/net/ethernet/cadence/macb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,8 @@ struct macb {
12791279
struct clk *rx_clk;
12801280
struct clk *tsu_clk;
12811281
struct net_device *dev;
1282+
/* Protects hw_stats and ethtool_stats */
1283+
spinlock_t stats_lock;
12821284
union {
12831285
struct macb_stats macb;
12841286
struct gem_stats gem;

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,10 +1978,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
19781978

19791979
if (status & MACB_BIT(ISR_ROVR)) {
19801980
/* We missed at least one packet */
1981+
spin_lock(&bp->stats_lock);
19811982
if (macb_is_gem(bp))
19821983
bp->hw_stats.gem.rx_overruns++;
19831984
else
19841985
bp->hw_stats.macb.rx_overruns++;
1986+
spin_unlock(&bp->stats_lock);
19851987

19861988
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
19871989
queue_writel(queue, ISR, MACB_BIT(ISR_ROVR));
@@ -3102,6 +3104,7 @@ static struct net_device_stats *gem_get_stats(struct macb *bp)
31023104
if (!netif_running(bp->dev))
31033105
return nstat;
31043106

3107+
spin_lock_irq(&bp->stats_lock);
31053108
gem_update_stats(bp);
31063109

31073110
nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors +
@@ -3131,19 +3134,21 @@ static struct net_device_stats *gem_get_stats(struct macb *bp)
31313134
nstat->tx_aborted_errors = hwstat->tx_excessive_collisions;
31323135
nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors;
31333136
nstat->tx_fifo_errors = hwstat->tx_underrun;
3137+
spin_unlock_irq(&bp->stats_lock);
31343138

31353139
return nstat;
31363140
}
31373141

31383142
static void gem_get_ethtool_stats(struct net_device *dev,
31393143
struct ethtool_stats *stats, u64 *data)
31403144
{
3141-
struct macb *bp;
3145+
struct macb *bp = netdev_priv(dev);
31423146

3143-
bp = netdev_priv(dev);
3147+
spin_lock_irq(&bp->stats_lock);
31443148
gem_update_stats(bp);
31453149
memcpy(data, &bp->ethtool_stats, sizeof(u64)
31463150
* (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES));
3151+
spin_unlock_irq(&bp->stats_lock);
31473152
}
31483153

31493154
static int gem_get_sset_count(struct net_device *dev, int sset)
@@ -3193,6 +3198,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
31933198
return gem_get_stats(bp);
31943199

31953200
/* read stats from hardware */
3201+
spin_lock_irq(&bp->stats_lock);
31963202
macb_update_stats(bp);
31973203

31983204
/* Convert HW stats into netdevice stats */
@@ -3226,6 +3232,7 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
32263232
nstat->tx_carrier_errors = hwstat->tx_carrier_errors;
32273233
nstat->tx_fifo_errors = hwstat->tx_underruns;
32283234
/* Don't know about heartbeat or window errors... */
3235+
spin_unlock_irq(&bp->stats_lock);
32293236

32303237
return nstat;
32313238
}
@@ -5097,6 +5104,7 @@ static int macb_probe(struct platform_device *pdev)
50975104
}
50985105
}
50995106
spin_lock_init(&bp->lock);
5107+
spin_lock_init(&bp->stats_lock);
51005108

51015109
/* setup capabilities */
51025110
macb_configure_caps(bp, macb_config);

0 commit comments

Comments
 (0)