Skip to content

Commit 65e87c0

Browse files
jacob-kellerJeff Kirsher
authored andcommitted
i40evf: support queue-specific settings for interrupt moderation
In commit a75e800 ("i40e: queue-specific settings for interrupt moderation") the i40e driver gained support for setting interrupt moderation values per queue. This patch adds support for this feature to the i40evf driver as well. In addition, a few changes are made to the i40e implementation to add function header documentation comments, as well. This behaves in a similar fashion to the implementation in i40e. Thus, requesting the moderation value when no queue is provided will report queue 0 value, while setting the value without a queue will set all queues at once. Change-ID: I1f310a57c8e6c84a8524c178d44d1b7a6d3a848e Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
1 parent a4fa59c commit 65e87c0

File tree

7 files changed

+280
-70
lines changed

7 files changed

+280
-70
lines changed

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

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,11 +1970,22 @@ static int i40e_set_phys_id(struct net_device *netdev,
19701970
* 125us (8000 interrupts per second) == ITR(62)
19711971
*/
19721972

1973+
/**
1974+
* __i40e_get_coalesce - get per-queue coalesce settings
1975+
* @netdev: the netdev to check
1976+
* @ec: ethtool coalesce data structure
1977+
* @queue: which queue to pick
1978+
*
1979+
* Gets the per-queue settings for coalescence. Specifically Rx and Tx usecs
1980+
* are per queue. If queue is <0 then we default to queue 0 as the
1981+
* representative value.
1982+
**/
19731983
static int __i40e_get_coalesce(struct net_device *netdev,
19741984
struct ethtool_coalesce *ec,
19751985
int queue)
19761986
{
19771987
struct i40e_netdev_priv *np = netdev_priv(netdev);
1988+
struct i40e_ring *rx_ring, *tx_ring;
19781989
struct i40e_vsi *vsi = np->vsi;
19791990

19801991
ec->tx_max_coalesced_frames_irq = vsi->work_limit;
@@ -1989,14 +2000,18 @@ static int __i40e_get_coalesce(struct net_device *netdev,
19892000
return -EINVAL;
19902001
}
19912002

1992-
if (ITR_IS_DYNAMIC(vsi->rx_rings[queue]->rx_itr_setting))
2003+
rx_ring = vsi->rx_rings[queue];
2004+
tx_ring = vsi->tx_rings[queue];
2005+
2006+
if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))
19932007
ec->use_adaptive_rx_coalesce = 1;
19942008

1995-
if (ITR_IS_DYNAMIC(vsi->tx_rings[queue]->tx_itr_setting))
2009+
if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))
19962010
ec->use_adaptive_tx_coalesce = 1;
19972011

1998-
ec->rx_coalesce_usecs = vsi->rx_rings[queue]->rx_itr_setting & ~I40E_ITR_DYNAMIC;
1999-
ec->tx_coalesce_usecs = vsi->tx_rings[queue]->tx_itr_setting & ~I40E_ITR_DYNAMIC;
2012+
ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;
2013+
ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;
2014+
20002015

20012016
/* we use the _usecs_high to store/set the interrupt rate limit
20022017
* that the hardware supports, that almost but not quite
@@ -2010,18 +2025,44 @@ static int __i40e_get_coalesce(struct net_device *netdev,
20102025
return 0;
20112026
}
20122027

2028+
/**
2029+
* i40e_get_coalesce - get a netdev's coalesce settings
2030+
* @netdev: the netdev to check
2031+
* @ec: ethtool coalesce data structure
2032+
*
2033+
* Gets the coalesce settings for a particular netdev. Note that if user has
2034+
* modified per-queue settings, this only guarantees to represent queue 0. See
2035+
* __i40e_get_coalesce for more details.
2036+
**/
20132037
static int i40e_get_coalesce(struct net_device *netdev,
20142038
struct ethtool_coalesce *ec)
20152039
{
20162040
return __i40e_get_coalesce(netdev, ec, -1);
20172041
}
20182042

2043+
/**
2044+
* i40e_get_per_queue_coalesce - gets coalesce settings for particular queue
2045+
* @netdev: netdev structure
2046+
* @ec: ethtool's coalesce settings
2047+
* @queue: the particular queue to read
2048+
*
2049+
* Will read a specific queue's coalesce settings
2050+
**/
20192051
static int i40e_get_per_queue_coalesce(struct net_device *netdev, u32 queue,
20202052
struct ethtool_coalesce *ec)
20212053
{
20222054
return __i40e_get_coalesce(netdev, ec, queue);
20232055
}
20242056

2057+
/**
2058+
* i40e_set_itr_per_queue - set ITR values for specific queue
2059+
* @vsi: the VSI to set values for
2060+
* @ec: coalesce settings from ethtool
2061+
* @queue: the queue to modify
2062+
*
2063+
* Change the ITR settings for a specific queue.
2064+
**/
2065+
20252066
static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,
20262067
struct ethtool_coalesce *ec,
20272068
int queue)
@@ -2060,6 +2101,14 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi,
20602101
i40e_flush(hw);
20612102
}
20622103

2104+
/**
2105+
* __i40e_set_coalesce - set coalesce settings for particular queue
2106+
* @netdev: the netdev to change
2107+
* @ec: ethtool coalesce settings
2108+
* @queue: the queue to change
2109+
*
2110+
* Sets the coalesce settings for a particular queue.
2111+
**/
20632112
static int __i40e_set_coalesce(struct net_device *netdev,
20642113
struct ethtool_coalesce *ec,
20652114
int queue)
@@ -2120,12 +2169,27 @@ static int __i40e_set_coalesce(struct net_device *netdev,
21202169
return 0;
21212170
}
21222171

2172+
/**
2173+
* i40e_set_coalesce - set coalesce settings for every queue on the netdev
2174+
* @netdev: the netdev to change
2175+
* @ec: ethtool coalesce settings
2176+
*
2177+
* This will set each queue to the same coalesce settings.
2178+
**/
21232179
static int i40e_set_coalesce(struct net_device *netdev,
21242180
struct ethtool_coalesce *ec)
21252181
{
21262182
return __i40e_set_coalesce(netdev, ec, -1);
21272183
}
21282184

2185+
/**
2186+
* i40e_set_per_queue_coalesce - set specific queue's coalesce settings
2187+
* @netdev: the netdev to change
2188+
* @ec: ethtool's coalesce settings
2189+
* @queue: the queue to change
2190+
*
2191+
* Sets the specified queue's coalesce settings.
2192+
**/
21292193
static int i40e_set_per_queue_coalesce(struct net_device *netdev, u32 queue,
21302194
struct ethtool_coalesce *ec)
21312195
{

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,15 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)
18771877

18781878
/* a small macro to shorten up some long lines */
18791879
#define INTREG I40E_PFINT_DYN_CTLN
1880+
static inline int get_rx_itr_enabled(struct i40e_vsi *vsi, int idx)
1881+
{
1882+
return !!(vsi->rx_rings[idx]->rx_itr_setting);
1883+
}
1884+
1885+
static inline int get_tx_itr_enabled(struct i40e_vsi *vsi, int idx)
1886+
{
1887+
return !!(vsi->tx_rings[idx]->tx_itr_setting);
1888+
}
18801889

18811890
/**
18821891
* i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -1892,6 +1901,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
18921901
u32 rxval, txval;
18931902
int vector;
18941903
int idx = q_vector->v_idx;
1904+
int rx_itr_setting, tx_itr_setting;
18951905

18961906
vector = (q_vector->v_idx + vsi->base_vector);
18971907

@@ -1900,18 +1910,21 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
19001910
*/
19011911
rxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
19021912

1913+
rx_itr_setting = get_rx_itr_enabled(vsi, idx);
1914+
tx_itr_setting = get_tx_itr_enabled(vsi, idx);
1915+
19031916
if (q_vector->itr_countdown > 0 ||
1904-
(!ITR_IS_DYNAMIC(vsi->rx_rings[idx]->rx_itr_setting) &&
1905-
!ITR_IS_DYNAMIC(vsi->tx_rings[idx]->tx_itr_setting))) {
1917+
(!ITR_IS_DYNAMIC(rx_itr_setting) &&
1918+
!ITR_IS_DYNAMIC(tx_itr_setting))) {
19061919
goto enable_int;
19071920
}
19081921

1909-
if (ITR_IS_DYNAMIC(vsi->rx_rings[idx]->rx_itr_setting)) {
1922+
if (ITR_IS_DYNAMIC(tx_itr_setting)) {
19101923
rx = i40e_set_new_dynamic_itr(&q_vector->rx);
19111924
rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
19121925
}
19131926

1914-
if (ITR_IS_DYNAMIC(vsi->tx_rings[idx]->tx_itr_setting)) {
1927+
if (ITR_IS_DYNAMIC(tx_itr_setting)) {
19151928
tx = i40e_set_new_dynamic_itr(&q_vector->tx);
19161929
txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
19171930
}

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,19 @@ static u32 i40e_buildreg_itr(const int type, const u16 itr)
13111311

13121312
/* a small macro to shorten up some long lines */
13131313
#define INTREG I40E_VFINT_DYN_CTLN1
1314+
static inline int get_rx_itr_enabled(struct i40e_vsi *vsi, int idx)
1315+
{
1316+
struct i40evf_adapter *adapter = vsi->back;
1317+
1318+
return !!(adapter->rx_rings[idx].rx_itr_setting);
1319+
}
1320+
1321+
static inline int get_tx_itr_enabled(struct i40e_vsi *vsi, int idx)
1322+
{
1323+
struct i40evf_adapter *adapter = vsi->back;
1324+
1325+
return !!(adapter->tx_rings[idx].tx_itr_setting);
1326+
}
13141327

13151328
/**
13161329
* i40e_update_enable_itr - Update itr and re-enable MSIX interrupt
@@ -1325,6 +1338,8 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
13251338
bool rx = false, tx = false;
13261339
u32 rxval, txval;
13271340
int vector;
1341+
int idx = q_vector->v_idx;
1342+
int rx_itr_setting, tx_itr_setting;
13281343

13291344
vector = (q_vector->v_idx + vsi->base_vector);
13301345

@@ -1333,18 +1348,21 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
13331348
*/
13341349
rxval = txval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
13351350

1351+
rx_itr_setting = get_rx_itr_enabled(vsi, idx);
1352+
tx_itr_setting = get_tx_itr_enabled(vsi, idx);
1353+
13361354
if (q_vector->itr_countdown > 0 ||
1337-
(!ITR_IS_DYNAMIC(vsi->rx_itr_setting) &&
1338-
!ITR_IS_DYNAMIC(vsi->tx_itr_setting))) {
1355+
(!ITR_IS_DYNAMIC(rx_itr_setting) &&
1356+
!ITR_IS_DYNAMIC(tx_itr_setting))) {
13391357
goto enable_int;
13401358
}
13411359

1342-
if (ITR_IS_DYNAMIC(vsi->rx_itr_setting)) {
1360+
if (ITR_IS_DYNAMIC(rx_itr_setting)) {
13431361
rx = i40e_set_new_dynamic_itr(&q_vector->rx);
13441362
rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
13451363
}
13461364

1347-
if (ITR_IS_DYNAMIC(vsi->tx_itr_setting)) {
1365+
if (ITR_IS_DYNAMIC(tx_itr_setting)) {
13481366
tx = i40e_set_new_dynamic_itr(&q_vector->tx);
13491367
txval = i40e_buildreg_itr(I40E_TX_ITR, q_vector->tx.itr);
13501368
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,14 @@ struct i40e_ring {
287287
u8 dcb_tc; /* Traffic class of ring */
288288
u8 __iomem *tail;
289289

290+
/* high bit set means dynamic, use accessors routines to read/write.
291+
* hardware only supports 2us resolution for the ITR registers.
292+
* these values always store the USER setting, and must be converted
293+
* before programming to a register.
294+
*/
295+
u16 rx_itr_setting;
296+
u16 tx_itr_setting;
297+
290298
u16 count; /* Number of descriptors */
291299
u16 reg_idx; /* HW register index of the ring */
292300
u16 rx_buf_len;

drivers/net/ethernet/intel/i40evf/i40evf.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,6 @@ struct i40e_vsi {
5959
unsigned long state;
6060
int base_vector;
6161
u16 work_limit;
62-
/* high bit set means dynamic, use accessor routines to read/write.
63-
* hardware only supports 2us resolution for the ITR registers.
64-
* these values always store the USER setting, and must be converted
65-
* before programming to a register.
66-
*/
67-
u16 rx_itr_setting;
68-
u16 tx_itr_setting;
6962
u16 qs_handle;
7063
};
7164

0 commit comments

Comments
 (0)