[tip:core/locking] typhoon: fix a race in typhoon_do_get_stats

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  21ff2929edc89397cc4c621d3c3f842994640acd
Gitweb:     http://git.kernel.org/tip/21ff2929edc89397cc4c621d3c3f842994640acd
Author:     Eric Dumazet <eric.dumazet@xxxxxxxxx>
AuthorDate: Tue, 24 Aug 2010 04:18:13 +0000
Committer:  David S. Miller <davem@xxxxxxxxxxxxx>
CommitDate: Wed, 25 Aug 2010 16:36:49 -0700

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@xxxxxxxxx>
Acked-by: David Dillow <dave@xxxxxxxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
---
 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 2e50077..3f4681f 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp)
 	 * The extra status reported would be a good candidate for
 	 * ethtool_ops->get_{strings,stats}()
 	 */
-	stats->tx_packets = le32_to_cpu(s->txPackets);
-	stats->tx_bytes = le64_to_cpu(s->txBytes);
-	stats->tx_errors = le32_to_cpu(s->txCarrierLost);
-	stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost);
-	stats->collisions = le32_to_cpu(s->txMultipleCollisions);
-	stats->rx_packets = le32_to_cpu(s->rxPacketsGood);
-	stats->rx_bytes = le64_to_cpu(s->rxBytesGood);
-	stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns);
+	stats->tx_packets = le32_to_cpu(s->txPackets) +
+			saved->tx_packets;
+	stats->tx_bytes = le64_to_cpu(s->txBytes) +
+			saved->tx_bytes;
+	stats->tx_errors = le32_to_cpu(s->txCarrierLost) +
+			saved->tx_errors;
+	stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) +
+			saved->tx_carrier_errors;
+	stats->collisions = le32_to_cpu(s->txMultipleCollisions) +
+			saved->collisions;
+	stats->rx_packets = le32_to_cpu(s->rxPacketsGood) +
+			saved->rx_packets;
+	stats->rx_bytes = le64_to_cpu(s->rxBytesGood) +
+			saved->rx_bytes;
+	stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) +
+			saved->rx_fifo_errors;
 	stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
-			le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors);
-	stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors);
-	stats->rx_length_errors = le32_to_cpu(s->rxOversized);
+			le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) +
+			saved->rx_errors;
+	stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) +
+			saved->rx_crc_errors;
+	stats->rx_length_errors = le32_to_cpu(s->rxOversized) +
+			saved->rx_length_errors;
 	tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
 			SPEED_100 : SPEED_10;
 	tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 
-	/* add in the saved statistics
-	 */
-	stats->tx_packets += saved->tx_packets;
-	stats->tx_bytes += saved->tx_bytes;
-	stats->tx_errors += saved->tx_errors;
-	stats->collisions += saved->collisions;
-	stats->rx_packets += saved->rx_packets;
-	stats->rx_bytes += saved->rx_bytes;
-	stats->rx_fifo_errors += saved->rx_fifo_errors;
-	stats->rx_errors += saved->rx_errors;
-	stats->rx_crc_errors += saved->rx_crc_errors;
-	stats->rx_length_errors += saved->rx_length_errors;
-
 	return 0;
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux