All of lore.kernel.org
 help / color / mirror / Atom feed
From: sdf@google.com
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, ast@kernel.org,
	daniel@iogearbox.net, andrii@kernel.org, davem@davemloft.net,
	kuba@kernel.org, hawk@kernel.org, pabeni@redhat.com,
	edumazet@google.com, toke@redhat.com, memxor@gmail.com,
	alardam@gmail.com, saeedm@nvidia.com, anthony.l.nguyen@intel.com,
	gospo@broadcom.com, vladimir.oltean@nxp.com, nbd@nbd.name,
	john@phrozen.org, leon@kernel.org, simon.horman@corigine.com,
	aelior@marvell.com, christophe.jaillet@wanadoo.fr,
	ecree.xilinx@gmail.com, mst@redhat.com, bjorn@kernel.org,
	magnus.karlsson@intel.com, maciej.fijalkowski@intel.com,
	intel-wired-lan@lists.osuosl.org, lorenzo.bianconi@redhat.com
Subject: Re: [RFC v2 bpf-next 2/7] drivers: net: turn on XDP features
Date: Wed, 18 Jan 2023 12:30:40 -0800	[thread overview]
Message-ID: <Y8hW8IqJTa0zE2aS@google.com> (raw)
In-Reply-To: <b606e729c9baf36a28be246bf0bfa4d21cc097fb.1673710867.git.lorenzo@kernel.org>

On 01/14, Lorenzo Bianconi wrote:
> From: Marek Majtyka <alardam@gmail.com>

> A summary of the flags being set for various drivers is given below.
> Note that XDP_F_REDIRECT_TARGET and XDP_F_FRAG_TARGET are features
> that can be turned off and on at runtime. This means that these flags
> may be set and unset under RTNL lock protection by the driver. Hence,
> READ_ONCE must be used by code loading the flag value.

> Also, these flags are not used for synchronization against the  
> availability
> of XDP resources on a device. It is merely a hint, and hence the read
> may race with the actual teardown of XDP resources on the device. This
> may change in the future, e.g. operations taking a reference on the XDP
> resources of the driver, and in turn inhibiting turning off this flag.
> However, for now, it can only be used as a hint to check whether device
> supports becoming a redirection target.

> Turn 'hw-offload' feature flag on for:
>   - netronome (nfp)
>   - netdevsim.

> Turn 'native' and 'zerocopy' features flags on for:
>   - intel (i40e, ice, ixgbe, igc)
>   - mellanox (mlx5).
>   - stmmac

> Turn 'native' features flags on for:
>   - amazon (ena)
>   - broadcom (bnxt)
>   - freescale (dpaa, dpaa2, enetc)
>   - funeth
>   - intel (igb)
>   - marvell (mvneta, mvpp2, octeontx2)
>   - mellanox (mlx4)
>   - qlogic (qede)
>   - sfc
>   - socionext (netsec)
>   - ti (cpsw)
>   - tap
>   - veth
>   - xen
>   - virtio_net.

> Turn 'basic' (tx, pass, aborted and drop) features flags on for:
>   - netronome (nfp)
>   - cavium (thunder)
>   - hyperv.

> Turn 'tx_lock' feature flag on for:
>   - aquantia
>   - freescale (dpaa2)
>   - intel (igb)
>   - marvell (mvneta, mvpp2)
>   - microsoft (mana)
>   - mediatek
>   - qlogic (qede)
>   - socionext (netsec)
>   - ti (cpsw)
>   - tap
>   - veth
>   - xen

> Turn 'redirect_target' feature flag on for:
>   - amanzon (ena)
>   - broadcom (bnxt)
>   - freescale (dpaa, dpaa2)
>   - intel (i40e, ice, igb, ixgbe)
>   - ti (cpsw)
>   - marvell (mvneta, mvpp2)
>   - sfc
>   - socionext (netsec)
>   - qlogic (qede)
>   - mellanox (mlx5)
>   - tap
>   - veth
>   - virtio_net
>   - xen

> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Marek Majtyka <alardam@gmail.com>
> ---
>   drivers/net/ethernet/amazon/ena/ena_netdev.c  |  5 +++
>   .../net/ethernet/aquantia/atlantic/aq_nic.c   |  4 ++
>   drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  2 +
>   drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  2 +
>   .../net/ethernet/cavium/thunder/nicvf_main.c  |  2 +
>   .../net/ethernet/freescale/dpaa/dpaa_eth.c    |  2 +
>   .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |  2 +
>   .../net/ethernet/freescale/enetc/enetc_pf.c   |  2 +
>   .../ethernet/fungible/funeth/funeth_main.c    |  6 +++
>   drivers/net/ethernet/intel/i40e/i40e_main.c   |  9 ++++-
>   drivers/net/ethernet/intel/ice/ice_main.c     |  5 +++
>   drivers/net/ethernet/intel/igb/igb_main.c     |  9 ++++-
>   drivers/net/ethernet/intel/igc/igc_main.c     |  2 +
>   drivers/net/ethernet/intel/igc/igc_xdp.c      |  5 +++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  5 +++
>   .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |  1 +
>   drivers/net/ethernet/marvell/mvneta.c         |  2 +
>   .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  3 ++
>   .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  9 ++++-
>   drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  5 +++
>   .../net/ethernet/mellanox/mlx4/en_netdev.c    |  2 +
>   .../net/ethernet/mellanox/mlx5/core/en_main.c |  9 +++++
>   drivers/net/ethernet/microsoft/mana/mana_en.c |  1 +
>   .../ethernet/netronome/nfp/nfp_net_common.c   |  4 ++
>   drivers/net/ethernet/qlogic/qede/qede_main.c  |  2 +
>   drivers/net/ethernet/sfc/efx.c                |  3 ++
>   drivers/net/ethernet/sfc/siena/efx.c          |  3 ++
>   drivers/net/ethernet/socionext/netsec.c       |  2 +
>   .../net/ethernet/stmicro/stmmac/stmmac_main.c |  1 +
>   drivers/net/ethernet/ti/cpsw.c                |  2 +
>   drivers/net/ethernet/ti/cpsw_new.c            |  3 ++
>   drivers/net/hyperv/netvsc_drv.c               |  2 +
>   drivers/net/netdevsim/netdev.c                |  1 +
>   drivers/net/tun.c                             |  4 ++
>   drivers/net/veth.c                            |  3 ++
>   drivers/net/virtio_net.c                      |  5 +++
>   drivers/net/xen-netfront.c                    |  1 +
>   include/net/xdp.h                             | 39 +++++++++++++++++++
>   38 files changed, 164 insertions(+), 5 deletions(-)

> diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c  
> b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> index e8ad5ea31aff..e8aeae70675a 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> @@ -597,7 +597,10 @@ static int ena_xdp_set(struct net_device *netdev,  
> struct netdev_bpf *bpf)
>   				if (rc)
>   					return rc;
>   			}
> +			__xdp_features_set_redirect_target(&netdev->xdp_features,
> +							   NETDEV_XDP_ACT_NDO_XMIT);
>   		} else if (old_bpf_prog) {
> +			xdp_features_clear_redirect_target(&netdev->xdp_features);
>   			rc = ena_destroy_and_free_all_xdp_queues(adapter);
>   			if (rc)
>   				return rc;
> @@ -4103,6 +4106,8 @@ static void ena_set_conf_feat_params(struct  
> ena_adapter *adapter,
>   	/* Set offload features */
>   	ena_set_dev_offloads(feat, netdev);

> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	adapter->max_mtu = feat->dev_attr.max_mtu;
>   	netdev->max_mtu = adapter->max_mtu;
>   	netdev->min_mtu = ENA_MIN_MTU;
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c  
> b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> index 06508eebb585..3fc9a702083c 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> @@ -384,6 +384,10 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
>   	self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
>   	self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;

> +	self->ndev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				   NETDEV_XDP_ACT_NDO_XMIT |
> +				   NETDEV_XDP_ACT_RX_SG |
> +				   NETDEV_XDP_ACT_NDO_XMIT_SG;
>   }

>   void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c  
> b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index 16ce7a90610c..333636d83620 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -13686,6 +13686,8 @@ static int bnxt_init_one(struct pci_dev *pdev,  
> const struct pci_device_id *ent)

>   	netif_set_tso_max_size(dev, GSO_MAX_SIZE);

> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_RX_SG;
> +
>   #ifdef CONFIG_BNXT_SRIOV
>   	init_waitqueue_head(&bp->sriov_cfg_wait);
>   #endif
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c  
> b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> index 36d5202c0aee..b701d6b5a405 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> @@ -422,9 +422,11 @@ static int bnxt_xdp_set(struct bnxt *bp, struct  
> bpf_prog *prog)

>   	if (prog) {
>   		bnxt_set_rx_skb_mode(bp, true);
> +		xdp_features_set_redirect_target(&dev->xdp_features);
>   	} else {
>   		int rx, tx;

> +		xdp_features_clear_redirect_target(&dev->xdp_features);
>   		bnxt_set_rx_skb_mode(bp, false);
>   		bnxt_get_max_rings(bp, &rx, &tx, true);
>   		if (rx > 1) {
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c  
> b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> index f2f95493ec89..8b25313c7f6b 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> @@ -2218,6 +2218,8 @@ static int nicvf_probe(struct pci_dev *pdev, const  
> struct pci_device_id *ent)
>   	netdev->netdev_ops = &nicvf_netdev_ops;
>   	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;

> +	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
> +
>   	/* MTU range: 64 - 9200 */
>   	netdev->min_mtu = NIC_HW_MIN_FRS;
>   	netdev->max_mtu = NIC_HW_MAX_FRS;
> diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c  
> b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> index 3f8032947d86..f6e1b270b6d0 100644
> --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> @@ -244,6 +244,8 @@ static int dpaa_netdev_init(struct net_device  
> *net_dev,
>   	net_dev->features |= net_dev->hw_features;
>   	net_dev->vlan_features = net_dev->features;

> +	net_dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (is_valid_ether_addr(mac_addr)) {
>   		memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
>   		eth_hw_addr_set(net_dev, mac_addr);
> diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c  
> b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> index 0c35abb7d065..8c51c59d3c86 100644
> --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> @@ -4593,6 +4593,8 @@ static int dpaa2_eth_netdev_init(struct net_device  
> *net_dev)
>   			    NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
>   	net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS;
>   	net_dev->hw_features = net_dev->features;
> +	net_dev->xdp_features = NETDEV_XDP_ACT_FULL_ZC |
> +				NETDEV_XDP_ACT_NDO_XMIT;

>   	if (priv->dpni_attrs.vlan_filter_entries)
>   		net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c  
> b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> index 9f6c4f5c0a6c..5f481985d3c1 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> @@ -825,6 +825,8 @@ static void enetc_pf_netdev_setup(struct enetc_si  
> *si, struct net_device *ndev,
>   		ndev->hw_features |= NETIF_F_RXHASH;

>   	ndev->priv_flags |= IFF_UNICAST_FLT;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			     NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;

>   	if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
>   		priv->active_offloads |= ENETC_F_QCI;
> diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c  
> b/drivers/net/ethernet/fungible/funeth/funeth_main.c
> index b4cce30e526a..003411b33a92 100644
> --- a/drivers/net/ethernet/fungible/funeth/funeth_main.c
> +++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c
> @@ -1160,6 +1160,11 @@ static int fun_xdp_setup(struct net_device *dev,  
> struct netdev_bpf *xdp)
>   			WRITE_ONCE(rxqs[i]->xdp_prog, prog);
>   	}

> +	if (prog)
> +		xdp_features_set_redirect_target(&dev->xdp_features);
> +	else
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +
>   	dev->max_mtu = prog ? XDP_MAX_MTU : FUN_MAX_MTU;
>   	old_prog = xchg(&fp->xdp_prog, prog);
>   	if (old_prog)
> @@ -1765,6 +1770,7 @@ static int fun_create_netdev(struct fun_ethdev *ed,  
> unsigned int portid)
>   	netdev->vlan_features = netdev->features & VLAN_FEAT;
>   	netdev->mpls_features = netdev->vlan_features;
>   	netdev->hw_enc_features = netdev->hw_features;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = FUN_MAX_MTU;
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c  
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 53d0083e35da..39f8ab2a22e6 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -13339,9 +13339,11 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi,  
> struct bpf_prog *prog,
>   	old_prog = xchg(&vsi->xdp_prog, prog);

>   	if (need_reset) {
> -		if (!prog)
> +		if (!prog) {
> +			xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
>   			/* Wait until ndo_xsk_wakeup completes. */
>   			synchronize_rcu();
> +		}
>   		i40e_reset_and_rebuild(pf, true, true);
>   	}

> @@ -13362,11 +13364,13 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi,  
> struct bpf_prog *prog,
>   	/* Kick start the NAPI context if there is an AF_XDP socket open
>   	 * on that queue id. This so that receiving will start.
>   	 */
> -	if (need_reset && prog)
> +	if (need_reset && prog) {
>   		for (i = 0; i < vsi->num_queue_pairs; i++)
>   			if (vsi->xdp_rings[i]->xsk_pool)
>   				(void)i40e_xsk_wakeup(vsi->netdev, i,
>   						      XDP_WAKEUP_RX);
> +		xdp_features_set_redirect_target(&vsi->netdev->xdp_features);
> +	}

>   	return 0;
>   }
> @@ -13783,6 +13787,7 @@ static int i40e_config_netdev(struct i40e_vsi  
> *vsi)
>   	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;

>   	netdev->features &= ~NETIF_F_HW_TC;
> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;

>   	if (vsi->type == I40E_VSI_MAIN) {
>   		SET_NETDEV_DEV(netdev, &pf->pdev->dev);
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c  
> b/drivers/net/ethernet/intel/ice/ice_main.c
> index a9a7f8b52140..0c9c75fa2349 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -22,6 +22,7 @@
>   #include "ice_eswitch.h"
>   #include "ice_tc_lib.h"
>   #include "ice_vsi_vlan_ops.h"
> +#include <net/xdp_sock_drv.h>

>   #define DRV_SUMMARY	"Intel(R) Ethernet Connection E800 Series Linux  
> Driver"
>   static const char ice_driver_string[] = DRV_SUMMARY;
> @@ -2899,11 +2900,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct  
> bpf_prog *prog,
>   			if (xdp_ring_err)
>   				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
>   		}
> +		__xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
> +						   NETDEV_XDP_ACT_NDO_XMIT);
>   		/* reallocate Rx queues that are used for zero-copy */
>   		xdp_ring_err = ice_realloc_zc_buf(vsi, true);
>   		if (xdp_ring_err)
>   			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
>   	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
> +		xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
>   		xdp_ring_err = ice_destroy_xdp_rings(vsi);
>   		if (xdp_ring_err)
>   			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
> @@ -3446,6 +3450,7 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
>   	np->vsi = vsi;

>   	ice_set_netdev_features(netdev);
> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;

>   	ice_set_ops(netdev);

> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c  
> b/drivers/net/ethernet/intel/igb/igb_main.c
> index 3c0c35ecea10..a20cc52a52d6 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2871,8 +2871,14 @@ static int igb_xdp_setup(struct net_device *dev,  
> struct netdev_bpf *bpf)
>   		bpf_prog_put(old_prog);

>   	/* bpf is just replaced, RXQ and MTU are already setup */
> -	if (!need_reset)
> +	if (!need_reset) {
>   		return 0;
> +	} else {
> +		if (prog)
> +			xdp_features_set_redirect_target(&dev->xdp_features);
> +		else
> +			xdp_features_clear_redirect_target(&dev->xdp_features);
> +	}

>   	if (running)
>   		igb_open(dev);
> @@ -3317,6 +3323,7 @@ static int igb_probe(struct pci_dev *pdev, const  
> struct pci_device_id *ent)
>   	netdev->priv_flags |= IFF_SUPP_NOFCS;

>   	netdev->priv_flags |= IFF_UNICAST_FLT;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	/* MTU range: 68 - 9216 */
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c  
> b/drivers/net/ethernet/intel/igc/igc_main.c
> index e86b15efaeb8..3702c3cea383 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6533,6 +6533,8 @@ static int igc_probe(struct pci_dev *pdev,
>   	netdev->mpls_features |= NETIF_F_HW_CSUM;
>   	netdev->hw_enc_features |= netdev->vlan_features;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
> +
>   	/* MTU range: 68 - 9216 */
>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
> diff --git a/drivers/net/ethernet/intel/igc/igc_xdp.c  
> b/drivers/net/ethernet/intel/igc/igc_xdp.c
> index aeeb34e64610..570170a29e3a 100644
> --- a/drivers/net/ethernet/intel/igc/igc_xdp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_xdp.c
> @@ -29,6 +29,11 @@ int igc_xdp_set_prog(struct igc_adapter *adapter,  
> struct bpf_prog *prog,
>   	if (old_prog)
>   		bpf_prog_put(old_prog);

> +	if (prog)
> +		xdp_features_set_redirect_target(&dev->xdp_features);
> +	else
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +
>   	if (if_running)
>   		igc_open(dev);

> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index ab8370c413f3..ae018a80d140 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -10301,6 +10301,8 @@ static int ixgbe_xdp_setup(struct net_device  
> *dev, struct bpf_prog *prog)
>   			rcu_assign_pointer(adapter->xdp_prog, old_prog);
>   			return -EINVAL;
>   		}
> +		if (!prog)
> +			xdp_features_clear_redirect_target(&dev->xdp_features);
>   	} else {
>   		for (i = 0; i < adapter->num_rx_queues; i++)
>   			(void)xchg(&adapter->rx_ring[i]->xdp_prog,
> @@ -10320,6 +10322,7 @@ static int ixgbe_xdp_setup(struct net_device  
> *dev, struct bpf_prog *prog)
>   			if (adapter->xdp_ring[i]->xsk_pool)
>   				(void)ixgbe_xsk_wakeup(adapter->netdev, i,
>   						       XDP_WAKEUP_RX);
> +		xdp_features_set_redirect_target(&dev->xdp_features);
>   	}

>   	return 0;
> @@ -11017,6 +11020,8 @@ static int ixgbe_probe(struct pci_dev *pdev,  
> const struct pci_device_id *ent)
>   	netdev->priv_flags |= IFF_UNICAST_FLT;
>   	netdev->priv_flags |= IFF_SUPP_NOFCS;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
> +
>   	/* MTU range: 68 - 9710 */
>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c  
> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> index ea0a230c1153..a44e4bd56142 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> @@ -4634,6 +4634,7 @@ static int ixgbevf_probe(struct pci_dev *pdev,  
> const struct pci_device_id *ent)
>   			    NETIF_F_HW_VLAN_CTAG_TX;

>   	netdev->priv_flags |= IFF_UNICAST_FLT;
> +	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;

>   	/* MTU range: 68 - 1504 or 9710 */
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/drivers/net/ethernet/marvell/mvneta.c  
> b/drivers/net/ethernet/marvell/mvneta.c
> index f8925cac61e4..7ca49753d618 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -5612,6 +5612,8 @@ static int mvneta_probe(struct platform_device  
> *pdev)
>   			NETIF_F_TSO | NETIF_F_RXCSUM;
>   	dev->hw_features |= dev->features;
>   	dev->vlan_features |= dev->features;
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
>   	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
>   	netif_set_tso_max_segs(dev, MVNETA_MAX_TSO_SEGS);

> diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c  
> b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> index 4da45c5abba5..826423541d7a 100644
> --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> @@ -6866,6 +6866,9 @@ static int mvpp2_port_probe(struct platform_device  
> *pdev,

>   	dev->vlan_features |= features;
>   	netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
> +
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	dev->priv_flags |= IFF_UNICAST_FLT;

>   	/* MTU range: 68 - 9704 */
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c  
> b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> index c1ea60bc2630..dd53bb315100 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> @@ -2512,10 +2512,14 @@ static int otx2_xdp_setup(struct otx2_nic *pf,  
> struct bpf_prog *prog)
>   	/* Network stack and XDP shared same rx queues.
>   	 * Use separate tx queues for XDP and network stack.
>   	 */
> -	if (pf->xdp_prog)
> +	if (pf->xdp_prog) {
>   		pf->hw.xdp_queues = pf->hw.rx_queues;
> -	else
> +		__xdp_features_set_redirect_target(&dev->xdp_features,
> +						   NETDEV_XDP_ACT_NDO_XMIT);
> +	} else {
>   		pf->hw.xdp_queues = 0;
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +	}

>   	pf->hw.tot_tx_queues += pf->hw.xdp_queues;

> @@ -2878,6 +2882,7 @@ static int otx2_probe(struct pci_dev *pdev, const  
> struct pci_device_id *id)
>   	netdev->watchdog_timeo = OTX2_TX_TIMEOUT;

>   	netdev->netdev_ops = &otx2_netdev_ops;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	netdev->min_mtu = OTX2_MIN_MTU;
>   	netdev->max_mtu = otx2_get_max_mtu(pf);
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c  
> b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index e3de9a53b2d9..d960dd3841d7 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -4186,6 +4186,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct  
> device_node *np)
>   		register_netdevice_notifier(&mac->device_notifier);
>   	}

> +	if (mtk_page_pool_enabled(eth))
> +		eth->netdev[id]->xdp_features = NETDEV_XDP_ACT_FULL |
> +						NETDEV_XDP_ACT_NDO_XMIT |
> +						NETDEV_XDP_ACT_NDO_XMIT_SG;
> +
>   	return 0;

>   free_netdev:
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c  
> b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 8800d3f1f55c..77957db600cb 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -3410,6 +3410,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev,  
> int port,
>   		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
>   	}

> +	dev->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	/* MTU range: 68 - hw-specific max */
>   	dev->min_mtu = ETH_MIN_MTU;
>   	dev->max_mtu = priv->max_mtu;
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c  
> b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index cff5f2e29e1e..f50988c5d636 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> @@ -4776,6 +4776,13 @@ static int mlx5e_xdp_set(struct net_device  
> *netdev, struct bpf_prog *prog)
>   	if (old_prog)
>   		bpf_prog_put(old_prog);

> +	if (reset) {
> +		if (prog)
> +			xdp_features_set_redirect_target(&netdev->xdp_features);
> +		else
> +			xdp_features_clear_redirect_target(&netdev->xdp_features);
> +	}
> +
>   	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
>   		goto unlock;

> @@ -5170,6 +5177,8 @@ static void mlx5e_build_nic_netdev(struct  
> net_device *netdev)
>   	netdev->features         |= NETIF_F_HIGHDMA;
>   	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_RX_SG;
> +
>   	netdev->priv_flags       |= IFF_UNICAST_FLT;

>   	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c  
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index 2f6a048dee90..25f21942aa20 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2160,6 +2160,7 @@ static int mana_probe_port(struct mana_context *ac,  
> int port_idx,
>   	ndev->hw_features |= NETIF_F_RXHASH;
>   	ndev->features = ndev->hw_features;
>   	ndev->vlan_features = 0;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	err = register_netdev(ndev);
>   	if (err) {
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c  
> b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> index 18fc9971f1c8..5a8ddeaff74d 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> @@ -2529,10 +2529,14 @@ static void nfp_net_netdev_init(struct nfp_net  
> *nn)
>   	netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
>   	nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;

> +	nn->dp.netdev->xdp_features = NETDEV_XDP_ACT_BASIC |
> +				      NETDEV_XDP_ACT_HW_OFFLOAD;
> +
>   	/* Finalise the netdev setup */
>   	switch (nn->dp.ops->version) {
>   	case NFP_NFD_VER_NFD3:
>   		netdev->netdev_ops = &nfp_nfd3_netdev_ops;
> +		nn->dp.netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
>   		break;
>   	case NFP_NFD_VER_NFDK:
>   		netdev->netdev_ops = &nfp_nfdk_netdev_ops;
> diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c  
> b/drivers/net/ethernet/qlogic/qede/qede_main.c
> index 953f304b8588..a8ad2b8386d3 100644
> --- a/drivers/net/ethernet/qlogic/qede/qede_main.c
> +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
> @@ -892,6 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)

>   	ndev->hw_features = hw_features;

> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	/* MTU range: 46 - 9600 */
>   	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
>   	ndev->max_mtu = QEDE_MAX_JUMBO_PACKET_SIZE;
> diff --git a/drivers/net/ethernet/sfc/efx.c  
> b/drivers/net/ethernet/sfc/efx.c
> index 0556542d7a6b..60b2183681ce 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -1078,6 +1078,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,

>   	pci_info(pci_dev, "Solarflare NIC detected\n");

> +	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (!efx->type->is_vf)
>   		efx_probe_vpd_strings(efx);

> diff --git a/drivers/net/ethernet/sfc/siena/efx.c  
> b/drivers/net/ethernet/sfc/siena/efx.c
> index 60e5b7c8ccf9..175c999bebc1 100644
> --- a/drivers/net/ethernet/sfc/siena/efx.c
> +++ b/drivers/net/ethernet/sfc/siena/efx.c
> @@ -1048,6 +1048,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,

>   	pci_info(pci_dev, "Solarflare NIC detected\n");

> +	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (!efx->type->is_vf)
>   		efx_probe_vpd_strings(efx);

> diff --git a/drivers/net/ethernet/socionext/netsec.c  
> b/drivers/net/ethernet/socionext/netsec.c
> index 9b46579b5a10..4d6f17efa227 100644
> --- a/drivers/net/ethernet/socionext/netsec.c
> +++ b/drivers/net/ethernet/socionext/netsec.c
> @@ -2104,6 +2104,8 @@ static int netsec_probe(struct platform_device  
> *pdev)
>   				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
>   	ndev->hw_features = ndev->features;

> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	priv->rx_cksum_offload_flag = true;

>   	ret = netsec_register_mdio(priv, phy_addr);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index c6951c976f5d..316574ce3aa0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -7145,6 +7145,7 @@ int stmmac_dvr_probe(struct device *device,

>   	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
>   			    NETIF_F_RXCSUM;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ret = stmmac_tc_init(priv, priv);
>   	if (!ret) {
> diff --git a/drivers/net/ethernet/ti/cpsw.c  
> b/drivers/net/ethernet/ti/cpsw.c
> index 13c9c2d6b79b..68b89c56d8b6 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -1458,6 +1458,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv  
> *priv)
>   	priv_sl2->emac_port = 1;
>   	cpsw->slaves[1].ndev = ndev;
>   	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ndev->netdev_ops = &cpsw_netdev_ops;
>   	ndev->ethtool_ops = &cpsw_ethtool_ops;
> @@ -1635,6 +1636,7 @@ static int cpsw_probe(struct platform_device *pdev)
>   	cpsw->slaves[0].ndev = ndev;

>   	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ndev->netdev_ops = &cpsw_netdev_ops;
>   	ndev->ethtool_ops = &cpsw_ethtool_ops;
> diff --git a/drivers/net/ethernet/ti/cpsw_new.c  
> b/drivers/net/ethernet/ti/cpsw_new.c
> index 83596ec0c7cb..1cf8c6202e05 100644
> --- a/drivers/net/ethernet/ti/cpsw_new.c
> +++ b/drivers/net/ethernet/ti/cpsw_new.c
> @@ -1405,6 +1405,9 @@ static int cpsw_create_ports(struct cpsw_common  
> *cpsw)
>   		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
>   				  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;

> +		ndev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   		ndev->netdev_ops = &cpsw_netdev_ops;
>   		ndev->ethtool_ops = &cpsw_ethtool_ops;
>   		SET_NETDEV_DEV(ndev, dev);
> diff --git a/drivers/net/hyperv/netvsc_drv.c  
> b/drivers/net/hyperv/netvsc_drv.c
> index f9b219e6cd58..c7c1ce6ca201 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,

>   	netdev_lockdep_set_classes(net);

> +	net->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	/* MTU range: 68 - 1500 or 65521 */
>   	net->min_mtu = NETVSC_MTU_MIN;
>   	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> diff --git a/drivers/net/netdevsim/netdev.c  
> b/drivers/net/netdevsim/netdev.c
> index 6db6a75ff9b9..35fa1ca98671 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -286,6 +286,7 @@ static void nsim_setup(struct net_device *dev)
>   			 NETIF_F_TSO;
>   	dev->hw_features |= NETIF_F_HW_TC;
>   	dev->max_mtu = ETH_MAX_MTU;
> +	dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD;
>   }

>   static int nsim_init_netdevsim(struct netdevsim *ns)
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index a7d17c680f4a..fc041cff75e4 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1401,6 +1401,10 @@ static void tun_net_initialize(struct net_device  
> *dev)

>   		eth_hw_addr_random(dev);

> +		/* Currently tun does not support XDP, only tap does. */
> +		dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				    NETDEV_XDP_ACT_NDO_XMIT;
> +
>   		break;
>   	}

> diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> index dfc7d87fad59..01f7b38888a0 100644
> --- a/drivers/net/veth.c
> +++ b/drivers/net/veth.c
> @@ -1649,6 +1649,9 @@ static void veth_setup(struct net_device *dev)
>   	dev->hw_enc_features = VETH_FEATURES;
>   	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
>   	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
> +
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
>   }

>   /*
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 7723b2a49d8e..0721dff8c82c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -3155,7 +3155,11 @@ static int virtnet_xdp_set(struct net_device *dev,  
> struct bpf_prog *prog,
>   			if (i == 0 && !old_prog)
>   				virtnet_clear_guest_offloads(vi);
>   		}
> +		if (!old_prog)
> +			__xdp_features_set_redirect_target(&dev->xdp_features,
> +							   NETDEV_XDP_ACT_NDO_XMIT);
>   	} else {
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
>   		vi->xdp_enabled = false;
>   	}

> @@ -3785,6 +3789,7 @@ static int virtnet_probe(struct virtio_device *vdev)
>   		dev->hw_features |= NETIF_F_GRO_HW;

>   	dev->vlan_features = dev->features;
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	/* MTU range: 68 - 65535 */
>   	dev->min_mtu = MIN_MTU;
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index 14aec417fa06..58f0cbbadc90 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1741,6 +1741,7 @@ static struct net_device *xennet_create_dev(struct  
> xenbus_device *dev)
>            * negotiate with the backend regarding supported features.
>            */
>   	netdev->features |= netdev->hw_features;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	netdev->ethtool_ops = &xennet_ethtool_ops;
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/include/net/xdp.h b/include/net/xdp.h
> index 3d37460f0bdb..c3a8f17c0310 100644
> --- a/include/net/xdp.h
> +++ b/include/net/xdp.h
> @@ -410,6 +410,45 @@ struct netdev_bpf;
>   void xdp_attachment_setup(struct xdp_attachment_info *info,
>   			  struct netdev_bpf *bpf);

> +#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
> +
> +static inline void
> +__xdp_features_set_redirect_target(xdp_features_t *xdp_features, u32  
> flags)
> +{
> +	flags &= (NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_NDO_XMIT_SG);
> +	WRITE_ONCE(*xdp_features, *xdp_features | flags);

Maybe stupid question: why do we need WRITE_ONCE here?
And if we do need it, do we need READ_ONCE as well?

WRITE_ONCE(*xdp_features, READ_ONCE(*xdp_features) | flags);

?

Also, would it make sense to drop this __xdp_features_set_redirect_target
and just define the following:

static inline void
xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool  
support_sg)
{
	xdp_features_t flags = NETDEV_XDP_ACT_NDO_XMIT;

	if (support_sg)
		flags |= NETDEV_XDP_ACT_NDO_XMIT_SG;
	*xdp_features |= flags; /* or WRITE_ONCE */
}

This should avoid having two different sets of functions. Or does it
look worse because of that 'naked' true/false argument in the call
sites?


> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +	WRITE_ONCE(*xdp_features,
> +		   *xdp_features & ~(NETDEV_XDP_ACT_NDO_XMIT |
> +				     NETDEV_XDP_ACT_NDO_XMIT_SG));
> +}
> +
> +#else
> +
> +static inline void
> +__xdp_features_set_redirect_target(xdp_features_t *xdp_features, u32  
> flags)
> +{
> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +}
> +
> +#endif
> +
> +static inline void
> +xdp_features_set_redirect_target(xdp_features_t *xdp_features)
> +{
> +	__xdp_features_set_redirect_target(xdp_features,
> +					   NETDEV_XDP_ACT_NDO_XMIT |
> +					   NETDEV_XDP_ACT_NDO_XMIT_SG);
> +}
> +
>   #define DEV_MAP_BULK_SIZE XDP_BULK_QUEUE_SIZE

>   #endif /* __LINUX_NET_XDP_H__ */
> --
> 2.39.0


WARNING: multiple messages have this Message-ID (diff)
From: sdf@google.com
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: mst@redhat.com, vladimir.oltean@nxp.com, ast@kernel.org,
	edumazet@google.com, anthony.l.nguyen@intel.com,
	daniel@iogearbox.net, andrii@kernel.org,
	intel-wired-lan@lists.osuosl.org, simon.horman@corigine.com,
	kuba@kernel.org, pabeni@redhat.com, aelior@marvell.com,
	hawk@kernel.org, christophe.jaillet@wanadoo.fr, memxor@gmail.com,
	john@phrozen.org, bjorn@kernel.org, bpf@vger.kernel.org,
	magnus.karlsson@intel.com, leon@kernel.org,
	netdev@vger.kernel.org, toke@redhat.com, ecree.xilinx@gmail.com,
	alardam@gmail.com, gospo@broadcom.com, saeedm@nvidia.com,
	davem@davemloft.net, nbd@nbd.name
Subject: Re: [Intel-wired-lan] [RFC v2 bpf-next 2/7] drivers: net: turn on XDP features
Date: Wed, 18 Jan 2023 12:30:40 -0800	[thread overview]
Message-ID: <Y8hW8IqJTa0zE2aS@google.com> (raw)
In-Reply-To: <b606e729c9baf36a28be246bf0bfa4d21cc097fb.1673710867.git.lorenzo@kernel.org>

On 01/14, Lorenzo Bianconi wrote:
> From: Marek Majtyka <alardam@gmail.com>

> A summary of the flags being set for various drivers is given below.
> Note that XDP_F_REDIRECT_TARGET and XDP_F_FRAG_TARGET are features
> that can be turned off and on at runtime. This means that these flags
> may be set and unset under RTNL lock protection by the driver. Hence,
> READ_ONCE must be used by code loading the flag value.

> Also, these flags are not used for synchronization against the  
> availability
> of XDP resources on a device. It is merely a hint, and hence the read
> may race with the actual teardown of XDP resources on the device. This
> may change in the future, e.g. operations taking a reference on the XDP
> resources of the driver, and in turn inhibiting turning off this flag.
> However, for now, it can only be used as a hint to check whether device
> supports becoming a redirection target.

> Turn 'hw-offload' feature flag on for:
>   - netronome (nfp)
>   - netdevsim.

> Turn 'native' and 'zerocopy' features flags on for:
>   - intel (i40e, ice, ixgbe, igc)
>   - mellanox (mlx5).
>   - stmmac

> Turn 'native' features flags on for:
>   - amazon (ena)
>   - broadcom (bnxt)
>   - freescale (dpaa, dpaa2, enetc)
>   - funeth
>   - intel (igb)
>   - marvell (mvneta, mvpp2, octeontx2)
>   - mellanox (mlx4)
>   - qlogic (qede)
>   - sfc
>   - socionext (netsec)
>   - ti (cpsw)
>   - tap
>   - veth
>   - xen
>   - virtio_net.

> Turn 'basic' (tx, pass, aborted and drop) features flags on for:
>   - netronome (nfp)
>   - cavium (thunder)
>   - hyperv.

> Turn 'tx_lock' feature flag on for:
>   - aquantia
>   - freescale (dpaa2)
>   - intel (igb)
>   - marvell (mvneta, mvpp2)
>   - microsoft (mana)
>   - mediatek
>   - qlogic (qede)
>   - socionext (netsec)
>   - ti (cpsw)
>   - tap
>   - veth
>   - xen

> Turn 'redirect_target' feature flag on for:
>   - amanzon (ena)
>   - broadcom (bnxt)
>   - freescale (dpaa, dpaa2)
>   - intel (i40e, ice, igb, ixgbe)
>   - ti (cpsw)
>   - marvell (mvneta, mvpp2)
>   - sfc
>   - socionext (netsec)
>   - qlogic (qede)
>   - mellanox (mlx5)
>   - tap
>   - veth
>   - virtio_net
>   - xen

> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> Signed-off-by: Marek Majtyka <alardam@gmail.com>
> ---
>   drivers/net/ethernet/amazon/ena/ena_netdev.c  |  5 +++
>   .../net/ethernet/aquantia/atlantic/aq_nic.c   |  4 ++
>   drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  2 +
>   drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |  2 +
>   .../net/ethernet/cavium/thunder/nicvf_main.c  |  2 +
>   .../net/ethernet/freescale/dpaa/dpaa_eth.c    |  2 +
>   .../net/ethernet/freescale/dpaa2/dpaa2-eth.c  |  2 +
>   .../net/ethernet/freescale/enetc/enetc_pf.c   |  2 +
>   .../ethernet/fungible/funeth/funeth_main.c    |  6 +++
>   drivers/net/ethernet/intel/i40e/i40e_main.c   |  9 ++++-
>   drivers/net/ethernet/intel/ice/ice_main.c     |  5 +++
>   drivers/net/ethernet/intel/igb/igb_main.c     |  9 ++++-
>   drivers/net/ethernet/intel/igc/igc_main.c     |  2 +
>   drivers/net/ethernet/intel/igc/igc_xdp.c      |  5 +++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  5 +++
>   .../net/ethernet/intel/ixgbevf/ixgbevf_main.c |  1 +
>   drivers/net/ethernet/marvell/mvneta.c         |  2 +
>   .../net/ethernet/marvell/mvpp2/mvpp2_main.c   |  3 ++
>   .../ethernet/marvell/octeontx2/nic/otx2_pf.c  |  9 ++++-
>   drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  5 +++
>   .../net/ethernet/mellanox/mlx4/en_netdev.c    |  2 +
>   .../net/ethernet/mellanox/mlx5/core/en_main.c |  9 +++++
>   drivers/net/ethernet/microsoft/mana/mana_en.c |  1 +
>   .../ethernet/netronome/nfp/nfp_net_common.c   |  4 ++
>   drivers/net/ethernet/qlogic/qede/qede_main.c  |  2 +
>   drivers/net/ethernet/sfc/efx.c                |  3 ++
>   drivers/net/ethernet/sfc/siena/efx.c          |  3 ++
>   drivers/net/ethernet/socionext/netsec.c       |  2 +
>   .../net/ethernet/stmicro/stmmac/stmmac_main.c |  1 +
>   drivers/net/ethernet/ti/cpsw.c                |  2 +
>   drivers/net/ethernet/ti/cpsw_new.c            |  3 ++
>   drivers/net/hyperv/netvsc_drv.c               |  2 +
>   drivers/net/netdevsim/netdev.c                |  1 +
>   drivers/net/tun.c                             |  4 ++
>   drivers/net/veth.c                            |  3 ++
>   drivers/net/virtio_net.c                      |  5 +++
>   drivers/net/xen-netfront.c                    |  1 +
>   include/net/xdp.h                             | 39 +++++++++++++++++++
>   38 files changed, 164 insertions(+), 5 deletions(-)

> diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c  
> b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> index e8ad5ea31aff..e8aeae70675a 100644
> --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
> +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
> @@ -597,7 +597,10 @@ static int ena_xdp_set(struct net_device *netdev,  
> struct netdev_bpf *bpf)
>   				if (rc)
>   					return rc;
>   			}
> +			__xdp_features_set_redirect_target(&netdev->xdp_features,
> +							   NETDEV_XDP_ACT_NDO_XMIT);
>   		} else if (old_bpf_prog) {
> +			xdp_features_clear_redirect_target(&netdev->xdp_features);
>   			rc = ena_destroy_and_free_all_xdp_queues(adapter);
>   			if (rc)
>   				return rc;
> @@ -4103,6 +4106,8 @@ static void ena_set_conf_feat_params(struct  
> ena_adapter *adapter,
>   	/* Set offload features */
>   	ena_set_dev_offloads(feat, netdev);

> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	adapter->max_mtu = feat->dev_attr.max_mtu;
>   	netdev->max_mtu = adapter->max_mtu;
>   	netdev->min_mtu = ENA_MIN_MTU;
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c  
> b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> index 06508eebb585..3fc9a702083c 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> @@ -384,6 +384,10 @@ void aq_nic_ndev_init(struct aq_nic_s *self)
>   	self->ndev->mtu = aq_nic_cfg->mtu - ETH_HLEN;
>   	self->ndev->max_mtu = aq_hw_caps->mtu - ETH_FCS_LEN - ETH_HLEN;

> +	self->ndev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				   NETDEV_XDP_ACT_NDO_XMIT |
> +				   NETDEV_XDP_ACT_RX_SG |
> +				   NETDEV_XDP_ACT_NDO_XMIT_SG;
>   }

>   void aq_nic_set_tx_ring(struct aq_nic_s *self, unsigned int idx,
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c  
> b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index 16ce7a90610c..333636d83620 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -13686,6 +13686,8 @@ static int bnxt_init_one(struct pci_dev *pdev,  
> const struct pci_device_id *ent)

>   	netif_set_tso_max_size(dev, GSO_MAX_SIZE);

> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_RX_SG;
> +
>   #ifdef CONFIG_BNXT_SRIOV
>   	init_waitqueue_head(&bp->sriov_cfg_wait);
>   #endif
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c  
> b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> index 36d5202c0aee..b701d6b5a405 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
> @@ -422,9 +422,11 @@ static int bnxt_xdp_set(struct bnxt *bp, struct  
> bpf_prog *prog)

>   	if (prog) {
>   		bnxt_set_rx_skb_mode(bp, true);
> +		xdp_features_set_redirect_target(&dev->xdp_features);
>   	} else {
>   		int rx, tx;

> +		xdp_features_clear_redirect_target(&dev->xdp_features);
>   		bnxt_set_rx_skb_mode(bp, false);
>   		bnxt_get_max_rings(bp, &rx, &tx, true);
>   		if (rx > 1) {
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c  
> b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> index f2f95493ec89..8b25313c7f6b 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> @@ -2218,6 +2218,8 @@ static int nicvf_probe(struct pci_dev *pdev, const  
> struct pci_device_id *ent)
>   	netdev->netdev_ops = &nicvf_netdev_ops;
>   	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;

> +	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;
> +
>   	/* MTU range: 64 - 9200 */
>   	netdev->min_mtu = NIC_HW_MIN_FRS;
>   	netdev->max_mtu = NIC_HW_MAX_FRS;
> diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c  
> b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> index 3f8032947d86..f6e1b270b6d0 100644
> --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
> @@ -244,6 +244,8 @@ static int dpaa_netdev_init(struct net_device  
> *net_dev,
>   	net_dev->features |= net_dev->hw_features;
>   	net_dev->vlan_features = net_dev->features;

> +	net_dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (is_valid_ether_addr(mac_addr)) {
>   		memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
>   		eth_hw_addr_set(net_dev, mac_addr);
> diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c  
> b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> index 0c35abb7d065..8c51c59d3c86 100644
> --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
> @@ -4593,6 +4593,8 @@ static int dpaa2_eth_netdev_init(struct net_device  
> *net_dev)
>   			    NETIF_F_LLTX | NETIF_F_HW_TC | NETIF_F_TSO;
>   	net_dev->gso_max_segs = DPAA2_ETH_ENQUEUE_MAX_FDS;
>   	net_dev->hw_features = net_dev->features;
> +	net_dev->xdp_features = NETDEV_XDP_ACT_FULL_ZC |
> +				NETDEV_XDP_ACT_NDO_XMIT;

>   	if (priv->dpni_attrs.vlan_filter_entries)
>   		net_dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c  
> b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> index 9f6c4f5c0a6c..5f481985d3c1 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
> @@ -825,6 +825,8 @@ static void enetc_pf_netdev_setup(struct enetc_si  
> *si, struct net_device *ndev,
>   		ndev->hw_features |= NETIF_F_RXHASH;

>   	ndev->priv_flags |= IFF_UNICAST_FLT;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			     NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;

>   	if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
>   		priv->active_offloads |= ENETC_F_QCI;
> diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c  
> b/drivers/net/ethernet/fungible/funeth/funeth_main.c
> index b4cce30e526a..003411b33a92 100644
> --- a/drivers/net/ethernet/fungible/funeth/funeth_main.c
> +++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c
> @@ -1160,6 +1160,11 @@ static int fun_xdp_setup(struct net_device *dev,  
> struct netdev_bpf *xdp)
>   			WRITE_ONCE(rxqs[i]->xdp_prog, prog);
>   	}

> +	if (prog)
> +		xdp_features_set_redirect_target(&dev->xdp_features);
> +	else
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +
>   	dev->max_mtu = prog ? XDP_MAX_MTU : FUN_MAX_MTU;
>   	old_prog = xchg(&fp->xdp_prog, prog);
>   	if (old_prog)
> @@ -1765,6 +1770,7 @@ static int fun_create_netdev(struct fun_ethdev *ed,  
> unsigned int portid)
>   	netdev->vlan_features = netdev->features & VLAN_FEAT;
>   	netdev->mpls_features = netdev->vlan_features;
>   	netdev->hw_enc_features = netdev->hw_features;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = FUN_MAX_MTU;
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c  
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 53d0083e35da..39f8ab2a22e6 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -13339,9 +13339,11 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi,  
> struct bpf_prog *prog,
>   	old_prog = xchg(&vsi->xdp_prog, prog);

>   	if (need_reset) {
> -		if (!prog)
> +		if (!prog) {
> +			xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
>   			/* Wait until ndo_xsk_wakeup completes. */
>   			synchronize_rcu();
> +		}
>   		i40e_reset_and_rebuild(pf, true, true);
>   	}

> @@ -13362,11 +13364,13 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi,  
> struct bpf_prog *prog,
>   	/* Kick start the NAPI context if there is an AF_XDP socket open
>   	 * on that queue id. This so that receiving will start.
>   	 */
> -	if (need_reset && prog)
> +	if (need_reset && prog) {
>   		for (i = 0; i < vsi->num_queue_pairs; i++)
>   			if (vsi->xdp_rings[i]->xsk_pool)
>   				(void)i40e_xsk_wakeup(vsi->netdev, i,
>   						      XDP_WAKEUP_RX);
> +		xdp_features_set_redirect_target(&vsi->netdev->xdp_features);
> +	}

>   	return 0;
>   }
> @@ -13783,6 +13787,7 @@ static int i40e_config_netdev(struct i40e_vsi  
> *vsi)
>   	netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;

>   	netdev->features &= ~NETIF_F_HW_TC;
> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;

>   	if (vsi->type == I40E_VSI_MAIN) {
>   		SET_NETDEV_DEV(netdev, &pf->pdev->dev);
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c  
> b/drivers/net/ethernet/intel/ice/ice_main.c
> index a9a7f8b52140..0c9c75fa2349 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -22,6 +22,7 @@
>   #include "ice_eswitch.h"
>   #include "ice_tc_lib.h"
>   #include "ice_vsi_vlan_ops.h"
> +#include <net/xdp_sock_drv.h>

>   #define DRV_SUMMARY	"Intel(R) Ethernet Connection E800 Series Linux  
> Driver"
>   static const char ice_driver_string[] = DRV_SUMMARY;
> @@ -2899,11 +2900,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct  
> bpf_prog *prog,
>   			if (xdp_ring_err)
>   				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
>   		}
> +		__xdp_features_set_redirect_target(&vsi->netdev->xdp_features,
> +						   NETDEV_XDP_ACT_NDO_XMIT);
>   		/* reallocate Rx queues that are used for zero-copy */
>   		xdp_ring_err = ice_realloc_zc_buf(vsi, true);
>   		if (xdp_ring_err)
>   			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
>   	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
> +		xdp_features_clear_redirect_target(&vsi->netdev->xdp_features);
>   		xdp_ring_err = ice_destroy_xdp_rings(vsi);
>   		if (xdp_ring_err)
>   			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
> @@ -3446,6 +3450,7 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
>   	np->vsi = vsi;

>   	ice_set_netdev_features(netdev);
> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;

>   	ice_set_ops(netdev);

> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c  
> b/drivers/net/ethernet/intel/igb/igb_main.c
> index 3c0c35ecea10..a20cc52a52d6 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2871,8 +2871,14 @@ static int igb_xdp_setup(struct net_device *dev,  
> struct netdev_bpf *bpf)
>   		bpf_prog_put(old_prog);

>   	/* bpf is just replaced, RXQ and MTU are already setup */
> -	if (!need_reset)
> +	if (!need_reset) {
>   		return 0;
> +	} else {
> +		if (prog)
> +			xdp_features_set_redirect_target(&dev->xdp_features);
> +		else
> +			xdp_features_clear_redirect_target(&dev->xdp_features);
> +	}

>   	if (running)
>   		igb_open(dev);
> @@ -3317,6 +3323,7 @@ static int igb_probe(struct pci_dev *pdev, const  
> struct pci_device_id *ent)
>   	netdev->priv_flags |= IFF_SUPP_NOFCS;

>   	netdev->priv_flags |= IFF_UNICAST_FLT;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	/* MTU range: 68 - 9216 */
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c  
> b/drivers/net/ethernet/intel/igc/igc_main.c
> index e86b15efaeb8..3702c3cea383 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -6533,6 +6533,8 @@ static int igc_probe(struct pci_dev *pdev,
>   	netdev->mpls_features |= NETIF_F_HW_CSUM;
>   	netdev->hw_enc_features |= netdev->vlan_features;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
> +
>   	/* MTU range: 68 - 9216 */
>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = MAX_STD_JUMBO_FRAME_SIZE;
> diff --git a/drivers/net/ethernet/intel/igc/igc_xdp.c  
> b/drivers/net/ethernet/intel/igc/igc_xdp.c
> index aeeb34e64610..570170a29e3a 100644
> --- a/drivers/net/ethernet/intel/igc/igc_xdp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_xdp.c
> @@ -29,6 +29,11 @@ int igc_xdp_set_prog(struct igc_adapter *adapter,  
> struct bpf_prog *prog,
>   	if (old_prog)
>   		bpf_prog_put(old_prog);

> +	if (prog)
> +		xdp_features_set_redirect_target(&dev->xdp_features);
> +	else
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +
>   	if (if_running)
>   		igc_open(dev);

> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  
> b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index ab8370c413f3..ae018a80d140 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -10301,6 +10301,8 @@ static int ixgbe_xdp_setup(struct net_device  
> *dev, struct bpf_prog *prog)
>   			rcu_assign_pointer(adapter->xdp_prog, old_prog);
>   			return -EINVAL;
>   		}
> +		if (!prog)
> +			xdp_features_clear_redirect_target(&dev->xdp_features);
>   	} else {
>   		for (i = 0; i < adapter->num_rx_queues; i++)
>   			(void)xchg(&adapter->rx_ring[i]->xdp_prog,
> @@ -10320,6 +10322,7 @@ static int ixgbe_xdp_setup(struct net_device  
> *dev, struct bpf_prog *prog)
>   			if (adapter->xdp_ring[i]->xsk_pool)
>   				(void)ixgbe_xsk_wakeup(adapter->netdev, i,
>   						       XDP_WAKEUP_RX);
> +		xdp_features_set_redirect_target(&dev->xdp_features);
>   	}

>   	return 0;
> @@ -11017,6 +11020,8 @@ static int ixgbe_probe(struct pci_dev *pdev,  
> const struct pci_device_id *ent)
>   	netdev->priv_flags |= IFF_UNICAST_FLT;
>   	netdev->priv_flags |= IFF_SUPP_NOFCS;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC;
> +
>   	/* MTU range: 68 - 9710 */
>   	netdev->min_mtu = ETH_MIN_MTU;
>   	netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);
> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c  
> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> index ea0a230c1153..a44e4bd56142 100644
> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> @@ -4634,6 +4634,7 @@ static int ixgbevf_probe(struct pci_dev *pdev,  
> const struct pci_device_id *ent)
>   			    NETIF_F_HW_VLAN_CTAG_TX;

>   	netdev->priv_flags |= IFF_UNICAST_FLT;
> +	netdev->xdp_features = NETDEV_XDP_ACT_BASIC;

>   	/* MTU range: 68 - 1504 or 9710 */
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/drivers/net/ethernet/marvell/mvneta.c  
> b/drivers/net/ethernet/marvell/mvneta.c
> index f8925cac61e4..7ca49753d618 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -5612,6 +5612,8 @@ static int mvneta_probe(struct platform_device  
> *pdev)
>   			NETIF_F_TSO | NETIF_F_RXCSUM;
>   	dev->hw_features |= dev->features;
>   	dev->vlan_features |= dev->features;
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
>   	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
>   	netif_set_tso_max_segs(dev, MVNETA_MAX_TSO_SEGS);

> diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c  
> b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> index 4da45c5abba5..826423541d7a 100644
> --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
> @@ -6866,6 +6866,9 @@ static int mvpp2_port_probe(struct platform_device  
> *pdev,

>   	dev->vlan_features |= features;
>   	netif_set_tso_max_segs(dev, MVPP2_MAX_TSO_SEGS);
> +
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	dev->priv_flags |= IFF_UNICAST_FLT;

>   	/* MTU range: 68 - 9704 */
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c  
> b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> index c1ea60bc2630..dd53bb315100 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
> @@ -2512,10 +2512,14 @@ static int otx2_xdp_setup(struct otx2_nic *pf,  
> struct bpf_prog *prog)
>   	/* Network stack and XDP shared same rx queues.
>   	 * Use separate tx queues for XDP and network stack.
>   	 */
> -	if (pf->xdp_prog)
> +	if (pf->xdp_prog) {
>   		pf->hw.xdp_queues = pf->hw.rx_queues;
> -	else
> +		__xdp_features_set_redirect_target(&dev->xdp_features,
> +						   NETDEV_XDP_ACT_NDO_XMIT);
> +	} else {
>   		pf->hw.xdp_queues = 0;
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
> +	}

>   	pf->hw.tot_tx_queues += pf->hw.xdp_queues;

> @@ -2878,6 +2882,7 @@ static int otx2_probe(struct pci_dev *pdev, const  
> struct pci_device_id *id)
>   	netdev->watchdog_timeo = OTX2_TX_TIMEOUT;

>   	netdev->netdev_ops = &otx2_netdev_ops;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	netdev->min_mtu = OTX2_MIN_MTU;
>   	netdev->max_mtu = otx2_get_max_mtu(pf);
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c  
> b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index e3de9a53b2d9..d960dd3841d7 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -4186,6 +4186,11 @@ static int mtk_add_mac(struct mtk_eth *eth, struct  
> device_node *np)
>   		register_netdevice_notifier(&mac->device_notifier);
>   	}

> +	if (mtk_page_pool_enabled(eth))
> +		eth->netdev[id]->xdp_features = NETDEV_XDP_ACT_FULL |
> +						NETDEV_XDP_ACT_NDO_XMIT |
> +						NETDEV_XDP_ACT_NDO_XMIT_SG;
> +
>   	return 0;

>   free_netdev:
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c  
> b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 8800d3f1f55c..77957db600cb 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -3410,6 +3410,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev,  
> int port,
>   		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
>   	}

> +	dev->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	/* MTU range: 68 - hw-specific max */
>   	dev->min_mtu = ETH_MIN_MTU;
>   	dev->max_mtu = priv->max_mtu;
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c  
> b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index cff5f2e29e1e..f50988c5d636 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> @@ -4776,6 +4776,13 @@ static int mlx5e_xdp_set(struct net_device  
> *netdev, struct bpf_prog *prog)
>   	if (old_prog)
>   		bpf_prog_put(old_prog);

> +	if (reset) {
> +		if (prog)
> +			xdp_features_set_redirect_target(&netdev->xdp_features);
> +		else
> +			xdp_features_clear_redirect_target(&netdev->xdp_features);
> +	}
> +
>   	if (!test_bit(MLX5E_STATE_OPENED, &priv->state) || reset)
>   		goto unlock;

> @@ -5170,6 +5177,8 @@ static void mlx5e_build_nic_netdev(struct  
> net_device *netdev)
>   	netdev->features         |= NETIF_F_HIGHDMA;
>   	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;

> +	netdev->xdp_features = NETDEV_XDP_ACT_ZC | NETDEV_XDP_ACT_RX_SG;
> +
>   	netdev->priv_flags       |= IFF_UNICAST_FLT;

>   	netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c  
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index 2f6a048dee90..25f21942aa20 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2160,6 +2160,7 @@ static int mana_probe_port(struct mana_context *ac,  
> int port_idx,
>   	ndev->hw_features |= NETIF_F_RXHASH;
>   	ndev->features = ndev->hw_features;
>   	ndev->vlan_features = 0;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	err = register_netdev(ndev);
>   	if (err) {
> diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c  
> b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> index 18fc9971f1c8..5a8ddeaff74d 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
> @@ -2529,10 +2529,14 @@ static void nfp_net_netdev_init(struct nfp_net  
> *nn)
>   	netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
>   	nn->dp.ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ;

> +	nn->dp.netdev->xdp_features = NETDEV_XDP_ACT_BASIC |
> +				      NETDEV_XDP_ACT_HW_OFFLOAD;
> +
>   	/* Finalise the netdev setup */
>   	switch (nn->dp.ops->version) {
>   	case NFP_NFD_VER_NFD3:
>   		netdev->netdev_ops = &nfp_nfd3_netdev_ops;
> +		nn->dp.netdev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
>   		break;
>   	case NFP_NFD_VER_NFDK:
>   		netdev->netdev_ops = &nfp_nfdk_netdev_ops;
> diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c  
> b/drivers/net/ethernet/qlogic/qede/qede_main.c
> index 953f304b8588..a8ad2b8386d3 100644
> --- a/drivers/net/ethernet/qlogic/qede/qede_main.c
> +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
> @@ -892,6 +892,8 @@ static void qede_init_ndev(struct qede_dev *edev)

>   	ndev->hw_features = hw_features;

> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	/* MTU range: 46 - 9600 */
>   	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
>   	ndev->max_mtu = QEDE_MAX_JUMBO_PACKET_SIZE;
> diff --git a/drivers/net/ethernet/sfc/efx.c  
> b/drivers/net/ethernet/sfc/efx.c
> index 0556542d7a6b..60b2183681ce 100644
> --- a/drivers/net/ethernet/sfc/efx.c
> +++ b/drivers/net/ethernet/sfc/efx.c
> @@ -1078,6 +1078,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,

>   	pci_info(pci_dev, "Solarflare NIC detected\n");

> +	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (!efx->type->is_vf)
>   		efx_probe_vpd_strings(efx);

> diff --git a/drivers/net/ethernet/sfc/siena/efx.c  
> b/drivers/net/ethernet/sfc/siena/efx.c
> index 60e5b7c8ccf9..175c999bebc1 100644
> --- a/drivers/net/ethernet/sfc/siena/efx.c
> +++ b/drivers/net/ethernet/sfc/siena/efx.c
> @@ -1048,6 +1048,9 @@ static int efx_pci_probe(struct pci_dev *pci_dev,

>   	pci_info(pci_dev, "Solarflare NIC detected\n");

> +	efx->net_dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	if (!efx->type->is_vf)
>   		efx_probe_vpd_strings(efx);

> diff --git a/drivers/net/ethernet/socionext/netsec.c  
> b/drivers/net/ethernet/socionext/netsec.c
> index 9b46579b5a10..4d6f17efa227 100644
> --- a/drivers/net/ethernet/socionext/netsec.c
> +++ b/drivers/net/ethernet/socionext/netsec.c
> @@ -2104,6 +2104,8 @@ static int netsec_probe(struct platform_device  
> *pdev)
>   				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
>   	ndev->hw_features = ndev->features;

> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;
> +
>   	priv->rx_cksum_offload_flag = true;

>   	ret = netsec_register_mdio(priv, phy_addr);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index c6951c976f5d..316574ce3aa0 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -7145,6 +7145,7 @@ int stmmac_dvr_probe(struct device *device,

>   	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
>   			    NETIF_F_RXCSUM;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ret = stmmac_tc_init(priv, priv);
>   	if (!ret) {
> diff --git a/drivers/net/ethernet/ti/cpsw.c  
> b/drivers/net/ethernet/ti/cpsw.c
> index 13c9c2d6b79b..68b89c56d8b6 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -1458,6 +1458,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv  
> *priv)
>   	priv_sl2->emac_port = 1;
>   	cpsw->slaves[1].ndev = ndev;
>   	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ndev->netdev_ops = &cpsw_netdev_ops;
>   	ndev->ethtool_ops = &cpsw_ethtool_ops;
> @@ -1635,6 +1636,7 @@ static int cpsw_probe(struct platform_device *pdev)
>   	cpsw->slaves[0].ndev = ndev;

>   	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
> +	ndev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	ndev->netdev_ops = &cpsw_netdev_ops;
>   	ndev->ethtool_ops = &cpsw_ethtool_ops;
> diff --git a/drivers/net/ethernet/ti/cpsw_new.c  
> b/drivers/net/ethernet/ti/cpsw_new.c
> index 83596ec0c7cb..1cf8c6202e05 100644
> --- a/drivers/net/ethernet/ti/cpsw_new.c
> +++ b/drivers/net/ethernet/ti/cpsw_new.c
> @@ -1405,6 +1405,9 @@ static int cpsw_create_ports(struct cpsw_common  
> *cpsw)
>   		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
>   				  NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_NETNS_LOCAL | NETIF_F_HW_TC;

> +		ndev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				     NETDEV_XDP_ACT_NDO_XMIT;
> +
>   		ndev->netdev_ops = &cpsw_netdev_ops;
>   		ndev->ethtool_ops = &cpsw_ethtool_ops;
>   		SET_NETDEV_DEV(ndev, dev);
> diff --git a/drivers/net/hyperv/netvsc_drv.c  
> b/drivers/net/hyperv/netvsc_drv.c
> index f9b219e6cd58..c7c1ce6ca201 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -2559,6 +2559,8 @@ static int netvsc_probe(struct hv_device *dev,

>   	netdev_lockdep_set_classes(net);

> +	net->xdp_features = NETDEV_XDP_ACT_FULL;
> +
>   	/* MTU range: 68 - 1500 or 65521 */
>   	net->min_mtu = NETVSC_MTU_MIN;
>   	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
> diff --git a/drivers/net/netdevsim/netdev.c  
> b/drivers/net/netdevsim/netdev.c
> index 6db6a75ff9b9..35fa1ca98671 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -286,6 +286,7 @@ static void nsim_setup(struct net_device *dev)
>   			 NETIF_F_TSO;
>   	dev->hw_features |= NETIF_F_HW_TC;
>   	dev->max_mtu = ETH_MAX_MTU;
> +	dev->xdp_features = NETDEV_XDP_ACT_HW_OFFLOAD;
>   }

>   static int nsim_init_netdevsim(struct netdevsim *ns)
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index a7d17c680f4a..fc041cff75e4 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -1401,6 +1401,10 @@ static void tun_net_initialize(struct net_device  
> *dev)

>   		eth_hw_addr_random(dev);

> +		/* Currently tun does not support XDP, only tap does. */
> +		dev->xdp_features = NETDEV_XDP_ACT_FULL |
> +				    NETDEV_XDP_ACT_NDO_XMIT;
> +
>   		break;
>   	}

> diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> index dfc7d87fad59..01f7b38888a0 100644
> --- a/drivers/net/veth.c
> +++ b/drivers/net/veth.c
> @@ -1649,6 +1649,9 @@ static void veth_setup(struct net_device *dev)
>   	dev->hw_enc_features = VETH_FEATURES;
>   	dev->mpls_features = NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE;
>   	netif_set_tso_max_size(dev, GSO_MAX_SIZE);
> +
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT |
> +			    NETDEV_XDP_ACT_RX_SG | NETDEV_XDP_ACT_NDO_XMIT_SG;
>   }

>   /*
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 7723b2a49d8e..0721dff8c82c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -3155,7 +3155,11 @@ static int virtnet_xdp_set(struct net_device *dev,  
> struct bpf_prog *prog,
>   			if (i == 0 && !old_prog)
>   				virtnet_clear_guest_offloads(vi);
>   		}
> +		if (!old_prog)
> +			__xdp_features_set_redirect_target(&dev->xdp_features,
> +							   NETDEV_XDP_ACT_NDO_XMIT);
>   	} else {
> +		xdp_features_clear_redirect_target(&dev->xdp_features);
>   		vi->xdp_enabled = false;
>   	}

> @@ -3785,6 +3789,7 @@ static int virtnet_probe(struct virtio_device *vdev)
>   		dev->hw_features |= NETIF_F_GRO_HW;

>   	dev->vlan_features = dev->features;
> +	dev->xdp_features = NETDEV_XDP_ACT_FULL;

>   	/* MTU range: 68 - 65535 */
>   	dev->min_mtu = MIN_MTU;
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index 14aec417fa06..58f0cbbadc90 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1741,6 +1741,7 @@ static struct net_device *xennet_create_dev(struct  
> xenbus_device *dev)
>            * negotiate with the backend regarding supported features.
>            */
>   	netdev->features |= netdev->hw_features;
> +	netdev->xdp_features = NETDEV_XDP_ACT_FULL | NETDEV_XDP_ACT_NDO_XMIT;

>   	netdev->ethtool_ops = &xennet_ethtool_ops;
>   	netdev->min_mtu = ETH_MIN_MTU;
> diff --git a/include/net/xdp.h b/include/net/xdp.h
> index 3d37460f0bdb..c3a8f17c0310 100644
> --- a/include/net/xdp.h
> +++ b/include/net/xdp.h
> @@ -410,6 +410,45 @@ struct netdev_bpf;
>   void xdp_attachment_setup(struct xdp_attachment_info *info,
>   			  struct netdev_bpf *bpf);

> +#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
> +
> +static inline void
> +__xdp_features_set_redirect_target(xdp_features_t *xdp_features, u32  
> flags)
> +{
> +	flags &= (NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_NDO_XMIT_SG);
> +	WRITE_ONCE(*xdp_features, *xdp_features | flags);

Maybe stupid question: why do we need WRITE_ONCE here?
And if we do need it, do we need READ_ONCE as well?

WRITE_ONCE(*xdp_features, READ_ONCE(*xdp_features) | flags);

?

Also, would it make sense to drop this __xdp_features_set_redirect_target
and just define the following:

static inline void
xdp_features_set_redirect_target(xdp_features_t *xdp_features, bool  
support_sg)
{
	xdp_features_t flags = NETDEV_XDP_ACT_NDO_XMIT;

	if (support_sg)
		flags |= NETDEV_XDP_ACT_NDO_XMIT_SG;
	*xdp_features |= flags; /* or WRITE_ONCE */
}

This should avoid having two different sets of functions. Or does it
look worse because of that 'naked' true/false argument in the call
sites?


> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +	WRITE_ONCE(*xdp_features,
> +		   *xdp_features & ~(NETDEV_XDP_ACT_NDO_XMIT |
> +				     NETDEV_XDP_ACT_NDO_XMIT_SG));
> +}
> +
> +#else
> +
> +static inline void
> +__xdp_features_set_redirect_target(xdp_features_t *xdp_features, u32  
> flags)
> +{
> +}
> +
> +static inline void
> +xdp_features_clear_redirect_target(xdp_features_t *xdp_features)
> +{
> +}
> +
> +#endif
> +
> +static inline void
> +xdp_features_set_redirect_target(xdp_features_t *xdp_features)
> +{
> +	__xdp_features_set_redirect_target(xdp_features,
> +					   NETDEV_XDP_ACT_NDO_XMIT |
> +					   NETDEV_XDP_ACT_NDO_XMIT_SG);
> +}
> +
>   #define DEV_MAP_BULK_SIZE XDP_BULK_QUEUE_SIZE

>   #endif /* __LINUX_NET_XDP_H__ */
> --
> 2.39.0

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan@osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan


  parent reply	other threads:[~2023-01-18 20:32 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-14 15:54 [RFC v2 bpf-next 0/7] xdp: introduce xdp-feature support Lorenzo Bianconi
2023-01-14 15:54 ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 15:54 ` [RFC v2 bpf-next 1/7] netdev-genl: create a simple family for netdev stuff Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 17:07   ` kernel test robot
2023-01-14 17:17   ` kernel test robot
2023-01-14 15:54 ` [RFC v2 bpf-next 2/7] drivers: net: turn on XDP features Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 17:38   ` kernel test robot
2023-01-17 21:29   ` Niklas Söderlund
2023-01-17 21:29     ` [Intel-wired-lan] " Niklas Söderlund
2023-01-17 21:58     ` Toke Høiland-Jørgensen
2023-01-17 21:58       ` [Intel-wired-lan] " Toke Høiland-Jørgensen
2023-01-17 22:05       ` Niklas Söderlund
2023-01-17 22:05         ` [Intel-wired-lan] " Niklas Söderlund
2023-01-17 22:15         ` Toke Høiland-Jørgensen
2023-01-17 22:15           ` [Intel-wired-lan] " Toke Høiland-Jørgensen
2023-01-17 22:29           ` Niklas Söderlund
2023-01-17 22:29             ` [Intel-wired-lan] " Niklas Söderlund
2023-01-17 22:42             ` Toke Høiland-Jørgensen
2023-01-17 22:42               ` [Intel-wired-lan] " Toke Høiland-Jørgensen
2023-01-17 23:45     ` Lorenzo Bianconi
2023-01-17 23:45       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-18  8:50       ` Niklas Söderlund
2023-01-18  8:50         ` [Intel-wired-lan] " Niklas Söderlund
2023-01-18  9:38         ` Lorenzo Bianconi
2023-01-18  9:38           ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-18 20:30   ` sdf [this message]
2023-01-18 20:30     ` sdf
2023-01-19 14:23     ` Lorenzo Bianconi
2023-01-19 14:23       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 15:54 ` [RFC v2 bpf-next 3/7] xsk: add usage of XDP features flags Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-17 22:07   ` Yonghong Song
2023-01-17 22:07     ` [Intel-wired-lan] " Yonghong Song
2023-01-17 23:34     ` Lorenzo Bianconi
2023-01-17 23:34       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-17 23:37       ` Yonghong Song
2023-01-17 23:37         ` [Intel-wired-lan] " Yonghong Song
2023-01-14 15:54 ` [RFC v2 bpf-next 4/7] libbpf: add the capability to specify netlink proto in libbpf_netlink_send_recv Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 15:54 ` [RFC v2 bpf-next 5/7] libbpf: add API to get XDP/XSK supported features Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-18  0:58   ` Jakub Kicinski
2023-01-18  0:58     ` [Intel-wired-lan] " Jakub Kicinski
2023-01-19 22:39     ` Lorenzo Bianconi
2023-01-19 22:39       ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 15:54 ` [RFC v2 bpf-next 6/7] bpf: devmap: check XDP features in bpf_map_update_elem and __xdp_enqueue Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
2023-01-14 15:54 ` [RFC v2 bpf-next 7/7] selftests/bpf: introduce XDP compliance test tool Lorenzo Bianconi
2023-01-14 15:54   ` [Intel-wired-lan] " Lorenzo Bianconi
  -- strict thread matches above, loose matches on Subject: below --
2023-01-15  0:22 [RFC v2 bpf-next 1/7] netdev-genl: create a simple family for netdev stuff kernel test robot
2023-01-16  9:04 ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y8hW8IqJTa0zE2aS@google.com \
    --to=sdf@google.com \
    --cc=aelior@marvell.com \
    --cc=alardam@gmail.com \
    --cc=andrii@kernel.org \
    --cc=anthony.l.nguyen@intel.com \
    --cc=ast@kernel.org \
    --cc=bjorn@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=christophe.jaillet@wanadoo.fr \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=edumazet@google.com \
    --cc=gospo@broadcom.com \
    --cc=hawk@kernel.org \
    --cc=intel-wired-lan@lists.osuosl.org \
    --cc=john@phrozen.org \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=lorenzo.bianconi@redhat.com \
    --cc=lorenzo@kernel.org \
    --cc=maciej.fijalkowski@intel.com \
    --cc=magnus.karlsson@intel.com \
    --cc=memxor@gmail.com \
    --cc=mst@redhat.com \
    --cc=nbd@nbd.name \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=saeedm@nvidia.com \
    --cc=simon.horman@corigine.com \
    --cc=toke@redhat.com \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.