|
@@ -221,7 +221,8 @@ static int bnx2x_stats_comp(struct bnx2x *bp)
|
|
|
* Statistics service functions
|
|
|
*/
|
|
|
|
|
|
-static void bnx2x_stats_pmf_update(struct bnx2x *bp)
|
|
|
+/* should be called under stats_sema */
|
|
|
+static void __bnx2x_stats_pmf_update(struct bnx2x *bp)
|
|
|
{
|
|
|
struct dmae_command *dmae;
|
|
|
u32 opcode;
|
|
@@ -518,7 +519,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp)
|
|
|
*stats_comp = 0;
|
|
|
}
|
|
|
|
|
|
-static void bnx2x_stats_start(struct bnx2x *bp)
|
|
|
+/* should be called under stats_sema */
|
|
|
+static void __bnx2x_stats_start(struct bnx2x *bp)
|
|
|
{
|
|
|
/* vfs travel through here as part of the statistics FSM, but no action
|
|
|
* is required
|
|
@@ -534,13 +536,34 @@ static void bnx2x_stats_start(struct bnx2x *bp)
|
|
|
|
|
|
bnx2x_hw_stats_post(bp);
|
|
|
bnx2x_storm_stats_post(bp);
|
|
|
+
|
|
|
+ bp->stats_started = true;
|
|
|
+}
|
|
|
+
|
|
|
+static void bnx2x_stats_start(struct bnx2x *bp)
|
|
|
+{
|
|
|
+ if (down_timeout(&bp->stats_sema, HZ/10))
|
|
|
+ BNX2X_ERR("Unable to acquire stats lock\n");
|
|
|
+ __bnx2x_stats_start(bp);
|
|
|
+ up(&bp->stats_sema);
|
|
|
}
|
|
|
|
|
|
static void bnx2x_stats_pmf_start(struct bnx2x *bp)
|
|
|
{
|
|
|
+ if (down_timeout(&bp->stats_sema, HZ/10))
|
|
|
+ BNX2X_ERR("Unable to acquire stats lock\n");
|
|
|
bnx2x_stats_comp(bp);
|
|
|
- bnx2x_stats_pmf_update(bp);
|
|
|
- bnx2x_stats_start(bp);
|
|
|
+ __bnx2x_stats_pmf_update(bp);
|
|
|
+ __bnx2x_stats_start(bp);
|
|
|
+ up(&bp->stats_sema);
|
|
|
+}
|
|
|
+
|
|
|
+static void bnx2x_stats_pmf_update(struct bnx2x *bp)
|
|
|
+{
|
|
|
+ if (down_timeout(&bp->stats_sema, HZ/10))
|
|
|
+ BNX2X_ERR("Unable to acquire stats lock\n");
|
|
|
+ __bnx2x_stats_pmf_update(bp);
|
|
|
+ up(&bp->stats_sema);
|
|
|
}
|
|
|
|
|
|
static void bnx2x_stats_restart(struct bnx2x *bp)
|
|
@@ -550,8 +573,11 @@ static void bnx2x_stats_restart(struct bnx2x *bp)
|
|
|
*/
|
|
|
if (IS_VF(bp))
|
|
|
return;
|
|
|
+ if (down_timeout(&bp->stats_sema, HZ/10))
|
|
|
+ BNX2X_ERR("Unable to acquire stats lock\n");
|
|
|
bnx2x_stats_comp(bp);
|
|
|
- bnx2x_stats_start(bp);
|
|
|
+ __bnx2x_stats_start(bp);
|
|
|
+ up(&bp->stats_sema);
|
|
|
}
|
|
|
|
|
|
static void bnx2x_bmac_stats_update(struct bnx2x *bp)
|
|
@@ -888,9 +914,7 @@ static int bnx2x_storm_stats_validate_counters(struct bnx2x *bp)
|
|
|
/* Make sure we use the value of the counter
|
|
|
* used for sending the last stats ramrod.
|
|
|
*/
|
|
|
- spin_lock_bh(&bp->stats_lock);
|
|
|
cur_stats_counter = bp->stats_counter - 1;
|
|
|
- spin_unlock_bh(&bp->stats_lock);
|
|
|
|
|
|
/* are storm stats valid? */
|
|
|
if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) {
|
|
@@ -1227,12 +1251,18 @@ static void bnx2x_stats_update(struct bnx2x *bp)
|
|
|
{
|
|
|
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
|
|
|
|
|
|
- if (bnx2x_edebug_stats_stopped(bp))
|
|
|
+ /* we run update from timer context, so give up
|
|
|
+ * if somebody is in the middle of transition
|
|
|
+ */
|
|
|
+ if (down_trylock(&bp->stats_sema))
|
|
|
return;
|
|
|
|
|
|
+ if (bnx2x_edebug_stats_stopped(bp) || !bp->stats_started)
|
|
|
+ goto out;
|
|
|
+
|
|
|
if (IS_PF(bp)) {
|
|
|
if (*stats_comp != DMAE_COMP_VAL)
|
|
|
- return;
|
|
|
+ goto out;
|
|
|
|
|
|
if (bp->port.pmf)
|
|
|
bnx2x_hw_stats_update(bp);
|
|
@@ -1242,7 +1272,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
|
|
|
BNX2X_ERR("storm stats were not updated for 3 times\n");
|
|
|
bnx2x_panic();
|
|
|
}
|
|
|
- return;
|
|
|
+ goto out;
|
|
|
}
|
|
|
} else {
|
|
|
/* vf doesn't collect HW statistics, and doesn't get completions
|
|
@@ -1256,7 +1286,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
|
|
|
|
|
|
/* vf is done */
|
|
|
if (IS_VF(bp))
|
|
|
- return;
|
|
|
+ goto out;
|
|
|
|
|
|
if (netif_msg_timer(bp)) {
|
|
|
struct bnx2x_eth_stats *estats = &bp->eth_stats;
|
|
@@ -1267,6 +1297,9 @@ static void bnx2x_stats_update(struct bnx2x *bp)
|
|
|
|
|
|
bnx2x_hw_stats_post(bp);
|
|
|
bnx2x_storm_stats_post(bp);
|
|
|
+
|
|
|
+out:
|
|
|
+ up(&bp->stats_sema);
|
|
|
}
|
|
|
|
|
|
static void bnx2x_port_stats_stop(struct bnx2x *bp)
|
|
@@ -1332,6 +1365,11 @@ static void bnx2x_stats_stop(struct bnx2x *bp)
|
|
|
{
|
|
|
int update = 0;
|
|
|
|
|
|
+ if (down_timeout(&bp->stats_sema, HZ/10))
|
|
|
+ BNX2X_ERR("Unable to acquire stats lock\n");
|
|
|
+
|
|
|
+ bp->stats_started = false;
|
|
|
+
|
|
|
bnx2x_stats_comp(bp);
|
|
|
|
|
|
if (bp->port.pmf)
|
|
@@ -1348,6 +1386,8 @@ static void bnx2x_stats_stop(struct bnx2x *bp)
|
|
|
bnx2x_hw_stats_post(bp);
|
|
|
bnx2x_stats_comp(bp);
|
|
|
}
|
|
|
+
|
|
|
+ up(&bp->stats_sema);
|
|
|
}
|
|
|
|
|
|
static void bnx2x_stats_do_nothing(struct bnx2x *bp)
|
|
@@ -1376,15 +1416,17 @@ static const struct {
|
|
|
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
|
|
|
{
|
|
|
enum bnx2x_stats_state state;
|
|
|
+ void (*action)(struct bnx2x *bp);
|
|
|
if (unlikely(bp->panic))
|
|
|
return;
|
|
|
|
|
|
spin_lock_bh(&bp->stats_lock);
|
|
|
state = bp->stats_state;
|
|
|
bp->stats_state = bnx2x_stats_stm[state][event].next_state;
|
|
|
+ action = bnx2x_stats_stm[state][event].action;
|
|
|
spin_unlock_bh(&bp->stats_lock);
|
|
|
|
|
|
- bnx2x_stats_stm[state][event].action(bp);
|
|
|
+ action(bp);
|
|
|
|
|
|
if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
|
|
|
DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
|