diff options
author | Anjali Singhai Jain <anjali.singhai@intel.com> | 2014-07-10 03:58:25 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2014-08-27 04:11:00 -0400 |
commit | 810b3ae42f5a6d1ddb17bb20eb69046de08ab1ef (patch) | |
tree | 90d543634f2b5f9e675d97e02aa0f1428f3e343a /drivers/net/ethernet/intel/i40e | |
parent | 30650cc552cf9a60fa80a205693c6f76f7a00549 (diff) |
i40e/i40evf: Ignore a driver perceived Tx hang if the number of desc pending < 4
We are seeing situations where the driver sees a hang with less than 4
desc pending, if the driver chooses to ignore it the queue progresses
forward and the stack never experiences a real hang.
With this patch we will log a stat when this situation happens
"tx_sluggish" will increment and we can see some more details
at a higher debug level. Other than that we will ignore this
particular case of Tx hang.
Change-ID: I7d1d1666d990e2b12f4f6bed0d17d22e1b6410d5
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/i40e')
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.h | 1 |
4 files changed, 14 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 85269509f420..4e97ba1b04de 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h | |||
@@ -316,6 +316,7 @@ struct i40e_pf { | |||
316 | u32 tx_timeout_count; | 316 | u32 tx_timeout_count; |
317 | u32 tx_timeout_recovery_level; | 317 | u32 tx_timeout_recovery_level; |
318 | unsigned long tx_timeout_last_recovery; | 318 | unsigned long tx_timeout_last_recovery; |
319 | u32 tx_sluggish_count; | ||
319 | u32 hw_csum_rx_error; | 320 | u32 hw_csum_rx_error; |
320 | u32 led_status; | 321 | u32 led_status; |
321 | u16 corer_count; /* Core reset count */ | 322 | u16 corer_count; /* Core reset count */ |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 5a0cabeb35ed..7067f4b9159c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c | |||
@@ -1356,6 +1356,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp, | |||
1356 | "emp reset count: %d\n", pf->empr_count); | 1356 | "emp reset count: %d\n", pf->empr_count); |
1357 | dev_info(&pf->pdev->dev, | 1357 | dev_info(&pf->pdev->dev, |
1358 | "pf reset count: %d\n", pf->pfr_count); | 1358 | "pf reset count: %d\n", pf->pfr_count); |
1359 | dev_info(&pf->pdev->dev, | ||
1360 | "pf tx sluggish count: %d\n", | ||
1361 | pf->tx_sluggish_count); | ||
1359 | } else if (strncmp(&cmd_buf[5], "port", 4) == 0) { | 1362 | } else if (strncmp(&cmd_buf[5], "port", 4) == 0) { |
1360 | struct i40e_aqc_query_port_ets_config_resp *bw_data; | 1363 | struct i40e_aqc_query_port_ets_config_resp *bw_data; |
1361 | struct i40e_dcbx_config *cfg = | 1364 | struct i40e_dcbx_config *cfg = |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 366624a51229..4bf49d2acb04 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -607,6 +607,7 @@ static u32 i40e_get_tx_pending(struct i40e_ring *ring) | |||
607 | static bool i40e_check_tx_hang(struct i40e_ring *tx_ring) | 607 | static bool i40e_check_tx_hang(struct i40e_ring *tx_ring) |
608 | { | 608 | { |
609 | u32 tx_pending = i40e_get_tx_pending(tx_ring); | 609 | u32 tx_pending = i40e_get_tx_pending(tx_ring); |
610 | struct i40e_pf *pf = tx_ring->vsi->back; | ||
610 | bool ret = false; | 611 | bool ret = false; |
611 | 612 | ||
612 | clear_check_for_tx_hang(tx_ring); | 613 | clear_check_for_tx_hang(tx_ring); |
@@ -623,10 +624,17 @@ static bool i40e_check_tx_hang(struct i40e_ring *tx_ring) | |||
623 | * pending but without time to complete it yet. | 624 | * pending but without time to complete it yet. |
624 | */ | 625 | */ |
625 | if ((tx_ring->tx_stats.tx_done_old == tx_ring->stats.packets) && | 626 | if ((tx_ring->tx_stats.tx_done_old == tx_ring->stats.packets) && |
626 | tx_pending) { | 627 | (tx_pending >= I40E_MIN_DESC_PENDING)) { |
627 | /* make sure it is true for two checks in a row */ | 628 | /* make sure it is true for two checks in a row */ |
628 | ret = test_and_set_bit(__I40E_HANG_CHECK_ARMED, | 629 | ret = test_and_set_bit(__I40E_HANG_CHECK_ARMED, |
629 | &tx_ring->state); | 630 | &tx_ring->state); |
631 | } else if ((tx_ring->tx_stats.tx_done_old == tx_ring->stats.packets) && | ||
632 | (tx_pending < I40E_MIN_DESC_PENDING) && | ||
633 | (tx_pending > 0)) { | ||
634 | if (I40E_DEBUG_FLOW & pf->hw.debug_mask) | ||
635 | dev_info(tx_ring->dev, "HW needs some more descs to do a cacheline flush. tx_pending %d, queue %d", | ||
636 | tx_pending, tx_ring->queue_index); | ||
637 | pf->tx_sluggish_count++; | ||
630 | } else { | 638 | } else { |
631 | /* update completed stats and disarm the hang check */ | 639 | /* update completed stats and disarm the hang check */ |
632 | tx_ring->tx_stats.tx_done_old = tx_ring->stats.packets; | 640 | tx_ring->tx_stats.tx_done_old = tx_ring->stats.packets; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 73f4fa425697..d7a625a6a14f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h | |||
@@ -121,6 +121,7 @@ enum i40e_dyn_idx_t { | |||
121 | /* Tx Descriptors needed, worst case */ | 121 | /* Tx Descriptors needed, worst case */ |
122 | #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) | 122 | #define TXD_USE_COUNT(S) DIV_ROUND_UP((S), I40E_MAX_DATA_PER_TXD) |
123 | #define DESC_NEEDED (MAX_SKB_FRAGS + 4) | 123 | #define DESC_NEEDED (MAX_SKB_FRAGS + 4) |
124 | #define I40E_MIN_DESC_PENDING 4 | ||
124 | 125 | ||
125 | #define I40E_TX_FLAGS_CSUM (u32)(1) | 126 | #define I40E_TX_FLAGS_CSUM (u32)(1) |
126 | #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) | 127 | #define I40E_TX_FLAGS_HW_VLAN (u32)(1 << 1) |