Commit 4ea83b75 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
idpf: add XDP support

Alexander Lobakin says:

Add XDP support (w/o XSk for now) to the idpf driver using the libeth_xdp
sublib. All possible verdicts, .ndo_xdp_xmit(), multi-buffer etc. are here.
In general, nothing outstanding comparing to ice, except performance --
let's say, up to 2x for .ndo_xdp_xmit() on certain platforms and
scenarios.
idpf doesn't support VLAN Rx offload, so only the hash hint is
available for now.

Patches 1-7 are prereqs, without which XDP would either not work at all
or work slower/worse/...

* '200GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  idpf: add XDP RSS hash hint
  idpf: add support for .ndo_xdp_xmit()
  idpf: add support for XDP on Rx
  idpf: use generic functions to build xdp_buff and skb
  idpf: implement XDP_SETUP_PROG in ndo_bpf for splitq
  idpf: prepare structures to support XDP
  idpf: add support for nointerrupt queues
  idpf: remove SW marker handling from NAPI
  idpf: add 4-byte completion descriptor definition
  idpf: link NAPIs to queues
  idpf: use a saner limit for default number of queues to allocate
  idpf: fix Rx descriptor ready check barrier in splitq
  xdp, libeth: make the xdp_init_buff() micro-optimization generic
====================

Link: https://patch.msgid.link/20250908195748.1707057-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents ce6adea1 88ca0c73
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ config IDPF
	depends on PCI_MSI
	depends on PTP_1588_CLOCK_OPTIONAL
	select DIMLIB
	select LIBETH
	select LIBETH_XDP
	help
	  This driver supports Intel(R) Infrastructure Data Path Function
	  devices.
+2 −0
Original line number Diff line number Diff line
@@ -21,3 +21,5 @@ idpf-$(CONFIG_IDPF_SINGLEQ) += idpf_singleq_txrx.o

idpf-$(CONFIG_PTP_1588_CLOCK)	+= idpf_ptp.o
idpf-$(CONFIG_PTP_1588_CLOCK)	+= idpf_virtchnl_ptp.o

idpf-y				+= xdp.o
+25 −6
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct idpf_vport_max_q;
#define IDPF_NUM_CHUNKS_PER_MSG(struct_sz, chunk_sz)	\
	((IDPF_CTLQ_MAX_BUF_LEN - (struct_sz)) / (chunk_sz))

#define IDPF_WAIT_FOR_MARKER_TIMEO	500
#define IDPF_MAX_WAIT			500

/* available message levels */
@@ -248,13 +249,10 @@ enum idpf_vport_reset_cause {
/**
 * enum idpf_vport_flags - Vport flags
 * @IDPF_VPORT_DEL_QUEUES: To send delete queues message
 * @IDPF_VPORT_SW_MARKER: Indicate TX pipe drain software marker packets
 *			  processing is done
 * @IDPF_VPORT_FLAGS_NBITS: Must be last
 */
enum idpf_vport_flags {
	IDPF_VPORT_DEL_QUEUES,
	IDPF_VPORT_SW_MARKER,
	IDPF_VPORT_FLAGS_NBITS,
};

@@ -289,6 +287,10 @@ struct idpf_fsteer_fltr {
 * @txq_model: Split queue or single queue queuing model
 * @txqs: Used only in hotpath to get to the right queue very fast
 * @crc_enable: Enable CRC insertion offload
 * @xdpsq_share: whether XDPSQ sharing is enabled
 * @num_xdp_txq: number of XDPSQs
 * @xdp_txq_offset: index of the first XDPSQ (== number of regular SQs)
 * @xdp_prog: installed XDP program
 * @num_rxq: Number of allocated RX queues
 * @num_bufq: Number of allocated buffer queues
 * @rxq_desc_count: RX queue descriptor count. *MUST* have enough descriptors
@@ -314,13 +316,15 @@ struct idpf_fsteer_fltr {
 * @num_q_vectors: Number of IRQ vectors allocated
 * @q_vectors: Array of queue vectors
 * @q_vector_idxs: Starting index of queue vectors
 * @noirq_dyn_ctl: register to enable/disable the vector for NOIRQ queues
 * @noirq_dyn_ctl_ena: value to write to the above to enable it
 * @noirq_v_idx: ID of the NOIRQ vector
 * @max_mtu: device given max possible MTU
 * @default_mac_addr: device will give a default MAC to use
 * @rx_itr_profile: RX profiles for Dynamic Interrupt Moderation
 * @tx_itr_profile: TX profiles for Dynamic Interrupt Moderation
 * @port_stats: per port csum, header split, and other offload stats
 * @link_up: True if link is up
 * @sw_marker_wq: workqueue for marker packets
 * @tx_tstamp_caps: Capabilities negotiated for Tx timestamping
 * @tstamp_config: The Tx tstamp config
 * @tstamp_task: Tx timestamping task
@@ -337,6 +341,11 @@ struct idpf_vport {
	struct idpf_tx_queue **txqs;
	bool crc_enable;

	bool xdpsq_share;
	u16 num_xdp_txq;
	u16 xdp_txq_offset;
	struct bpf_prog *xdp_prog;

	u16 num_rxq;
	u16 num_bufq;
	u32 rxq_desc_count;
@@ -361,6 +370,11 @@ struct idpf_vport {
	u16 num_q_vectors;
	struct idpf_q_vector *q_vectors;
	u16 *q_vector_idxs;

	void __iomem *noirq_dyn_ctl;
	u32 noirq_dyn_ctl_ena;
	u16 noirq_v_idx;

	u16 max_mtu;
	u8 default_mac_addr[ETH_ALEN];
	u16 rx_itr_profile[IDPF_DIM_PROFILE_SLOTS];
@@ -369,8 +383,6 @@ struct idpf_vport {

	bool link_up;

	wait_queue_head_t sw_marker_wq;

	struct idpf_ptp_vport_tx_tstamp_caps *tx_tstamp_caps;
	struct kernel_hwtstamp_config tstamp_config;
	struct work_struct tstamp_task;
@@ -435,6 +447,7 @@ struct idpf_q_coalesce {
 *		      ethtool
 * @num_req_rxq_desc: Number of user requested RX queue descriptors through
 *		      ethtool
 * @xdp_prog: requested XDP program to install
 * @user_flags: User toggled config flags
 * @mac_filter_list: List of MAC filters
 * @num_fsteer_fltrs: number of flow steering filters
@@ -449,6 +462,7 @@ struct idpf_vport_user_config_data {
	u16 num_req_rx_qs;
	u32 num_req_txq_desc;
	u32 num_req_rxq_desc;
	struct bpf_prog *xdp_prog;
	DECLARE_BITMAP(user_flags, __IDPF_USER_FLAGS_NBITS);
	struct list_head mac_filter_list;
	u32 num_fsteer_fltrs;
@@ -678,6 +692,11 @@ static inline int idpf_is_queue_model_split(u16 q_model)
	       q_model == VIRTCHNL2_QUEUE_MODEL_SPLIT;
}

static inline bool idpf_xdp_enabled(const struct idpf_vport *vport)
{
	return vport->adapter && vport->xdp_prog;
}

#define idpf_is_cap_ena(adapter, field, flag) \
	idpf_is_capability_ena(adapter, false, field, flag)
#define idpf_is_cap_ena_all(adapter, field, flag) \
+10 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static int idpf_intr_reg_init(struct idpf_vport *vport)
	int num_vecs = vport->num_q_vectors;
	struct idpf_vec_regs *reg_vals;
	int num_regs, i, err = 0;
	u32 rx_itr, tx_itr;
	u32 rx_itr, tx_itr, val;
	u16 total_vecs;

	total_vecs = idpf_get_reserved_vecs(vport->adapter);
@@ -121,6 +121,15 @@ static int idpf_intr_reg_init(struct idpf_vport *vport)
		intr->tx_itr = idpf_get_reg_addr(adapter, tx_itr);
	}

	/* Data vector for NOIRQ queues */

	val = reg_vals[vport->q_vector_idxs[i] - IDPF_MBX_Q_VEC].dyn_ctl_reg;
	vport->noirq_dyn_ctl = idpf_get_reg_addr(adapter, val);

	val = PF_GLINT_DYN_CTL_WB_ON_ITR_M | PF_GLINT_DYN_CTL_INTENA_MSK_M |
	      FIELD_PREP(PF_GLINT_DYN_CTL_ITR_INDX_M, IDPF_NO_ITR_UPDATE_IDX);
	vport->noirq_dyn_ctl_ena = val;

free_reg_vals:
	kfree(reg_vals);

+5 −1
Original line number Diff line number Diff line
@@ -186,13 +186,17 @@ struct idpf_base_tx_desc {
	__le64 qw1; /* type_cmd_offset_bsz_l2tag1 */
}; /* read used with buffer queues */

struct idpf_splitq_tx_compl_desc {
struct idpf_splitq_4b_tx_compl_desc {
	/* qid=[10:0] comptype=[13:11] rsvd=[14] gen=[15] */
	__le16 qid_comptype_gen;
	union {
		__le16 q_head; /* Queue head */
		__le16 compl_tag; /* Completion tag */
	} q_head_compl_tag;
}; /* writeback used with completion queues */

struct idpf_splitq_tx_compl_desc {
	struct idpf_splitq_4b_tx_compl_desc common;
	u8 ts[3];
	u8 rsvd; /* Reserved */
}; /* writeback used with completion queues */
Loading