Skip to content

Commit c2d548c

Browse files
jahay1anguy11
authored andcommitted
idpf: add TX splitq napi poll support
Add support to handle the interrupts for the TX completion queue and process the various completion types. In the flow scheduling mode, the driver processes primarily buffer completions as well as descriptor completions occasionally. This mode supports out of order TX completions. To do so, HW generates one buffer completion per packet. Each of those completions contains the unique tag provided during the TX encoding which is used to locate the packet either on the TX buffer ring or in a hash table. The hash table is used to track TX buffer information so the descriptor(s) for a given packet can be reused while the driver is still waiting on the buffer completion(s). Packets end up in the hash table in one of 2 ways: 1) a packet was stashed during descriptor completion cleaning, or 2) because an out of order buffer completion was processed. A descriptor completion arrives only every so often and is primarily used to guarantee the TX descriptor ring can be reused without having to wait on the individual buffer completions. E.g. a descriptor completion for N+16 guarantees HW read all of the descriptors for packets N through N+15, therefore all of the buffers for packets N through N+15 are stashed into the hash table and the descriptors can be reused for more TX packets. Similarly, a packet can be stashed in the hash table because an out an order buffer completion was processed. E.g. processing a buffer completion for packet N+3 implies that HW read all of the descriptors for packets N through N+3 and they can be reused. However, the HW did not do the DMA yet. The buffers for packets N through N+2 cannot be freed, so they are stashed in the hash table. In either case, the buffer completions will eventually be processed for all of the stashed packets, and all of the buffers will be cleaned from the hash table. In queue based scheduling mode, the driver processes primarily descriptor completions and cleans the TX ring the conventional way. Finally, the driver triggers a TX queue drain after sending the disable queues virtchnl message. When the HW completes the queue draining, it sends the driver a queue marker packet completion. The driver determines when all TX queues have been drained and proceeds with the disable flow. With this, the driver can send TX packets and clean up the resources properly. Signed-off-by: Joshua Hay <[email protected]> Co-developed-by: Alan Brady <[email protected]> Signed-off-by: Alan Brady <[email protected]> Co-developed-by: Madhu Chittim <[email protected]> Signed-off-by: Madhu Chittim <[email protected]> Co-developed-by: Phani Burra <[email protected]> Signed-off-by: Phani Burra <[email protected]> Reviewed-by: Sridhar Samudrala <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Co-developed-by: Pavan Kumar Linga <[email protected]> Signed-off-by: Pavan Kumar Linga <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 6818c4d commit c2d548c

File tree

6 files changed

+926
-5
lines changed

6 files changed

+926
-5
lines changed

drivers/net/ethernet/intel/idpf/idpf.h

+22
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct idpf_vport_max_q;
1414
#include <linux/etherdevice.h>
1515
#include <linux/pci.h>
1616
#include <linux/bitfield.h>
17+
#include <linux/dim.h>
1718

1819
#include "virtchnl2.h"
1920
#include "idpf_lan_txrx.h"
@@ -41,6 +42,8 @@ struct idpf_vport_max_q;
4142
/* available message levels */
4243
#define IDPF_AVAIL_NETIF_M (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
4344

45+
#define IDPF_DIM_PROFILE_SLOTS 5
46+
4447
#define IDPF_VIRTCHNL_VERSION_MAJOR VIRTCHNL2_VERSION_MAJOR_2
4548
#define IDPF_VIRTCHNL_VERSION_MINOR VIRTCHNL2_VERSION_MINOR_0
4649

@@ -254,12 +257,24 @@ enum idpf_vport_vc_state {
254257

255258
extern const char * const idpf_vport_vc_state_str[];
256259

260+
/**
261+
* enum idpf_vport_flags - Vport flags
262+
* @IDPF_VPORT_SW_MARKER: Indicate TX pipe drain software marker packets
263+
* processing is done
264+
* @IDPF_VPORT_FLAGS_NBITS: Must be last
265+
*/
266+
enum idpf_vport_flags {
267+
IDPF_VPORT_SW_MARKER,
268+
IDPF_VPORT_FLAGS_NBITS,
269+
};
270+
257271
/**
258272
* struct idpf_vport - Handle for netdevices and queue resources
259273
* @num_txq: Number of allocated TX queues
260274
* @num_complq: Number of allocated completion queues
261275
* @txq_desc_count: TX queue descriptor count
262276
* @complq_desc_count: Completion queue descriptor count
277+
* @compln_clean_budget: Work budget for completion clean
263278
* @num_txq_grp: Number of TX queue groups
264279
* @txq_grps: Array of TX queue groups
265280
* @txq_model: Split queue or single queue queuing model
@@ -280,6 +295,7 @@ extern const char * const idpf_vport_vc_state_str[];
280295
* @adapter: back pointer to associated adapter
281296
* @netdev: Associated net_device. Each vport should have one and only one
282297
* associated netdev.
298+
* @flags: See enum idpf_vport_flags
283299
* @vport_type: Default SRIOV, SIOV, etc.
284300
* @vport_id: Device given vport identifier
285301
* @idx: Software index in adapter vports struct
@@ -290,17 +306,20 @@ extern const char * const idpf_vport_vc_state_str[];
290306
* @q_vector_idxs: Starting index of queue vectors
291307
* @max_mtu: device given max possible MTU
292308
* @default_mac_addr: device will give a default MAC to use
309+
* @tx_itr_profile: TX profiles for Dynamic Interrupt Moderation
293310
* @link_up: True if link is up
294311
* @vc_msg: Virtchnl message buffer
295312
* @vc_state: Virtchnl message state
296313
* @vchnl_wq: Wait queue for virtchnl messages
314+
* @sw_marker_wq: workqueue for marker packets
297315
* @vc_buf_lock: Lock to protect virtchnl buffer
298316
*/
299317
struct idpf_vport {
300318
u16 num_txq;
301319
u16 num_complq;
302320
u32 txq_desc_count;
303321
u32 complq_desc_count;
322+
u32 compln_clean_budget;
304323
u16 num_txq_grp;
305324
struct idpf_txq_group *txq_grps;
306325
u32 txq_model;
@@ -319,6 +338,7 @@ struct idpf_vport {
319338

320339
struct idpf_adapter *adapter;
321340
struct net_device *netdev;
341+
DECLARE_BITMAP(flags, IDPF_VPORT_FLAGS_NBITS);
322342
u16 vport_type;
323343
u32 vport_id;
324344
u16 idx;
@@ -330,13 +350,15 @@ struct idpf_vport {
330350
u16 *q_vector_idxs;
331351
u16 max_mtu;
332352
u8 default_mac_addr[ETH_ALEN];
353+
u16 tx_itr_profile[IDPF_DIM_PROFILE_SLOTS];
333354

334355
bool link_up;
335356

336357
char vc_msg[IDPF_CTLQ_MAX_BUF_LEN];
337358
DECLARE_BITMAP(vc_state, IDPF_VC_NBITS);
338359

339360
wait_queue_head_t vchnl_wq;
361+
wait_queue_head_t sw_marker_wq;
340362
struct mutex vc_buf_lock;
341363
};
342364

drivers/net/ethernet/intel/idpf/idpf_lan_txrx.h

+16
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ enum idpf_rss_hash {
5656
BIT_ULL(IDPF_HASH_NONF_UNICAST_IPV6_UDP) | \
5757
BIT_ULL(IDPF_HASH_NONF_MULTICAST_IPV6_UDP))
5858

59+
/* For idpf_splitq_base_tx_compl_desc */
60+
#define IDPF_TXD_COMPLQ_GEN_S 15
61+
#define IDPF_TXD_COMPLQ_GEN_M BIT_ULL(IDPF_TXD_COMPLQ_GEN_S)
62+
#define IDPF_TXD_COMPLQ_COMPL_TYPE_S 11
63+
#define IDPF_TXD_COMPLQ_COMPL_TYPE_M GENMASK_ULL(13, 11)
64+
#define IDPF_TXD_COMPLQ_QID_S 0
65+
#define IDPF_TXD_COMPLQ_QID_M GENMASK_ULL(9, 0)
66+
5967
#define IDPF_TXD_CTX_QW1_MSS_S 50
6068
#define IDPF_TXD_CTX_QW1_MSS_M GENMASK_ULL(63, 50)
6169
#define IDPF_TXD_CTX_QW1_TSO_LEN_S 30
@@ -75,6 +83,14 @@ enum idpf_rss_hash {
7583
#define IDPF_TXD_QW1_DTYPE_S 0
7684
#define IDPF_TXD_QW1_DTYPE_M GENMASK_ULL(3, 0)
7785

86+
/* TX Completion Descriptor Completion Types */
87+
#define IDPF_TXD_COMPLT_ITR_FLUSH 0
88+
/* Descriptor completion type 1 is reserved */
89+
#define IDPF_TXD_COMPLT_RS 2
90+
/* Descriptor completion type 3 is reserved */
91+
#define IDPF_TXD_COMPLT_RE 4
92+
#define IDPF_TXD_COMPLT_SW_MARKER 5
93+
7894
enum idpf_tx_desc_dtype_value {
7995
IDPF_TX_DESC_DTYPE_DATA = 0,
8096
IDPF_TX_DESC_DTYPE_CTX = 1,

drivers/net/ethernet/intel/idpf/idpf_lib.c

+2
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
929929

930930
vport->idx = idx;
931931
vport->adapter = adapter;
932+
vport->compln_clean_budget = IDPF_TX_COMPLQ_CLEAN_BUDGET;
932933
vport->default_vport = adapter->num_alloc_vports <
933934
idpf_get_default_vports(adapter);
934935

@@ -1241,6 +1242,7 @@ void idpf_init_task(struct work_struct *work)
12411242
index = vport->idx;
12421243
vport_config = adapter->vport_config[index];
12431244

1245+
init_waitqueue_head(&vport->sw_marker_wq);
12441246
init_waitqueue_head(&vport->vchnl_wq);
12451247

12461248
mutex_init(&vport->vc_buf_lock);

0 commit comments

Comments
 (0)