Skip to content

Commit

Permalink
net: fix race condition in several drivers when reading stats
Browse files Browse the repository at this point in the history
Fix race condition in several network drivers when reading stats on 32bit
UP architectures.  These drivers update their stats in a BH context and
therefore should use u64_stats_fetch_begin_bh/u64_stats_fetch_retry_bh
instead of u64_stats_fetch_begin/u64_stats_fetch_retry when reading the
stats.

Signed-off-by: Kevin Groeneveld <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
kgroeneveld authored and davem330 committed Jul 22, 2012
1 parent 0980e56 commit e390648
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 14 deletions.
4 changes: 2 additions & 2 deletions drivers/net/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev,

dstats = per_cpu_ptr(dev->dstats, i);
do {
start = u64_stats_fetch_begin(&dstats->syncp);
start = u64_stats_fetch_begin_bh(&dstats->syncp);
tbytes = dstats->tx_bytes;
tpackets = dstats->tx_packets;
} while (u64_stats_fetch_retry(&dstats->syncp, start));
} while (u64_stats_fetch_retry_bh(&dstats->syncp, start));
stats->tx_bytes += tbytes;
stats->tx_packets += tpackets;
}
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/neterion/vxge/vxge-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3131,12 +3131,12 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
u64 packets, bytes, multicast;

do {
start = u64_stats_fetch_begin(&rxstats->syncp);
start = u64_stats_fetch_begin_bh(&rxstats->syncp);

packets = rxstats->rx_frms;
multicast = rxstats->rx_mcast;
bytes = rxstats->rx_bytes;
} while (u64_stats_fetch_retry(&rxstats->syncp, start));
} while (u64_stats_fetch_retry_bh(&rxstats->syncp, start));

net_stats->rx_packets += packets;
net_stats->rx_bytes += bytes;
Expand All @@ -3146,11 +3146,11 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
net_stats->rx_dropped += rxstats->rx_dropped;

do {
start = u64_stats_fetch_begin(&txstats->syncp);
start = u64_stats_fetch_begin_bh(&txstats->syncp);

packets = txstats->tx_frms;
bytes = txstats->tx_bytes;
} while (u64_stats_fetch_retry(&txstats->syncp, start));
} while (u64_stats_fetch_retry_bh(&txstats->syncp, start));

net_stats->tx_packets += packets;
net_stats->tx_bytes += bytes;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev,

lb_stats = per_cpu_ptr(dev->lstats, i);
do {
start = u64_stats_fetch_begin(&lb_stats->syncp);
start = u64_stats_fetch_begin_bh(&lb_stats->syncp);
tbytes = lb_stats->bytes;
tpackets = lb_stats->packets;
} while (u64_stats_fetch_retry(&lb_stats->syncp, start));
} while (u64_stats_fetch_retry_bh(&lb_stats->syncp, start));
bytes += tbytes;
packets += tpackets;
}
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,16 +704,16 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
u64 tpackets, tbytes, rpackets, rbytes;

do {
start = u64_stats_fetch_begin(&stats->tx_syncp);
start = u64_stats_fetch_begin_bh(&stats->tx_syncp);
tpackets = stats->tx_packets;
tbytes = stats->tx_bytes;
} while (u64_stats_fetch_retry(&stats->tx_syncp, start));
} while (u64_stats_fetch_retry_bh(&stats->tx_syncp, start));

do {
start = u64_stats_fetch_begin(&stats->rx_syncp);
start = u64_stats_fetch_begin_bh(&stats->rx_syncp);
rpackets = stats->rx_packets;
rbytes = stats->rx_bytes;
} while (u64_stats_fetch_retry(&stats->rx_syncp, start));
} while (u64_stats_fetch_retry_bh(&stats->rx_syncp, start));

tot->rx_packets += rpackets;
tot->tx_packets += tpackets;
Expand Down
4 changes: 2 additions & 2 deletions net/bridge/br_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev,
const struct br_cpu_netstats *bstats
= per_cpu_ptr(br->stats, cpu);
do {
start = u64_stats_fetch_begin(&bstats->syncp);
start = u64_stats_fetch_begin_bh(&bstats->syncp);
memcpy(&tmp, bstats, sizeof(tmp));
} while (u64_stats_fetch_retry(&bstats->syncp, start));
} while (u64_stats_fetch_retry_bh(&bstats->syncp, start));
sum.tx_bytes += tmp.tx_bytes;
sum.tx_packets += tmp.tx_packets;
sum.rx_bytes += tmp.rx_bytes;
Expand Down

0 comments on commit e390648

Please sign in to comment.