Skip to content

Commit

Permalink
net/mv643xx: don't disable the mib timer too early and lock properly
Browse files Browse the repository at this point in the history
mib_counters_update() also restarts the timer.
So the timer is dequeued, the stats are read and then the timer is
enqueued again. This is "okay" unless someone unloads the module.
The locking here is also broken:
mib_counters_update() grabs just a simple spinlock. The only thing the
lock is good for is to protect the timer func against other callers
namely mv643xx_eth_stop() && mv643xx_eth_get_ethtool_stats(). That means
if the spinlock is taken via the ethtool path and than the timer kicks
in then the box will lock up.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Acked-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sebastian Siewior authored and David S. Miller committed Feb 19, 2009
1 parent 82a5bd6 commit 57e8f26
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions drivers/net/mv643xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
{
struct mib_counters *p = &mp->mib_counters;

spin_lock(&mp->mib_counters_lock);
spin_lock_bh(&mp->mib_counters_lock);
p->good_octets_received += mib_read(mp, 0x00);
p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
p->bad_octets_received += mib_read(mp, 0x08);
Expand Down Expand Up @@ -1208,7 +1208,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
p->bad_crc_event += mib_read(mp, 0x74);
p->collision += mib_read(mp, 0x78);
p->late_collision += mib_read(mp, 0x7c);
spin_unlock(&mp->mib_counters_lock);
spin_unlock_bh(&mp->mib_counters_lock);

mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
}
Expand Down Expand Up @@ -2216,8 +2216,6 @@ static int mv643xx_eth_stop(struct net_device *dev)
wrlp(mp, INT_MASK, 0x00000000);
rdlp(mp, INT_MASK);

del_timer_sync(&mp->mib_counters_timer);

napi_disable(&mp->napi);

del_timer_sync(&mp->rx_oom);
Expand All @@ -2229,6 +2227,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
port_reset(mp);
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
del_timer_sync(&mp->mib_counters_timer);

skb_queue_purge(&mp->rx_recycle);

Expand Down

0 comments on commit 57e8f26

Please sign in to comment.