aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnjali Singhai Jain <anjali.singhai@intel.com>2014-07-10 04:03:26 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-08-27 02:51:37 -0400
commit1e1be8f622ee3d01acdbf5f4e00fbdd53ff950c9 (patch)
tree6b2c443e182d32aef21b5d0a683efca5b330a65e
parentf7233c5491156bc530ed965d4fabc55db35f2e37 (diff)
i40e: ATR policy change to flush the table to clean stale ATR rules
Instead of disabling ATR when we get a programming error, we now will wait it out to see if some room gets created by ATR rule deletion. If we still have too many errors and ATR filter count did not change much, its time to flush and replay. We no more auto-disable ATR when we have errors in programming. The disabling of ATR when we get programming error was buggy and was still adding new rules and causing continuous errors. With this policy change we flush instead when we see too many errors. ATR is still disabled if we add a SB rule for TCP/IPv4 flow type, more logic is added to re-enable it once all SB TCP/IPv4 rules are gone. Change-ID: I77edcbeab9500c72a7e0bd7b5c5b113ced133a9c Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com> Tested-by: Jim Young <jamesx.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c96
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c23
4 files changed, 111 insertions, 20 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 801da392a20e..0c6a9b97f7e2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -144,6 +144,7 @@ enum i40e_state_t {
144 __I40E_PTP_TX_IN_PROGRESS, 144 __I40E_PTP_TX_IN_PROGRESS,
145 __I40E_BAD_EEPROM, 145 __I40E_BAD_EEPROM,
146 __I40E_DOWN_REQUESTED, 146 __I40E_DOWN_REQUESTED,
147 __I40E_FD_FLUSH_REQUESTED,
147}; 148};
148 149
149enum i40e_interrupt_policy { 150enum i40e_interrupt_policy {
@@ -250,6 +251,10 @@ struct i40e_pf {
250 u16 fdir_pf_active_filters; 251 u16 fdir_pf_active_filters;
251 u16 fd_sb_cnt_idx; 252 u16 fd_sb_cnt_idx;
252 u16 fd_atr_cnt_idx; 253 u16 fd_atr_cnt_idx;
254 unsigned long fd_flush_timestamp;
255 u32 fd_add_err;
256 u32 fd_atr_cnt;
257 u32 fd_tcp_rule;
253 258
254#ifdef CONFIG_I40E_VXLAN 259#ifdef CONFIG_I40E_VXLAN
255 __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS]; 260 __be16 vxlan_ports[I40E_MAX_PF_UDP_OFFLOAD_PORTS];
@@ -608,6 +613,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
608void i40e_fdir_check_and_reenable(struct i40e_pf *pf); 613void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
609int i40e_get_current_fd_count(struct i40e_pf *pf); 614int i40e_get_current_fd_count(struct i40e_pf *pf);
610int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf); 615int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
616int i40e_get_current_atr_cnt(struct i40e_pf *pf);
611bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features); 617bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
612void i40e_set_ethtool_ops(struct net_device *netdev); 618void i40e_set_ethtool_ops(struct net_device *netdev);
613struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, 619struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index e8ba7470700a..7204e293dc71 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1977,6 +1977,9 @@ static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
1977 struct i40e_pf *pf = vsi->back; 1977 struct i40e_pf *pf = vsi->back;
1978 int ret = 0; 1978 int ret = 0;
1979 1979
1980 if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
1981 return -EBUSY;
1982
1980 ret = i40e_update_ethtool_fdir_entry(vsi, NULL, fsp->location, cmd); 1983 ret = i40e_update_ethtool_fdir_entry(vsi, NULL, fsp->location, cmd);
1981 1984
1982 i40e_fdir_check_and_reenable(pf); 1985 i40e_fdir_check_and_reenable(pf);
@@ -2010,6 +2013,9 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
2010 if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED) 2013 if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)
2011 return -ENOSPC; 2014 return -ENOSPC;
2012 2015
2016 if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
2017 return -EBUSY;
2018
2013 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs; 2019 fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
2014 2020
2015 if (fsp->location >= (pf->hw.func_caps.fd_filters_best_effort + 2021 if (fsp->location >= (pf->hw.func_caps.fd_filters_best_effort +
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index eddec6ba095b..cab9c9e3e694 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -4483,8 +4483,16 @@ static int i40e_up_complete(struct i40e_vsi *vsi)
4483 } 4483 }
4484 4484
4485 /* replay FDIR SB filters */ 4485 /* replay FDIR SB filters */
4486 if (vsi->type == I40E_VSI_FDIR) 4486 if (vsi->type == I40E_VSI_FDIR) {
4487 /* reset fd counters */
4488 pf->fd_add_err = pf->fd_atr_cnt = 0;
4489 if (pf->fd_tcp_rule > 0) {
4490 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
4491 dev_info(&pf->pdev->dev, "Forcing ATR off, sideband rules for TCP/IPv4 exist\n");
4492 pf->fd_tcp_rule = 0;
4493 }
4487 i40e_fdir_filter_restore(vsi); 4494 i40e_fdir_filter_restore(vsi);
4495 }
4488 i40e_service_event_schedule(pf); 4496 i40e_service_event_schedule(pf);
4489 4497
4490 return 0; 4498 return 0;
@@ -5125,6 +5133,7 @@ int i40e_get_current_fd_count(struct i40e_pf *pf)
5125 I40E_PFQF_FDSTAT_BEST_CNT_SHIFT); 5133 I40E_PFQF_FDSTAT_BEST_CNT_SHIFT);
5126 return fcnt_prog; 5134 return fcnt_prog;
5127} 5135}
5136
5128/** 5137/**
5129 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled 5138 * i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
5130 * @pf: board private structure 5139 * @pf: board private structure
@@ -5133,15 +5142,17 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
5133{ 5142{
5134 u32 fcnt_prog, fcnt_avail; 5143 u32 fcnt_prog, fcnt_avail;
5135 5144
5145 if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
5146 return;
5147
5136 /* Check if, FD SB or ATR was auto disabled and if there is enough room 5148 /* Check if, FD SB or ATR was auto disabled and if there is enough room
5137 * to re-enable 5149 * to re-enable
5138 */ 5150 */
5139 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
5140 (pf->flags & I40E_FLAG_FD_SB_ENABLED))
5141 return;
5142 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); 5151 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
5143 fcnt_avail = pf->fdir_pf_filter_count; 5152 fcnt_avail = pf->fdir_pf_filter_count;
5144 if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) { 5153 if ((fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) ||
5154 (pf->fd_add_err == 0) ||
5155 (i40e_get_current_atr_cnt(pf) < pf->fd_atr_cnt)) {
5145 if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) && 5156 if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
5146 (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) { 5157 (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
5147 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED; 5158 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
@@ -5158,23 +5169,83 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
5158 } 5169 }
5159} 5170}
5160 5171
5172#define I40E_MIN_FD_FLUSH_INTERVAL 10
5173/**
5174 * i40e_fdir_flush_and_replay - Function to flush all FD filters and replay SB
5175 * @pf: board private structure
5176 **/
5177static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
5178{
5179 int flush_wait_retry = 50;
5180 int reg;
5181
5182 if (time_after(jiffies, pf->fd_flush_timestamp +
5183 (I40E_MIN_FD_FLUSH_INTERVAL * HZ))) {
5184 set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
5185 pf->fd_flush_timestamp = jiffies;
5186 pf->auto_disable_flags |= I40E_FLAG_FD_SB_ENABLED;
5187 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
5188 /* flush all filters */
5189 wr32(&pf->hw, I40E_PFQF_CTL_1,
5190 I40E_PFQF_CTL_1_CLEARFDTABLE_MASK);
5191 i40e_flush(&pf->hw);
5192 pf->fd_add_err = 0;
5193 do {
5194 /* Check FD flush status every 5-6msec */
5195 usleep_range(5000, 6000);
5196 reg = rd32(&pf->hw, I40E_PFQF_CTL_1);
5197 if (!(reg & I40E_PFQF_CTL_1_CLEARFDTABLE_MASK))
5198 break;
5199 } while (flush_wait_retry--);
5200 if (reg & I40E_PFQF_CTL_1_CLEARFDTABLE_MASK) {
5201 dev_warn(&pf->pdev->dev, "FD table did not flush, needs more time\n");
5202 } else {
5203 /* replay sideband filters */
5204 i40e_fdir_filter_restore(pf->vsi[pf->lan_vsi]);
5205
5206 pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
5207 pf->auto_disable_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
5208 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
5209 clear_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
5210 dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
5211 }
5212 }
5213}
5214
5215/**
5216 * i40e_get_current_atr_count - Get the count of total FD ATR filters programmed
5217 * @pf: board private structure
5218 **/
5219int i40e_get_current_atr_cnt(struct i40e_pf *pf)
5220{
5221 return i40e_get_current_fd_count(pf) - pf->fdir_pf_active_filters;
5222}
5223
5224/* We can see up to 256 filter programming desc in transit if the filters are
5225 * being applied really fast; before we see the first
5226 * filter miss error on Rx queue 0. Accumulating enough error messages before
5227 * reacting will make sure we don't cause flush too often.
5228 */
5229#define I40E_MAX_FD_PROGRAM_ERROR 256
5230
5161/** 5231/**
5162 * i40e_fdir_reinit_subtask - Worker thread to reinit FDIR filter table 5232 * i40e_fdir_reinit_subtask - Worker thread to reinit FDIR filter table
5163 * @pf: board private structure 5233 * @pf: board private structure
5164 **/ 5234 **/
5165static void i40e_fdir_reinit_subtask(struct i40e_pf *pf) 5235static void i40e_fdir_reinit_subtask(struct i40e_pf *pf)
5166{ 5236{
5167 if (!(pf->flags & I40E_FLAG_FDIR_REQUIRES_REINIT))
5168 return;
5169 5237
5170 /* if interface is down do nothing */ 5238 /* if interface is down do nothing */
5171 if (test_bit(__I40E_DOWN, &pf->state)) 5239 if (test_bit(__I40E_DOWN, &pf->state))
5172 return; 5240 return;
5241
5242 if ((pf->fd_add_err >= I40E_MAX_FD_PROGRAM_ERROR) &&
5243 (i40e_get_current_atr_cnt(pf) >= pf->fd_atr_cnt) &&
5244 (i40e_get_current_atr_cnt(pf) > pf->fdir_pf_filter_count))
5245 i40e_fdir_flush_and_replay(pf);
5246
5173 i40e_fdir_check_and_reenable(pf); 5247 i40e_fdir_check_and_reenable(pf);
5174 5248
5175 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
5176 (pf->flags & I40E_FLAG_FD_SB_ENABLED))
5177 pf->flags &= ~I40E_FLAG_FDIR_REQUIRES_REINIT;
5178} 5249}
5179 5250
5180/** 5251/**
@@ -7086,6 +7157,11 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
7086 } 7157 }
7087 pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; 7158 pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
7088 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED; 7159 pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
7160 /* reset fd counters */
7161 pf->fd_add_err = pf->fd_atr_cnt = pf->fd_tcp_rule = 0;
7162 pf->fdir_pf_active_filters = 0;
7163 pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
7164 dev_info(&pf->pdev->dev, "ATR re-enabled.\n");
7089 /* if ATR was auto disabled it can be re-enabled. */ 7165 /* if ATR was auto disabled it can be re-enabled. */
7090 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) && 7166 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
7091 (pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED)) 7167 (pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 267c0e609a02..366624a51229 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -280,10 +280,18 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
280 tcp->source = fd_data->src_port; 280 tcp->source = fd_data->src_port;
281 281
282 if (add) { 282 if (add) {
283 pf->fd_tcp_rule++;
283 if (pf->flags & I40E_FLAG_FD_ATR_ENABLED) { 284 if (pf->flags & I40E_FLAG_FD_ATR_ENABLED) {
284 dev_info(&pf->pdev->dev, "Forcing ATR off, sideband rules for TCP/IPv4 flow being applied\n"); 285 dev_info(&pf->pdev->dev, "Forcing ATR off, sideband rules for TCP/IPv4 flow being applied\n");
285 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED; 286 pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
286 } 287 }
288 } else {
289 pf->fd_tcp_rule = (pf->fd_tcp_rule > 0) ?
290 (pf->fd_tcp_rule - 1) : 0;
291 if (pf->fd_tcp_rule == 0) {
292 pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
293 dev_info(&pf->pdev->dev, "ATR re-enabled due to no sideband TCP/IPv4 rules\n");
294 }
287 } 295 }
288 296
289 fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; 297 fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
@@ -462,6 +470,10 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
462 dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n", 470 dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
463 rx_desc->wb.qword0.hi_dword.fd_id); 471 rx_desc->wb.qword0.hi_dword.fd_id);
464 472
473 pf->fd_add_err++;
474 /* store the current atr filter count */
475 pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);
476
465 /* filter programming failed most likely due to table full */ 477 /* filter programming failed most likely due to table full */
466 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf); 478 fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
467 fcnt_avail = pf->fdir_pf_filter_count; 479 fcnt_avail = pf->fdir_pf_filter_count;
@@ -470,21 +482,12 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
470 * FD ATR/SB and then re-enable it when there is room. 482 * FD ATR/SB and then re-enable it when there is room.
471 */ 483 */
472 if (fcnt_prog >= (fcnt_avail - I40E_FDIR_BUFFER_FULL_MARGIN)) { 484 if (fcnt_prog >= (fcnt_avail - I40E_FDIR_BUFFER_FULL_MARGIN)) {
473 /* Turn off ATR first */ 485 if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
474 if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
475 !(pf->auto_disable_flags & 486 !(pf->auto_disable_flags &
476 I40E_FLAG_FD_ATR_ENABLED)) {
477 dev_warn(&pdev->dev, "FD filter space full, ATR for further flows will be turned off\n");
478 pf->auto_disable_flags |=
479 I40E_FLAG_FD_ATR_ENABLED;
480 pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
481 } else if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
482 !(pf->auto_disable_flags &
483 I40E_FLAG_FD_SB_ENABLED)) { 487 I40E_FLAG_FD_SB_ENABLED)) {
484 dev_warn(&pdev->dev, "FD filter space full, new ntuple rules will not be added\n"); 488 dev_warn(&pdev->dev, "FD filter space full, new ntuple rules will not be added\n");
485 pf->auto_disable_flags |= 489 pf->auto_disable_flags |=
486 I40E_FLAG_FD_SB_ENABLED; 490 I40E_FLAG_FD_SB_ENABLED;
487 pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
488 } 491 }
489 } else { 492 } else {
490 dev_info(&pdev->dev, 493 dev_info(&pdev->dev,