Skip to content

Commit de32e3e

Browse files
Carolyn WybornyJeff Kirsher
authored andcommitted
i40e/i40evf: Fix and refactor dynamic ITR code
This patch changes the switch statement for dynamic interrupt throttling and adds a default case. With this patch, we check the latency setting instead of the current ITR settings and the included refactor improves performance. Without this patch, the ITR setting would never change dynamically, and there was no default. Change-ID: Idb5a8a14c7109ec47c90f6e94bd43baa17d7ee37 Signed-off-by: Carolyn Wyborny <[email protected]> Signed-off-by: Anjali Singhai Jain <[email protected]> Tested-by: Jim Young <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 6fb4690 commit de32e3e

File tree

2 files changed

+161
-98
lines changed

2 files changed

+161
-98
lines changed

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 88 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
892892
* 20-1249MB/s bulk (8000 ints/s)
893893
*/
894894
bytes_per_int = rc->total_bytes / rc->itr;
895-
switch (rc->itr) {
895+
switch (new_latency_range) {
896896
case I40E_LOWEST_LATENCY:
897897
if (bytes_per_int > 10)
898898
new_latency_range = I40E_LOW_LATENCY;
@@ -905,9 +905,14 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
905905
break;
906906
case I40E_BULK_LATENCY:
907907
if (bytes_per_int <= 20)
908-
rc->latency_range = I40E_LOW_LATENCY;
908+
new_latency_range = I40E_LOW_LATENCY;
909+
break;
910+
default:
911+
if (bytes_per_int <= 20)
912+
new_latency_range = I40E_LOW_LATENCY;
909913
break;
910914
}
915+
rc->latency_range = new_latency_range;
911916

912917
switch (new_latency_range) {
913918
case I40E_LOWEST_LATENCY:
@@ -923,41 +928,13 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
923928
break;
924929
}
925930

926-
if (new_itr != rc->itr) {
927-
/* do an exponential smoothing */
928-
new_itr = (10 * new_itr * rc->itr) /
929-
((9 * new_itr) + rc->itr);
930-
rc->itr = new_itr & I40E_MAX_ITR;
931-
}
931+
if (new_itr != rc->itr)
932+
rc->itr = new_itr;
932933

933934
rc->total_bytes = 0;
934935
rc->total_packets = 0;
935936
}
936937

937-
/**
938-
* i40e_update_dynamic_itr - Adjust ITR based on bytes per int
939-
* @q_vector: the vector to adjust
940-
**/
941-
static void i40e_update_dynamic_itr(struct i40e_q_vector *q_vector)
942-
{
943-
u16 vector = q_vector->vsi->base_vector + q_vector->v_idx;
944-
struct i40e_hw *hw = &q_vector->vsi->back->hw;
945-
u32 reg_addr;
946-
u16 old_itr;
947-
948-
reg_addr = I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1);
949-
old_itr = q_vector->rx.itr;
950-
i40e_set_new_dynamic_itr(&q_vector->rx);
951-
if (old_itr != q_vector->rx.itr)
952-
wr32(hw, reg_addr, q_vector->rx.itr);
953-
954-
reg_addr = I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1);
955-
old_itr = q_vector->tx.itr;
956-
i40e_set_new_dynamic_itr(&q_vector->tx);
957-
if (old_itr != q_vector->tx.itr)
958-
wr32(hw, reg_addr, q_vector->tx.itr);
959-
}
960-
961938
/**
962939
* i40e_clean_programming_status - clean the programming status descriptor
963940
* @rx_ring: the rx ring that has this descriptor
@@ -1826,6 +1803,68 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
18261803
return total_rx_packets;
18271804
}
18281805

1806+
/**
1807+
* i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
1808+
* @vsi: the VSI we care about
1809+
* @q_vector: q_vector for which itr is being updated and interrupt enabled
1810+
*
1811+
**/
1812+
static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
1813+
struct i40e_q_vector *q_vector)
1814+
{
1815+
struct i40e_hw *hw = &vsi->back->hw;
1816+
u16 old_itr;
1817+
int vector;
1818+
u32 val;
1819+
1820+
vector = (q_vector->v_idx + vsi->base_vector);
1821+
if (ITR_IS_DYNAMIC(vsi->rx_itr_setting)) {
1822+
old_itr = q_vector->rx.itr;
1823+
i40e_set_new_dynamic_itr(&q_vector->rx);
1824+
if (old_itr != q_vector->rx.itr) {
1825+
val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
1826+
I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
1827+
(I40E_RX_ITR <<
1828+
I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
1829+
(q_vector->rx.itr <<
1830+
I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT);
1831+
} else {
1832+
val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
1833+
I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
1834+
(I40E_ITR_NONE <<
1835+
I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT);
1836+
}
1837+
if (!test_bit(__I40E_DOWN, &vsi->state))
1838+
wr32(hw, I40E_PFINT_DYN_CTLN(vector - 1), val);
1839+
} else {
1840+
i40e_irq_dynamic_enable(vsi,
1841+
q_vector->v_idx + vsi->base_vector);
1842+
}
1843+
if (ITR_IS_DYNAMIC(vsi->tx_itr_setting)) {
1844+
old_itr = q_vector->tx.itr;
1845+
i40e_set_new_dynamic_itr(&q_vector->tx);
1846+
if (old_itr != q_vector->tx.itr) {
1847+
val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
1848+
I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
1849+
(I40E_TX_ITR <<
1850+
I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
1851+
(q_vector->tx.itr <<
1852+
I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT);
1853+
} else {
1854+
val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
1855+
I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
1856+
(I40E_ITR_NONE <<
1857+
I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT);
1858+
}
1859+
if (!test_bit(__I40E_DOWN, &vsi->state))
1860+
wr32(hw, I40E_PFINT_DYN_CTLN(q_vector->v_idx +
1861+
vsi->base_vector - 1), val);
1862+
} else {
1863+
i40e_irq_dynamic_enable(vsi,
1864+
q_vector->v_idx + vsi->base_vector);
1865+
}
1866+
}
1867+
18291868
/**
18301869
* i40e_napi_poll - NAPI polling Rx/Tx cleanup routine
18311870
* @napi: napi struct with our devices info in it
@@ -1882,33 +1921,24 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
18821921

18831922
/* Work is done so exit the polling mode and re-enable the interrupt */
18841923
napi_complete(napi);
1885-
if (ITR_IS_DYNAMIC(vsi->rx_itr_setting) ||
1886-
ITR_IS_DYNAMIC(vsi->tx_itr_setting))
1887-
i40e_update_dynamic_itr(q_vector);
1888-
1889-
if (!test_bit(__I40E_DOWN, &vsi->state)) {
1890-
if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
1891-
i40e_irq_dynamic_enable(vsi,
1892-
q_vector->v_idx + vsi->base_vector);
1893-
} else {
1894-
struct i40e_hw *hw = &vsi->back->hw;
1895-
/* We re-enable the queue 0 cause, but
1896-
* don't worry about dynamic_enable
1897-
* because we left it on for the other
1898-
* possible interrupts during napi
1899-
*/
1900-
u32 qval = rd32(hw, I40E_QINT_RQCTL(0));
1901-
qval |= I40E_QINT_RQCTL_CAUSE_ENA_MASK;
1902-
wr32(hw, I40E_QINT_RQCTL(0), qval);
1903-
1904-
qval = rd32(hw, I40E_QINT_TQCTL(0));
1905-
qval |= I40E_QINT_TQCTL_CAUSE_ENA_MASK;
1906-
wr32(hw, I40E_QINT_TQCTL(0), qval);
1907-
1908-
i40e_irq_dynamic_enable_icr0(vsi->back);
1909-
}
1924+
if (vsi->back->flags & I40E_FLAG_MSIX_ENABLED) {
1925+
i40e_update_enable_itr(vsi, q_vector);
1926+
} else { /* Legacy mode */
1927+
struct i40e_hw *hw = &vsi->back->hw;
1928+
/* We re-enable the queue 0 cause, but
1929+
* don't worry about dynamic_enable
1930+
* because we left it on for the other
1931+
* possible interrupts during napi
1932+
*/
1933+
u32 qval = rd32(hw, I40E_QINT_RQCTL(0)) |
1934+
I40E_QINT_RQCTL_CAUSE_ENA_MASK;
1935+
1936+
wr32(hw, I40E_QINT_RQCTL(0), qval);
1937+
qval = rd32(hw, I40E_QINT_TQCTL(0)) |
1938+
I40E_QINT_TQCTL_CAUSE_ENA_MASK;
1939+
wr32(hw, I40E_QINT_TQCTL(0), qval);
1940+
i40e_irq_dynamic_enable_icr0(vsi->back);
19101941
}
1911-
19121942
return 0;
19131943
}
19141944

drivers/net/ethernet/intel/i40evf/i40e_txrx.c

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
404404
* 20-1249MB/s bulk (8000 ints/s)
405405
*/
406406
bytes_per_int = rc->total_bytes / rc->itr;
407-
switch (rc->itr) {
407+
switch (new_latency_range) {
408408
case I40E_LOWEST_LATENCY:
409409
if (bytes_per_int > 10)
410410
new_latency_range = I40E_LOW_LATENCY;
@@ -417,9 +417,14 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
417417
break;
418418
case I40E_BULK_LATENCY:
419419
if (bytes_per_int <= 20)
420-
rc->latency_range = I40E_LOW_LATENCY;
420+
new_latency_range = I40E_LOW_LATENCY;
421+
break;
422+
default:
423+
if (bytes_per_int <= 20)
424+
new_latency_range = I40E_LOW_LATENCY;
421425
break;
422426
}
427+
rc->latency_range = new_latency_range;
423428

424429
switch (new_latency_range) {
425430
case I40E_LOWEST_LATENCY:
@@ -435,42 +440,14 @@ static void i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
435440
break;
436441
}
437442

438-
if (new_itr != rc->itr) {
439-
/* do an exponential smoothing */
440-
new_itr = (10 * new_itr * rc->itr) /
441-
((9 * new_itr) + rc->itr);
442-
rc->itr = new_itr & I40E_MAX_ITR;
443-
}
443+
if (new_itr != rc->itr)
444+
rc->itr = new_itr;
444445

445446
rc->total_bytes = 0;
446447
rc->total_packets = 0;
447448
}
448449

449-
/**
450-
* i40e_update_dynamic_itr - Adjust ITR based on bytes per int
451-
* @q_vector: the vector to adjust
452-
**/
453-
static void i40e_update_dynamic_itr(struct i40e_q_vector *q_vector)
454-
{
455-
u16 vector = q_vector->vsi->base_vector + q_vector->v_idx;
456-
struct i40e_hw *hw = &q_vector->vsi->back->hw;
457-
u32 reg_addr;
458-
u16 old_itr;
459-
460-
reg_addr = I40E_VFINT_ITRN1(I40E_RX_ITR, vector - 1);
461-
old_itr = q_vector->rx.itr;
462-
i40e_set_new_dynamic_itr(&q_vector->rx);
463-
if (old_itr != q_vector->rx.itr)
464-
wr32(hw, reg_addr, q_vector->rx.itr);
465-
466-
reg_addr = I40E_VFINT_ITRN1(I40E_TX_ITR, vector - 1);
467-
old_itr = q_vector->tx.itr;
468-
i40e_set_new_dynamic_itr(&q_vector->tx);
469-
if (old_itr != q_vector->tx.itr)
470-
wr32(hw, reg_addr, q_vector->tx.itr);
471-
}
472-
473-
/**
450+
/*
474451
* i40evf_setup_tx_descriptors - Allocate the Tx descriptors
475452
* @tx_ring: the tx ring to set up
476453
*
@@ -1280,6 +1257,68 @@ static int i40e_clean_rx_irq_1buf(struct i40e_ring *rx_ring, int budget)
12801257
return total_rx_packets;
12811258
}
12821259

1260+
/**
1261+
* i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
1262+
* @vsi: the VSI we care about
1263+
* @q_vector: q_vector for which itr is being updated and interrupt enabled
1264+
*
1265+
**/
1266+
static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
1267+
struct i40e_q_vector *q_vector)
1268+
{
1269+
struct i40e_hw *hw = &vsi->back->hw;
1270+
u16 old_itr;
1271+
int vector;
1272+
u32 val;
1273+
1274+
vector = (q_vector->v_idx + vsi->base_vector);
1275+
if (ITR_IS_DYNAMIC(vsi->rx_itr_setting)) {
1276+
old_itr = q_vector->rx.itr;
1277+
i40e_set_new_dynamic_itr(&q_vector->rx);
1278+
if (old_itr != q_vector->rx.itr) {
1279+
val = I40E_VFINT_DYN_CTLN_INTENA_MASK |
1280+
I40E_VFINT_DYN_CTLN_CLEARPBA_MASK |
1281+
(I40E_RX_ITR <<
1282+
I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT) |
1283+
(q_vector->rx.itr <<
1284+
I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT);
1285+
} else {
1286+
val = I40E_VFINT_DYN_CTLN_INTENA_MASK |
1287+
I40E_VFINT_DYN_CTLN_CLEARPBA_MASK |
1288+
(I40E_ITR_NONE <<
1289+
I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT);
1290+
}
1291+
if (!test_bit(__I40E_DOWN, &vsi->state))
1292+
wr32(hw, I40E_VFINT_DYN_CTLN1(vector - 1), val);
1293+
} else {
1294+
i40evf_irq_enable_queues(vsi->back, 1
1295+
<< q_vector->v_idx);
1296+
}
1297+
if (ITR_IS_DYNAMIC(vsi->tx_itr_setting)) {
1298+
old_itr = q_vector->tx.itr;
1299+
i40e_set_new_dynamic_itr(&q_vector->tx);
1300+
if (old_itr != q_vector->tx.itr) {
1301+
val = I40E_VFINT_DYN_CTLN_INTENA_MASK |
1302+
I40E_VFINT_DYN_CTLN_CLEARPBA_MASK |
1303+
(I40E_TX_ITR <<
1304+
I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT) |
1305+
(q_vector->tx.itr <<
1306+
I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT);
1307+
1308+
} else {
1309+
val = I40E_VFINT_DYN_CTLN_INTENA_MASK |
1310+
I40E_VFINT_DYN_CTLN_CLEARPBA_MASK |
1311+
(I40E_ITR_NONE <<
1312+
I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT);
1313+
}
1314+
if (!test_bit(__I40E_DOWN, &vsi->state))
1315+
wr32(hw, I40E_VFINT_DYN_CTLN1(vector - 1), val);
1316+
} else {
1317+
i40evf_irq_enable_queues(vsi->back,
1318+
1 << q_vector->v_idx);
1319+
}
1320+
}
1321+
12831322
/**
12841323
* i40evf_napi_poll - NAPI polling Rx/Tx cleanup routine
12851324
* @napi: napi struct with our devices info in it
@@ -1336,13 +1375,7 @@ int i40evf_napi_poll(struct napi_struct *napi, int budget)
13361375

13371376
/* Work is done so exit the polling mode and re-enable the interrupt */
13381377
napi_complete(napi);
1339-
if (ITR_IS_DYNAMIC(vsi->rx_itr_setting) ||
1340-
ITR_IS_DYNAMIC(vsi->tx_itr_setting))
1341-
i40e_update_dynamic_itr(q_vector);
1342-
1343-
if (!test_bit(__I40E_DOWN, &vsi->state))
1344-
i40evf_irq_enable_queues(vsi->back, 1 << q_vector->v_idx);
1345-
1378+
i40e_update_enable_itr(vsi, q_vector);
13461379
return 0;
13471380
}
13481381

0 commit comments

Comments
 (0)