aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2017-12-29 08:49:53 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-02-12 13:35:49 -0500
commit71dc371993625b4b1ae26214af74427765bfa3a2 (patch)
tree4ddce1e9c08a5b52f2f4cd06ee505e8755485557
parent40588ca6513729e4de60e49896aab0a7ee09df19 (diff)
i40e/i40evf: Clean up logic for adaptive ITR
The logic for dynamic ITR update is confusing at best as there were odd paths chosen for how to find the rings associated with a given queue based on the vector index and other inconsistencies throughout the code. This patch is an attempt to clean up the logic so that we can more easily understand what is going on. Specifically if there is a Rx or Tx ring that is enabled in dynamic mode on the q_vector it is allowed to override the other side of the interrupt moderation. While it isn't correct all this patch is doing is cleaning up the logic for now so that when we come through and fix it we can more easily identify that this is wrong. The other big change made here is that we replace references to: vsi->rx_rings[q_vector->v_idx]->itr_setting with: q_vector->rx.ring->itr_setting The general idea is we can avoid the long pointer chase since just accessing q_vector->rx.ring is a single pointer access versus having to chase down vsi->rx_rings, and then finding the pointer in the array, and finally chasing down the itr_setting from there. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c55
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c59
2 files changed, 28 insertions, 86 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index b9121a87ee46..6b3fe5d26dc1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1016,6 +1016,9 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
1016 int bytes_per_usec; 1016 int bytes_per_usec;
1017 unsigned int usecs, estimated_usecs; 1017 unsigned int usecs, estimated_usecs;
1018 1018
1019 if (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))
1020 return false;
1021
1019 if (rc->total_packets == 0 || !rc->itr) 1022 if (rc->total_packets == 0 || !rc->itr)
1020 return false; 1023 return false;
1021 1024
@@ -2288,15 +2291,6 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)
2288 2291
2289/* a small macro to shorten up some long lines */ 2292/* a small macro to shorten up some long lines */
2290#define INTREG I40E_PFINT_DYN_CTLN 2293#define INTREG I40E_PFINT_DYN_CTLN
2291static inline int get_rx_itr(struct i40e_vsi *vsi, int idx)
2292{
2293 return vsi->rx_rings[idx]->itr_setting;
2294}
2295
2296static inline int get_tx_itr(struct i40e_vsi *vsi, int idx)
2297{
2298 return vsi->tx_rings[idx]->itr_setting;
2299}
2300 2294
2301/** 2295/**
2302 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt 2296 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -2309,9 +2303,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
2309{ 2303{
2310 struct i40e_hw *hw = &vsi->back->hw; 2304 struct i40e_hw *hw = &vsi->back->hw;
2311 bool rx = false, tx = false; 2305 bool rx = false, tx = false;
2312 u32 rxval, txval; 2306 u32 txval;
2313 int idx = q_vector->v_idx;
2314 int rx_itr_setting, tx_itr_setting;
2315 2307
2316 /* If we don't have MSIX, then we only need to re-enable icr0 */ 2308 /* If we don't have MSIX, then we only need to re-enable icr0 */
2317 if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) { 2309 if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) {
@@ -2319,29 +2311,15 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
2319 return; 2311 return;
2320 } 2312 }
2321 2313
2322 /* avoid dynamic calculation if in countdown mode OR if
2323 * all dynamic is disabled
2324 */
2325 txval = i40e_buildreg_itr(I40E_ITR_NONE, 0); 2314 txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
2326 2315
2327 rx_itr_setting = get_rx_itr(vsi, idx); 2316 /* avoid dynamic calculation if in countdown mode */
2328 tx_itr_setting = get_tx_itr(vsi, idx); 2317 if (q_vector->itr_countdown > 0)
2329
2330 if (q_vector->itr_countdown > 0 ||
2331 (!ITR_IS_DYNAMIC(rx_itr_setting) &&
2332 !ITR_IS_DYNAMIC(tx_itr_setting))) {
2333 goto enable_int; 2318 goto enable_int;
2334 }
2335 2319
2336 if (ITR_IS_DYNAMIC(rx_itr_setting)) { 2320 /* these will return false if dynamic mode is disabled */
2337 rx = i40e_set_new_dynamic_itr(&q_vector->rx); 2321 rx = i40e_set_new_dynamic_itr(&q_vector->rx);
2338 rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr); 2322 tx = i40e_set_new_dynamic_itr(&q_vector->tx);
2339 }
2340
2341 if (ITR_IS_DYNAMIC(tx_itr_setting)) {
2342 tx = i40e_set_new_dynamic_itr(&q_vector->tx);
2343 txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
2344 }
2345 2323
2346 if (rx || tx) { 2324 if (rx || tx) {
2347 /* get the higher of the two ITR adjustments and 2325 /* get the higher of the two ITR adjustments and
@@ -2349,25 +2327,20 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
2349 * when in adaptive mode (Rx and/or Tx) 2327 * when in adaptive mode (Rx and/or Tx)
2350 */ 2328 */
2351 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr); 2329 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr);
2330 u32 rxval;
2352 2331
2353 q_vector->tx.itr = q_vector->rx.itr = itr; 2332 q_vector->tx.itr = q_vector->rx.itr = itr;
2354 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
2355 tx = true;
2356 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr);
2357 rx = true;
2358 }
2359 2333
2360 /* only need to enable the interrupt once, but need
2361 * to possibly update both ITR values
2362 */
2363 if (rx) {
2364 /* set the INTENA_MSK_MASK so that this first write 2334 /* set the INTENA_MSK_MASK so that this first write
2365 * won't actually enable the interrupt, instead just 2335 * won't actually enable the interrupt, instead just
2366 * updating the ITR (it's bit 31 PF and VF) 2336 * updating the ITR (it's bit 31 PF and VF)
2367 */ 2337 */
2368 rxval |= BIT(31); 2338 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr) | BIT(31);
2339
2369 /* don't check _DOWN because interrupt isn't being enabled */ 2340 /* don't check _DOWN because interrupt isn't being enabled */
2370 wr32(hw, INTREG(q_vector->reg_idx), rxval); 2341 wr32(hw, INTREG(q_vector->reg_idx), rxval);
2342
2343 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
2371 } 2344 }
2372 2345
2373enable_int: 2346enable_int:
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 291130af2985..3fd7e9731f49 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -413,6 +413,9 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
413 int bytes_per_usec; 413 int bytes_per_usec;
414 unsigned int usecs, estimated_usecs; 414 unsigned int usecs, estimated_usecs;
415 415
416 if (!rc->ring || !ITR_IS_DYNAMIC(rc->ring->itr_setting))
417 return false;
418
416 if (rc->total_packets == 0 || !rc->itr) 419 if (rc->total_packets == 0 || !rc->itr)
417 return false; 420 return false;
418 421
@@ -1471,19 +1474,6 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)
1471 1474
1472/* a small macro to shorten up some long lines */ 1475/* a small macro to shorten up some long lines */
1473#define INTREG I40E_VFINT_DYN_CTLN1 1476#define INTREG I40E_VFINT_DYN_CTLN1
1474static inline int get_rx_itr(struct i40e_vsi *vsi, int idx)
1475{
1476 struct i40evf_adapter *adapter = vsi->back;
1477
1478 return adapter->rx_rings[idx].itr_setting;
1479}
1480
1481static inline int get_tx_itr(struct i40e_vsi *vsi, int idx)
1482{
1483 struct i40evf_adapter *adapter = vsi->back;
1484
1485 return adapter->tx_rings[idx].itr_setting;
1486}
1487 1477
1488/** 1478/**
1489 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt 1479 * i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -1496,33 +1486,17 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
1496{ 1486{
1497 struct i40e_hw *hw = &vsi->back->hw; 1487 struct i40e_hw *hw = &vsi->back->hw;
1498 bool rx = false, tx = false; 1488 bool rx = false, tx = false;
1499 u32 rxval, txval; 1489 u32 txval;
1500 int idx = q_vector->v_idx;
1501 int rx_itr_setting, tx_itr_setting;
1502 1490
1503 /* avoid dynamic calculation if in countdown mode OR if
1504 * all dynamic is disabled
1505 */
1506 txval = i40e_buildreg_itr(I40E_ITR_NONE, 0); 1491 txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
1507 1492
1508 rx_itr_setting = get_rx_itr(vsi, idx); 1493 /* avoid dynamic calculation if in countdown mode */
1509 tx_itr_setting = get_tx_itr(vsi, idx); 1494 if (q_vector->itr_countdown > 0)
1510
1511 if (q_vector->itr_countdown > 0 ||
1512 (!ITR_IS_DYNAMIC(rx_itr_setting) &&
1513 !ITR_IS_DYNAMIC(tx_itr_setting))) {
1514 goto enable_int; 1495 goto enable_int;
1515 }
1516 1496
1517 if (ITR_IS_DYNAMIC(rx_itr_setting)) { 1497 /* these will return false if dynamic mode is disabled */
1518 rx = i40e_set_new_dynamic_itr(&q_vector->rx); 1498 rx = i40e_set_new_dynamic_itr(&q_vector->rx);
1519 rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr); 1499 tx = i40e_set_new_dynamic_itr(&q_vector->tx);
1520 }
1521
1522 if (ITR_IS_DYNAMIC(tx_itr_setting)) {
1523 tx = i40e_set_new_dynamic_itr(&q_vector->tx);
1524 txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
1525 }
1526 1500
1527 if (rx || tx) { 1501 if (rx || tx) {
1528 /* get the higher of the two ITR adjustments and 1502 /* get the higher of the two ITR adjustments and
@@ -1530,25 +1504,20 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
1530 * when in adaptive mode (Rx and/or Tx) 1504 * when in adaptive mode (Rx and/or Tx)
1531 */ 1505 */
1532 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr); 1506 u16 itr = max(q_vector->tx.itr, q_vector->rx.itr);
1507 u32 rxval;
1533 1508
1534 q_vector->tx.itr = q_vector->rx.itr = itr; 1509 q_vector->tx.itr = q_vector->rx.itr = itr;
1535 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
1536 tx = true;
1537 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr);
1538 rx = true;
1539 }
1540 1510
1541 /* only need to enable the interrupt once, but need
1542 * to possibly update both ITR values
1543 */
1544 if (rx) {
1545 /* set the INTENA_MSK_MASK so that this first write 1511 /* set the INTENA_MSK_MASK so that this first write
1546 * won't actually enable the interrupt, instead just 1512 * won't actually enable the interrupt, instead just
1547 * updating the ITR (it's bit 31 PF and VF) 1513 * updating the ITR (it's bit 31 PF and VF)
1548 */ 1514 */
1549 rxval |= BIT(31); 1515 rxval = i40e_buildreg_itr(I40E_RX_ITR, itr) | BIT(31);
1516
1550 /* don't check _DOWN because interrupt isn't being enabled */ 1517 /* don't check _DOWN because interrupt isn't being enabled */
1551 wr32(hw, INTREG(q_vector->reg_idx), rxval); 1518 wr32(hw, INTREG(q_vector->reg_idx), rxval);
1519
1520 txval = i40e_buildreg_itr(I40E_TX_ITR, itr);
1552 } 1521 }
1553 1522
1554enable_int: 1523enable_int: