diff options
author | David S. Miller <davem@davemloft.net> | 2010-07-28 00:01:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-28 00:01:35 -0400 |
commit | bb7e95c8fd859922c6cf3ebbb3a8546007df1748 (patch) | |
tree | 58b54c6306ba168b76f25cc6dc9a2d1d2eb830a7 /drivers/net/bnx2x/bnx2x_stats.c | |
parent | b8bc0421ab7f83712a0a8ef7eb05fa73ec53c027 (diff) | |
parent | 5447080cfa3c77154498dfbf225367ac85b4c2b5 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bnx2x_main.c
Merge bnx2x bug fixes in by hand... :-/
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_stats.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 3f512772042..c7472446102 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c | |||
@@ -156,6 +156,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) | |||
156 | struct eth_query_ramrod_data ramrod_data = {0}; | 156 | struct eth_query_ramrod_data ramrod_data = {0}; |
157 | int i, rc; | 157 | int i, rc; |
158 | 158 | ||
159 | spin_lock_bh(&bp->stats_lock); | ||
160 | |||
159 | ramrod_data.drv_counter = bp->stats_counter++; | 161 | ramrod_data.drv_counter = bp->stats_counter++; |
160 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; | 162 | ramrod_data.collect_port = bp->port.pmf ? 1 : 0; |
161 | for_each_queue(bp, i) | 163 | for_each_queue(bp, i) |
@@ -169,6 +171,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) | |||
169 | bp->spq_left++; | 171 | bp->spq_left++; |
170 | bp->stats_pending = 1; | 172 | bp->stats_pending = 1; |
171 | } | 173 | } |
174 | |||
175 | spin_unlock_bh(&bp->stats_lock); | ||
172 | } | 176 | } |
173 | } | 177 | } |
174 | 178 | ||
@@ -734,6 +738,14 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) | |||
734 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); | 738 | struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); |
735 | struct bnx2x_eth_stats *estats = &bp->eth_stats; | 739 | struct bnx2x_eth_stats *estats = &bp->eth_stats; |
736 | int i; | 740 | int i; |
741 | u16 cur_stats_counter; | ||
742 | |||
743 | /* Make sure we use the value of the counter | ||
744 | * used for sending the last stats ramrod. | ||
745 | */ | ||
746 | spin_lock_bh(&bp->stats_lock); | ||
747 | cur_stats_counter = bp->stats_counter - 1; | ||
748 | spin_unlock_bh(&bp->stats_lock); | ||
737 | 749 | ||
738 | memcpy(&(fstats->total_bytes_received_hi), | 750 | memcpy(&(fstats->total_bytes_received_hi), |
739 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), | 751 | &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), |
@@ -761,25 +773,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) | |||
761 | u32 diff; | 773 | u32 diff; |
762 | 774 | ||
763 | /* are storm stats valid? */ | 775 | /* are storm stats valid? */ |
764 | if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != | 776 | if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) { |
765 | bp->stats_counter) { | ||
766 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" | 777 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" |
767 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", | 778 | " xstorm counter (0x%x) != stats_counter (0x%x)\n", |
768 | i, xclient->stats_counter, bp->stats_counter); | 779 | i, xclient->stats_counter, cur_stats_counter + 1); |
769 | return -1; | 780 | return -1; |
770 | } | 781 | } |
771 | if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != | 782 | if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) { |
772 | bp->stats_counter) { | ||
773 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" | 783 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" |
774 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", | 784 | " tstorm counter (0x%x) != stats_counter (0x%x)\n", |
775 | i, tclient->stats_counter, bp->stats_counter); | 785 | i, tclient->stats_counter, cur_stats_counter + 1); |
776 | return -2; | 786 | return -2; |
777 | } | 787 | } |
778 | if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != | 788 | if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) { |
779 | bp->stats_counter) { | ||
780 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" | 789 | DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" |
781 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", | 790 | " ustorm counter (0x%x) != stats_counter (0x%x)\n", |
782 | i, uclient->stats_counter, bp->stats_counter); | 791 | i, uclient->stats_counter, cur_stats_counter + 1); |
783 | return -4; | 792 | return -4; |
784 | } | 793 | } |
785 | 794 | ||
@@ -1216,16 +1225,18 @@ static const struct { | |||
1216 | 1225 | ||
1217 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | 1226 | void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) |
1218 | { | 1227 | { |
1219 | enum bnx2x_stats_state state = bp->stats_state; | 1228 | enum bnx2x_stats_state state; |
1220 | 1229 | ||
1221 | if (unlikely(bp->panic)) | 1230 | if (unlikely(bp->panic)) |
1222 | return; | 1231 | return; |
1223 | 1232 | ||
1224 | bnx2x_stats_stm[state][event].action(bp); | 1233 | /* Protect a state change flow */ |
1234 | spin_lock_bh(&bp->stats_lock); | ||
1235 | state = bp->stats_state; | ||
1225 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | 1236 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; |
1237 | spin_unlock_bh(&bp->stats_lock); | ||
1226 | 1238 | ||
1227 | /* Make sure the state has been "changed" */ | 1239 | bnx2x_stats_stm[state][event].action(bp); |
1228 | smp_wmb(); | ||
1229 | 1240 | ||
1230 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | 1241 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) |
1231 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | 1242 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", |