From nobody Wed Oct 8 22:34:49 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80FEC2EA49D; Tue, 24 Jun 2025 16:46:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750783574; cv=none; b=Rf1UFMCnSgMnKtFMV2kh84THy6e65XgEMXtsrMfpazMspkIX+lDgf1a4fWCD7culoNssPT8Wdtq0Y3/ipy9bDXS2u6ogz27z8AwAoIuaYRPjlBzHwukp89dvI6ghg4YFFRdDc90wY4P5EOmlam6jlwma3kiz20hQNIFFt1Fz43A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750783574; c=relaxed/simple; bh=3wvWgR3cBdJ90pqeQ5NUDZUlGDQSWEvAPlYVnDTIqD0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cmR4NjKSw+VYpFX4G7D4lKI4STX4KkZ6NmSlSU+SoeTD+0dHlAjdHyplVtET3sa0x3wI20/RzHojuQM+r9H3jl94kBGzEM/izEDzektgF2JFDBb4j0PVFUD/oeWkJIAxrK+yZKSljWkCAJUljzcw0QqCpqXu4LcJ+lLXZKpWZvY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ZywqGhf7; arc=none smtp.client-ip=198.175.65.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ZywqGhf7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1750783572; x=1782319572; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3wvWgR3cBdJ90pqeQ5NUDZUlGDQSWEvAPlYVnDTIqD0=; b=ZywqGhf7kg+awA4twDWhAyq6AaDH/BUyojgt8CmhyWZND5Y44kiLOoNo hOqF2pOOnRRcoxqV2UFQ9sNqRiKdH5nwnwSHb3czeb7Hg6yB+ACr2B5OI LtJ7AbZh4pEapnMIL/Uzkfx0HsnmO23PMTOJOq9xOgiWFBIoyjhj1bH/R fd7gf4yNDIDE1GyQKrtT0BbaH6qPrpo+tvkNaydC+yWlRSzIx0e/0nS7g 87ovUErz8u7fjU8zjblie2LPC4uA4zyjh0QnTGIZvHvaIoDsG8G5L8+LW lyEOnPxQMLROFp7OOFev8IVC3k5H8QlNKmpIPOXGDlt3pQ+PDtZhXnMjz g==; X-CSE-ConnectionGUID: aBy1zWa8TmWWj0vvpjM0CA== X-CSE-MsgGUID: q6CRcKV0QG+9sSw2u90uog== X-IronPort-AV: E=McAfee;i="6800,10657,11474"; a="64091268" X-IronPort-AV: E=Sophos;i="6.16,262,1744095600"; d="scan'208";a="64091268" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by orvoesa105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Jun 2025 09:46:12 -0700 X-CSE-ConnectionGUID: f5fyvQciQ8uHx21LkRFCOw== X-CSE-MsgGUID: qXasHY9OQQ2n732zSg1JEQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,262,1744095600"; d="scan'208";a="152669484" Received: from newjersey.igk.intel.com ([10.102.20.203]) by fmviesa010.fm.intel.com with ESMTP; 24 Jun 2025 09:46:08 -0700 From: Alexander Lobakin To: intel-wired-lan@lists.osuosl.org Cc: Alexander Lobakin , Michal Kubiak , Maciej Fijalkowski , Tony Nguyen , Przemek Kitszel , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Alexei Starovoitov , Daniel Borkmann , Simon Horman , nxne.cnse.osdt.itp.upstreaming@intel.com, bpf@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH iwl-next v2 08/12] idpf: implement XDP_SETUP_PROG in ndo_bpf for splitq Date: Tue, 24 Jun 2025 18:45:11 +0200 Message-ID: <20250624164515.2663137-9-aleksander.lobakin@intel.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250624164515.2663137-1-aleksander.lobakin@intel.com> References: <20250624164515.2663137-1-aleksander.lobakin@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Michal Kubiak Implement loading/removing XDP program using .ndo_bpf callback in the split queue mode. Reconfigure and restart the queues if needed (!!old_prog !=3D !!new_prog), otherwise, just update the pointers. Signed-off-by: Michal Kubiak Signed-off-by: Alexander Lobakin --- drivers/net/ethernet/intel/idpf/idpf_txrx.h | 4 +- drivers/net/ethernet/intel/idpf/xdp.h | 7 ++ drivers/net/ethernet/intel/idpf/idpf_lib.c | 1 + drivers/net/ethernet/intel/idpf/idpf_txrx.c | 4 + drivers/net/ethernet/intel/idpf/xdp.c | 98 +++++++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethe= rnet/intel/idpf/idpf_txrx.h index 03215f386bf6..251f400c2389 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h @@ -490,6 +490,7 @@ struct idpf_txq_stash { * @desc_ring: virtual descriptor ring address * @bufq_sets: Pointer to the array of buffer queues in splitq mode * @napi: NAPI instance corresponding to this queue (splitq) + * @xdp_prog: attached XDP program * @rx_buf: See struct &libeth_fqe * @pp: Page pool pointer in singleq mode * @tail: Tail offset. Used for both queue models single and split. @@ -531,13 +532,14 @@ struct idpf_rx_queue { struct { struct idpf_bufq_set *bufq_sets; struct napi_struct *napi; + struct bpf_prog __rcu *xdp_prog; }; struct { struct libeth_fqe *rx_buf; struct page_pool *pp; + void __iomem *tail; }; }; - void __iomem *tail; =20 DECLARE_BITMAP(flags, __IDPF_Q_FLAGS_NBITS); u16 idx; diff --git a/drivers/net/ethernet/intel/idpf/xdp.h b/drivers/net/ethernet/i= ntel/idpf/xdp.h index cf6823b24ba5..47553ce5f81a 100644 --- a/drivers/net/ethernet/intel/idpf/xdp.h +++ b/drivers/net/ethernet/intel/idpf/xdp.h @@ -6,12 +6,19 @@ =20 #include =20 +struct bpf_prog; struct idpf_vport; +struct net_device; +struct netdev_bpf; =20 int idpf_xdp_rxq_info_init_all(const struct idpf_vport *vport); void idpf_xdp_rxq_info_deinit_all(const struct idpf_vport *vport); +void idpf_xdp_copy_prog_to_rqs(const struct idpf_vport *vport, + struct bpf_prog *xdp_prog); =20 int idpf_xdpsqs_get(const struct idpf_vport *vport); void idpf_xdpsqs_put(const struct idpf_vport *vport); =20 +int idpf_xdp(struct net_device *dev, struct netdev_bpf *xdp); + #endif /* _IDPF_XDP_H_ */ diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ether= net/intel/idpf/idpf_lib.c index e2631c710573..c2c7528fe85b 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c @@ -2418,4 +2418,5 @@ static const struct net_device_ops idpf_netdev_ops = =3D { .ndo_tx_timeout =3D idpf_tx_timeout, .ndo_hwtstamp_get =3D idpf_hwtstamp_get, .ndo_hwtstamp_set =3D idpf_hwtstamp_set, + .ndo_bpf =3D idpf_xdp, }; diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethe= rnet/intel/idpf/idpf_txrx.c index c176af58c0e2..ed1736e52b1c 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c @@ -1108,6 +1108,8 @@ static void idpf_vport_queue_grp_rel_all(struct idpf_= vport *vport) */ void idpf_vport_queues_rel(struct idpf_vport *vport) { + idpf_xdp_copy_prog_to_rqs(vport, NULL); + idpf_tx_desc_rel_all(vport); idpf_rx_desc_rel_all(vport); =20 @@ -1678,6 +1680,8 @@ int idpf_vport_queues_alloc(struct idpf_vport *vport) if (err) goto err_out; =20 + idpf_xdp_copy_prog_to_rqs(vport, vport->xdp_prog); + return 0; =20 err_out: diff --git a/drivers/net/ethernet/intel/idpf/xdp.c b/drivers/net/ethernet/i= ntel/idpf/xdp.c index 08d63462dca4..09e84fe80d4e 100644 --- a/drivers/net/ethernet/intel/idpf/xdp.c +++ b/drivers/net/ethernet/intel/idpf/xdp.c @@ -4,6 +4,7 @@ #include =20 #include "idpf.h" +#include "idpf_virtchnl.h" #include "xdp.h" =20 static int idpf_rxq_for_each(const struct idpf_vport *vport, @@ -91,6 +92,28 @@ void idpf_xdp_rxq_info_deinit_all(const struct idpf_vpor= t *vport) (void *)(size_t)vport->rxq_model); } =20 +static int idpf_xdp_rxq_assign_prog(struct idpf_rx_queue *rxq, void *arg) +{ + struct mutex *lock =3D &rxq->q_vector->vport->adapter->vport_ctrl_lock; + struct bpf_prog *prog =3D arg; + struct bpf_prog *old; + + if (prog) + bpf_prog_inc(prog); + + old =3D rcu_replace_pointer(rxq->xdp_prog, prog, lockdep_is_held(lock)); + if (old) + bpf_prog_put(old); + + return 0; +} + +void idpf_xdp_copy_prog_to_rqs(const struct idpf_vport *vport, + struct bpf_prog *xdp_prog) +{ + idpf_rxq_for_each(vport, idpf_xdp_rxq_assign_prog, xdp_prog); +} + int idpf_xdpsqs_get(const struct idpf_vport *vport) { struct libeth_xdpsq_timer **timers __free(kvfree) =3D NULL; @@ -163,3 +186,78 @@ void idpf_xdpsqs_put(const struct idpf_vport *vport) idpf_queue_clear(NOIRQ, xdpsq); } } + +static int idpf_xdp_setup_prog(struct idpf_vport *vport, + const struct netdev_bpf *xdp) +{ + const struct idpf_netdev_priv *np =3D netdev_priv(vport->netdev); + struct bpf_prog *old, *prog =3D xdp->prog; + struct idpf_vport_config *cfg; + int ret; + + cfg =3D vport->adapter->vport_config[vport->idx]; + + if (test_bit(IDPF_REMOVE_IN_PROG, vport->adapter->flags) || + !test_bit(IDPF_VPORT_REG_NETDEV, cfg->flags) || + !!vport->xdp_prog =3D=3D !!prog) { + if (np->state =3D=3D __IDPF_VPORT_UP) + idpf_xdp_copy_prog_to_rqs(vport, prog); + + old =3D xchg(&vport->xdp_prog, prog); + if (old) + bpf_prog_put(old); + + cfg->user_config.xdp_prog =3D prog; + + return 0; + } + + if (!vport->num_xdp_txq && vport->num_txq =3D=3D cfg->max_q.max_txq) { + NL_SET_ERR_MSG_MOD(xdp->extack, + "No Tx queues available for XDP, please decrease the number of regu= lar SQs"); + return -ENOSPC; + } + + old =3D cfg->user_config.xdp_prog; + cfg->user_config.xdp_prog =3D prog; + + ret =3D idpf_initiate_soft_reset(vport, IDPF_SR_Q_CHANGE); + if (ret) { + NL_SET_ERR_MSG_MOD(xdp->extack, + "Could not reopen the vport after XDP setup"); + + cfg->user_config.xdp_prog =3D old; + old =3D prog; + } + + if (old) + bpf_prog_put(old); + + return ret; +} + +int idpf_xdp(struct net_device *dev, struct netdev_bpf *xdp) +{ + struct idpf_vport *vport; + int ret; + + idpf_vport_ctrl_lock(dev); + vport =3D idpf_netdev_to_vport(dev); + + if (!idpf_is_queue_model_split(vport->txq_model)) + goto notsupp; + + switch (xdp->command) { + case XDP_SETUP_PROG: + ret =3D idpf_xdp_setup_prog(vport, xdp); + break; + default: +notsupp: + ret =3D -EOPNOTSUPP; + break; + } + + idpf_vport_ctrl_unlock(dev); + + return ret; +} --=20 2.49.0