diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-08-24 00:18:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-25 19:36:49 -0400 |
commit | 21ff2929edc89397cc4c621d3c3f842994640acd (patch) | |
tree | 46f75007ed886061101d05e2acfd9901ffa3d3ec | |
parent | 884c06f4777c598ea7bf4fbc7557ff2fca066f63 (diff) |
typhoon: fix a race in typhoon_do_get_stats
Its important to store 'final' values in counters,
not using them as temporary variables,
or this might break some SNMP applications.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: David Dillow <dave@thedillows.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/typhoon.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 2e50077ff450..3f4681f78262 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp) | |||
962 | * The extra status reported would be a good candidate for | 962 | * The extra status reported would be a good candidate for |
963 | * ethtool_ops->get_{strings,stats}() | 963 | * ethtool_ops->get_{strings,stats}() |
964 | */ | 964 | */ |
965 | stats->tx_packets = le32_to_cpu(s->txPackets); | 965 | stats->tx_packets = le32_to_cpu(s->txPackets) + |
966 | stats->tx_bytes = le64_to_cpu(s->txBytes); | 966 | saved->tx_packets; |
967 | stats->tx_errors = le32_to_cpu(s->txCarrierLost); | 967 | stats->tx_bytes = le64_to_cpu(s->txBytes) + |
968 | stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost); | 968 | saved->tx_bytes; |
969 | stats->collisions = le32_to_cpu(s->txMultipleCollisions); | 969 | stats->tx_errors = le32_to_cpu(s->txCarrierLost) + |
970 | stats->rx_packets = le32_to_cpu(s->rxPacketsGood); | 970 | saved->tx_errors; |
971 | stats->rx_bytes = le64_to_cpu(s->rxBytesGood); | 971 | stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) + |
972 | stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns); | 972 | saved->tx_carrier_errors; |
973 | stats->collisions = le32_to_cpu(s->txMultipleCollisions) + | ||
974 | saved->collisions; | ||
975 | stats->rx_packets = le32_to_cpu(s->rxPacketsGood) + | ||
976 | saved->rx_packets; | ||
977 | stats->rx_bytes = le64_to_cpu(s->rxBytesGood) + | ||
978 | saved->rx_bytes; | ||
979 | stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) + | ||
980 | saved->rx_fifo_errors; | ||
973 | stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + | 981 | stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + |
974 | le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors); | 982 | le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) + |
975 | stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors); | 983 | saved->rx_errors; |
976 | stats->rx_length_errors = le32_to_cpu(s->rxOversized); | 984 | stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) + |
985 | saved->rx_crc_errors; | ||
986 | stats->rx_length_errors = le32_to_cpu(s->rxOversized) + | ||
987 | saved->rx_length_errors; | ||
977 | tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? | 988 | tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? |
978 | SPEED_100 : SPEED_10; | 989 | SPEED_100 : SPEED_10; |
979 | tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? | 990 | tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? |
980 | DUPLEX_FULL : DUPLEX_HALF; | 991 | DUPLEX_FULL : DUPLEX_HALF; |
981 | 992 | ||
982 | /* add in the saved statistics | ||
983 | */ | ||
984 | stats->tx_packets += saved->tx_packets; | ||
985 | stats->tx_bytes += saved->tx_bytes; | ||
986 | stats->tx_errors += saved->tx_errors; | ||
987 | stats->collisions += saved->collisions; | ||
988 | stats->rx_packets += saved->rx_packets; | ||
989 | stats->rx_bytes += saved->rx_bytes; | ||
990 | stats->rx_fifo_errors += saved->rx_fifo_errors; | ||
991 | stats->rx_errors += saved->rx_errors; | ||
992 | stats->rx_crc_errors += saved->rx_crc_errors; | ||
993 | stats->rx_length_errors += saved->rx_length_errors; | ||
994 | |||
995 | return 0; | 993 | return 0; |
996 | } | 994 | } |
997 | 995 | ||