mvneta: introduce XDP multi-buffer support
Subsystems (24)
cover mvneta: introduce XDP multi-buffer support
Finalize XDP multi-buffer support for mvneta driver introducing the capability to map non-linear buffers on tx side.
Introduce multi-buffer bit (mb) in xdp_frame/xdp_buffer to specify if shared_info area has been properly initialized.
Initialize multi-buffer bit (mb) to 0 in all XDP-capable drivers. Add multi-buff support to xdp_return_{buff/frame} utility routines.
Changes since RFC:
- squash multi-buffer bit initialization in a single patch
- add mvneta non-linear XDP buff support for tx side
Lorenzo Bianconi (6):
xdp: introduce mb in xdp_buff/xdp_frame
xdp: initialize xdp_buff mb bit to 0 in all XDP drivers
net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
xdp: add multi-buff support to xdp_return_{buff/frame}
net: mvneta: add multi buffer support to XDP_TX
net: mvneta: enable jumbo frames for XDP
drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 1 + .../net/ethernet/cavium/thunder/nicvf_main.c | 1 + .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 1 + drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + drivers/net/ethernet/intel/ice/ice_txrx.c | 1 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + drivers/net/ethernet/marvell/mvneta.c | 92 +++++++++++-------- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 + drivers/net/ethernet/mellanox/mlx4/en_rx.c | 1 + .../net/ethernet/mellanox/mlx5/core/en_rx.c | 1 + .../ethernet/netronome/nfp/nfp_net_common.c | 1 + drivers/net/ethernet/qlogic/qede/qede_fp.c | 1 + drivers/net/ethernet/sfc/rx.c | 1 + drivers/net/ethernet/socionext/netsec.c | 1 + drivers/net/ethernet/ti/cpsw.c | 1 + drivers/net/ethernet/ti/cpsw_new.c | 1 + drivers/net/hyperv/netvsc_bpf.c | 1 + drivers/net/tun.c | 2 + drivers/net/veth.c | 1 + drivers/net/virtio_net.c | 2 + drivers/net/xen-netfront.c | 1 + include/net/xdp.h | 25 ++++- net/core/dev.c | 1 + net/core/xdp.c | 37 ++++++++ 26 files changed, 135 insertions(+), 44 deletions(-)
Signature · 1 line
2.26.2
PATCH 1/6 xdp: introduce mb in xdp_buff/xdp_frame
Introduce multi-buffer bit (mb) in xdp_frame/xdp_buffer to specify if shared_info area has been properly initialized for non-linear xdp buffers
--- include/net/xdp.h | 8 ++++++-- net/core/xdp.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
include/net/xdp.h +6 -2
@@ -72,7 +72,8 @@ struct xdp_buff {void *data_hard_start;struct xdp_rxq_info *rxq;struct xdp_txq_info *txq; -u32 frame_sz;/* frame size to deduce data_hard_end/reserved tailroom*/ + u32 frame_sz:31; /* frame size to deduce data_hard_end/reserved tailroom*/ + u32 mb:1; /* xdp non-linear buffer */ };/* Reserve memory area at end-of data area.
@@ -96,7 +97,8 @@ struct xdp_frame {u16 len;u16 headroom; u32 metasize:8; - u32 frame_sz:24; + u32 frame_sz:23; + u32 mb:1; /* xdp non-linear frame *//* Lifetime of xdp_rxq_info is limited to NAPI/enqueue time, * while mem info is valid on remote CPU. */
@@ -141,6 +143,7 @@ void xdp_convert_frame_to_buff(struct xdp_frame *frame, struct xdp_buff *xdp) xdp->data_end = frame->data + frame->len; xdp->data_meta = frame->data - frame->metasize; xdp->frame_sz = frame->frame_sz; + xdp->mb = frame->mb; } static inline
@@ -167,6 +170,7 @@ int xdp_update_frame_from_buff(struct xdp_buff *xdp, xdp_frame->headroom = headroom -sizeof (*xdp_frame); xdp_frame->metasize = metasize; xdp_frame->frame_sz = xdp->frame_sz; + xdp_frame->mb = xdp->mb;return 0 ; }
net/core/xdp.c +1 -0
@@ -454,6 +454,7 @@ struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp) xdpf->headroom =0 ; xdpf->metasize = metasize; xdpf->frame_sz =PAGE_SIZE ; + xdpf->mb = xdp->mb; xdpf->mem.type =MEM_TYPE_PAGE_ORDER0 ;xsk_buff_free (xdp);
Signature · 1 line
2.26.2
Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
Quoted 27 lines · Lorenzo Bianconi
Introduce multi-buffer bit (mb) in xdp_frame/xdp_buffer to specify if
shared_infoarea has been properly initialized for non-linear xdp buffersSigned-off-by Lorenzo Bianconi <[email protected]>--- include/net/xdp.h | 8 ++++++-- net/core/xdp.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)include/net/xdp.h +0
-1@@ -72,7 +72,8 @@ struct xdp_buff {void *data_hard_start;struct xdp_rxq_info *rxq;struct xdp_txq_info *txq; -u32 frame_sz;/* frame size to deduce data_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 frame_sz:31; /* frame size to deducedata_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 mb:1; /* xdp non-linear buffer */ };/* Reserve memory area at end-of data area.
include/net/xdp.h struct xdp_frame { · line 101
Quoted 6 lines
include/net/xdp.h +2
-1@@ -96,7 +97,8 @@ struct xdp_frame {u16 len;u16 headroom; u32 metasize:8; - u32 frame_sz:24; + u32 frame_sz:23; + u32 mb:1; /* xdp non-linear frame */
Although this issue wasn't introduced with this patch, why not make frame_sz field to be the same size in xdp_buff and xdp_frame ?
thanks,
Shay
Quoted 35 lines
include/net/xdp.h +0
-0/* Lifetime of xdp_rxq_info is limited to NAPI/enqueue time, * while mem info is valid on remote CPU. include/net/xdp.h +1
-0*/ @@ -141,6 +143,7 @@ void xdp_convert_frame_to_buff(struct xdp_frame *frame, struct xdp_buff *xdp) xdp->data_end = frame->data + frame->len; xdp->data_meta = frame->data - frame->metasize; xdp->frame_sz = frame->frame_sz; + xdp->mb = frame->mb; }static inline
include/net/xdp.h +1
-0@@ -167,6 +170,7 @@ int xdp_update_frame_from_buff(struct xdp_buff *xdp, xdp_frame->headroom = headroom -sizeof (*xdp_frame); xdp_frame->metasize = metasize; xdp_frame->frame_sz = xdp->frame_sz; + xdp_frame->mb = xdp->mb;return 0 ;}
net/core/xdp.c +1
-0@@ -454,6 +454,7 @@ struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp) xdpf->headroom = 0; xdpf->metasize = metasize; xdpf->frame_sz =PAGE_SIZE ; + xdpf->mb = xdp->mb; xdpf->mem.type =MEM_TYPE_PAGE_ORDER0 ;
xsk_buff_free(xdp);
Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
Quoted 15 lines · On Sun, 23 Aug 2020 17:08:30 +0300 Shay Agroskin <[email protected]> wrote:
Quoted 15 lines
include/net/xdp.h +0
-1@@ -72,7 +72,8 @@ struct xdp_buff {void *data_hard_start;struct xdp_rxq_info *rxq;struct xdp_txq_info *txq; -u32 frame_sz;/* frame size to deduce data_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 frame_sz:31; /* frame size to deducedata_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 mb:1; /* xdp non-linear buffer */ };
Quoted 12 lines
include/net/xdp.h struct xdp_frame { · line 101
Quoted 8 lines
/* Reserve memory area at end-of data area.
include/net/xdp.h +2
-1@@ -96,7 +97,8 @@ struct xdp_frame {u16 len;u16 headroom; u32 metasize:8; - u32 frame_sz:24; + u32 frame_sz:23; + u32 mb:1; /* xdp non-linear frame */Although this issue wasn't introduced with this patch, why not make
frame_szfield to be the same size inxdp_buffandxdp_frame?
This is all about struct layout and saving memory size, due to cacheline access. Please read up on this and use the tool pahole to inspect the struct memory layout.
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
Quoted 29 lines · Jesper Dangaard Brouer
Quoted 15 lines · On Sun, 23 Aug 2020 17:08:30 +0300 Shay Agroskin <[email protected]> wrote:
Quoted 15 lines
include/net/xdp.h +0
-1@@ -72,7 +72,8 @@ struct xdp_buff {void *data_hard_start;struct xdp_rxq_info *rxq;struct xdp_txq_info *txq; -u32 frame_sz;/* frame size to deduce data_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 frame_sz:31; /* frame size to deducedata_hard_end/reserved tailroom*/
include/net/xdp.h +1
-0+ u32 mb:1; /* xdp non-linear buffer */ };Quoted 10 lines
include/net/xdp.h struct xdp_frame { · line 101
Quoted 8 lines
/* Reserve memory area at end-of data area.
include/net/xdp.h +2
-1@@ -96,7 +97,8 @@ struct xdp_frame {u16 len;u16 headroom; u32 metasize:8; - u32 frame_sz:24; + u32 frame_sz:23; + u32 mb:1; /* xdp non-linear frame */Although this issue wasn't introduced with this patch, why not make
frame_szfield to be the same size inxdp_buffandxdp_frame?
Quoted 3 lines
This is all about struct layout and saving memory size, due to cacheline access. Please read up on this and use the tool pahole to inspect the struct memory layout.
I actually meant reducing the size of frame_sz in xdp_buff (without changing xdp_frame so that it still fits 64 byte cache line). Reducing a field size shouldn't affect cache alignment as far as I can see. Doesn't matter all that much to me, I simply find it a better practice that the same field would have same size in different structs.
Shay
PATCH 2/6 xdp: initialize xdp_buff mb bit to 0 in all XDP drivers
In reply to Lorenzo BianconiInitialize multi-buffer bit (mb) to 0 in all XDP-capable drivers. This is a preliminary patch to enable xdp multi-buffer support.
--- drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 1 + drivers/net/ethernet/cavium/thunder/nicvf_main.c | 1 + drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 1 + drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + drivers/net/ethernet/intel/ice/ice_txrx.c | 1 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 + drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 1 + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 + drivers/net/ethernet/mellanox/mlx4/en_rx.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 1 + drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 1 + drivers/net/ethernet/qlogic/qede/qede_fp.c | 1 + drivers/net/ethernet/sfc/rx.c | 1 + drivers/net/ethernet/socionext/netsec.c | 1 + drivers/net/ethernet/ti/cpsw.c | 1 + drivers/net/ethernet/ti/cpsw_new.c | 1 + drivers/net/hyperv/netvsc_bpf.c | 1 + drivers/net/tun.c | 2 ++ drivers/net/veth.c | 1 + drivers/net/virtio_net.c | 2 ++ drivers/net/xen-netfront.c | 1 + net/core/dev.c | 1 + 23 files changed, 25 insertions(+)
drivers/net/ethernet/amazon/ena/ena_netdev.c +1 -0
@@ -1607,6 +1607,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, res_budget = budget; xdp.rxq = &rx_ring->xdp_rxq; xdp.frame_sz =ENA_PAGE_SIZE ; + xdp.mb =0 ; do { xdp_verdict = XDP_PASS;
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +1 -0
@@ -139,6 +139,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons, xdp.data_end = *data_ptr + *len; xdp.rxq = &rxr->xdp_rxq; xdp.frame_sz =PAGE_SIZE ;/* BNXT_RX_PAGE_MODE(bp) when XDP enabled */ + xdp.mb =0 ; orig_data = xdp.data;rcu_read_lock ();
drivers/net/ethernet/cavium/thunder/nicvf_main.c +1 -0
@@ -553,6 +553,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, xdp.data_end = xdp.data + len; xdp.rxq = &rq->xdp_rxq; xdp.frame_sz =RCV_FRAG_LEN +XDP_PACKET_HEADROOM ; + xdp.mb =0 ; orig_data = xdp.data;rcu_read_lock ();
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +1 -0
@@ -361,6 +361,7 @@ static u32 run_xdp(struct dpaa2_eth_priv *priv, xdp.frame_sz =DPAA2_ETH_RX_BUF_RAW_SIZE - (dpaa2_fd_get_offset (fd) -XDP_PACKET_HEADROOM ); + xdp.mb =0 ; xdp_act =bpf_prog_run_xdp (xdp_prog, &xdp);
drivers/net/ethernet/intel/i40e/i40e_txrx.c +1 -0
@@ -2324,6 +2324,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) xdp.frame_sz =i40e_rx_frame_truesize (rx_ring,0 );#endif xdp.rxq = &rx_ring->xdp_rxq; + xdp.mb =0 ;while (likely (total_rx_packets < (unsigned int )budget)) {struct i40e_rx_buffer *rx_buffer;
drivers/net/ethernet/intel/ice/ice_txrx.c +1 -0
@@ -1095,6 +1095,7 @@ int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)#if (PAGE_SIZE <8192 ) xdp.frame_sz =ice_rx_frame_truesize (rx_ring,0 );#endif + xdp.mb =0 ;/* start the loop to process Rx packets bounded by 'budget' */ while (likely (total_rx_pkts < (unsigned int )budget)) {
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1 -0
@@ -2303,6 +2303,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,#if (PAGE_SIZE <8192 ) xdp.frame_sz =ixgbe_rx_frame_truesize (rx_ring,0 );#endif + xdp.mb =0 ;while (likely (total_rx_packets < budget)) {union ixgbe_adv_rx_desc *rx_desc;
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +1 -0
@@ -1133,6 +1133,7 @@ static int ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,struct xdp_buff xdp; xdp.rxq = &rx_ring->xdp_rxq; + xdp.mb =0 ;/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */ #if (PAGE_SIZE <8192 )
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +1 -0
@@ -3475,6 +3475,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, xdp.data = data +MVPP2_MH_SIZE +MVPP2_SKB_HEADROOM ; xdp.data_end = xdp.data + rx_bytes; xdp.frame_sz =PAGE_SIZE ; + xdp.mb =0 ;if (bm_pool->pkt_size ==MVPP2_BM_SHORT_PKT_SIZE ) xdp.rxq = &rxq->xdp_rxq_short;
drivers/net/ethernet/mellanox/mlx4/en_rx.c +1 -0
@@ -684,6 +684,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud xdp_prog =rcu_dereference (ring->xdp_prog); xdp.rxq = &ring->xdp_rxq; xdp.frame_sz = priv->frag_info[0 ].frag_stride; + xdp.mb =0 ; doorbell_pending =0 ;/* We assume a 1:1 mapping between CQEs and Rx descriptors, so Rx
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +1 -0
@@ -1121,6 +1121,7 @@ static void mlx5e_fill_xdp_buff(struct mlx5e_rq *rq, void *va, u16 headroom, xdp->data_end = xdp->data + len; xdp->rxq = &rq->xdp_rxq; xdp->frame_sz = rq->buff.frame0_sz; + xdp->mb =0 ; } static struct sk_buff *
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +1 -0
@@ -1824,6 +1824,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) true_bufsz = xdp_prog ?PAGE_SIZE : dp->fl_bufsz; xdp.frame_sz =PAGE_SIZE -NFP_NET_RX_BUF_HEADROOM ; xdp.rxq = &rx_ring->xdp_rxq; + xdp.mb =0 ; tx_ring = r_vec->xdp_ring;while (pkts_polled < budget) {
drivers/net/ethernet/qlogic/qede/qede_fp.c +1 -0
@@ -1096,6 +1096,7 @@ static bool qede_rx_xdp(struct qede_dev *edev, xdp.data_end = xdp.data + *len; xdp.rxq = &rxq->xdp_rxq; xdp.frame_sz = rxq->rx_buf_seg_size;/* PAGE_SIZE when XDP enabled */ + xdp.mb =0 ;/* Queues always have a full reset currently, so for the time * being until there's atomic program replace just mark read
drivers/net/ethernet/sfc/rx.c +1 -0
@@ -301,6 +301,7 @@ static bool efx_do_xdp(struct efx_nic *efx, struct efx_channel *channel, xdp.data_end = xdp.data + rx_buf->len; xdp.rxq = &rx_queue->xdp_rxq_info; xdp.frame_sz = efx->rx_page_buf_step; + xdp.mb =0 ; xdp_act =bpf_prog_run_xdp (xdp_prog, &xdp);rcu_read_unlock ();
drivers/net/ethernet/socionext/netsec.c +1 -0
@@ -947,6 +947,7 @@ static int netsec_process_rx(struct netsec_priv *priv, int budget) xdp.rxq = &dring->xdp_rxq; xdp.frame_sz =PAGE_SIZE ; + xdp.mb =0 ;rcu_read_lock (); xdp_prog =READ_ONCE (priv->xdp_prog);
drivers/net/ethernet/ti/cpsw.c +1 -0
@@ -407,6 +407,7 @@ static void cpsw_rx_handler(void *token, int len, int status) xdp.data_hard_start = pa; xdp.rxq = &priv->xdp_rxq[ch]; xdp.frame_sz =PAGE_SIZE ; + xdp.mb =0 ; port = priv->emac_port + cpsw->data.dual_emac; ret =cpsw_run_xdp (priv, ch, &xdp, page, port);
drivers/net/ethernet/ti/cpsw_new.c +1 -0
@@ -349,6 +349,7 @@ static void cpsw_rx_handler(void *token, int len, int status) xdp.data_hard_start = pa; xdp.rxq = &priv->xdp_rxq[ch]; xdp.frame_sz =PAGE_SIZE ; + xdp.mb =0 ; ret =cpsw_run_xdp (priv, ch, &xdp, page, priv->emac_port);if (ret !=CPSW_XDP_PASS )
drivers/net/hyperv/netvsc_bpf.c +1 -0
@@ -50,6 +50,7 @@ u32 netvsc_run_xdp(struct net_device *ndev, struct netvsc_channel *nvchan, xdp->data_end = xdp->data + len; xdp->rxq = &nvchan->xdp_rxq; xdp->frame_sz =PAGE_SIZE ; + xdp->mb =0 ;memcpy (xdp->data, data, len);
drivers/net/tun.c +2 -0
@@ -1659,6 +1659,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, xdp.data_end = xdp.data + len; xdp.rxq = &tfile->xdp_rxq; xdp.frame_sz = buflen; + xdp.mb =0 ; act =bpf_prog_run_xdp (xdp_prog, &xdp);if (act ==XDP_REDIRECT || act ==XDP_TX ) {
@@ -2406,6 +2407,7 @@ static int tun_xdp_one(struct tun_struct *tun,xdp_set_data_meta_invalid (xdp); xdp->rxq = &tfile->xdp_rxq; xdp->frame_sz = buflen; + xdp->mb =0 ; act =bpf_prog_run_xdp (xdp_prog, xdp); err =tun_xdp_act (tun, xdp_prog, xdp, act);
drivers/net/veth.c +1 -0
@@ -711,6 +711,7 @@ static struct sk_buff *veth_xdp_rcv_skb(struct veth_rq *rq,/* SKB "head" area always have tailroom for skb_shared_info */ xdp.frame_sz = (void *)skb_end_pointer (skb) - xdp.data_hard_start; xdp.frame_sz +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); + xdp.mb =0 ; orig_data = xdp.data; orig_data_end = xdp.data_end;
drivers/net/virtio_net.c +2 -0
@@ -690,6 +690,7 @@ static struct sk_buff *receive_small(struct net_device *dev, xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; xdp.frame_sz = buflen; + xdp.mb =0 ; orig_data = xdp.data; act =bpf_prog_run_xdp (xdp_prog, &xdp); stats->xdp_packets++;
@@ -860,6 +861,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; xdp.frame_sz = frame_sz - vi->hdr_len; + xdp.mb =0 ; act =bpf_prog_run_xdp (xdp_prog, &xdp); stats->xdp_packets++;
drivers/net/xen-netfront.c +1 -0
@@ -870,6 +870,7 @@ static u32 xennet_run_xdp(struct netfront_queue *queue, struct page *pdata, xdp->data_end = xdp->data + len; xdp->rxq = &queue->xdp_rxq; xdp->frame_sz =XEN_PAGE_SIZE -XDP_PACKET_HEADROOM ; + xdp->mb =0 ; act =bpf_prog_run_xdp (prog, xdp);switch (act) {
net/core/dev.c +1 -0
@@ -4639,6 +4639,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,/* SKB "head" area always have tailroom for skb_shared_info */ xdp->frame_sz = (void *)skb_end_pointer (skb) - xdp->data_hard_start; xdp->frame_sz +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); + xdp->mb =0 ; orig_data_end = xdp->data_end; orig_data = xdp->data;
Signature · 1 line
2.26.2
PATCH 3/6 net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
In reply to Lorenzo BianconiUpdate multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP buffer
--- drivers/net/ethernet/marvell/mvneta.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/marvell/mvneta.c +3 -0
@@ -2170,11 +2170,14 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, struct bpf_prog *prog, struct xdp_buff *xdp, u32 frame_sz, struct mvneta_stats *stats) { + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);unsigned int len, data_len, sync;u32 ret, act; len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction; data_len = xdp->data_end - xdp->data; + + xdp->mb = !!sinfo->nr_frags; act =bpf_prog_run_xdp (prog, xdp);/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
Signature · 1 line
2.26.2
Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
Quoted 15 lines · On Wed, 19 Aug 2020 15:13:48 +0200 Lorenzo Bianconi <[email protected]> wrote:
Update multi-buffer bit (mb) in
xdp_buffto notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP bufferSigned-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/marvell/mvneta.c | 3 +++ 1 file changed, 3 insertions(+)drivers/net/ethernet/marvell/mvneta.c +0
-0@@ -2170,11 +2170,14 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, struct bpf_prog *prog, struct xdp_buff *xdp, u32 frame_sz, struct mvneta_stats *stats)
drivers/net/ethernet/marvell/mvneta.c mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, · line 2181
Quoted 10 lines
drivers/net/ethernet/marvell/mvneta.c +3
-0{ +struct skb_shared_info *sinfo =xdp_get_shared_info_from_buff (xdp);unsigned int len, data_len, sync;u32 ret, act; len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction; data_len = xdp->data_end - xdp->data; + + xdp->mb = !!sinfo->nr_frags; act =bpf_prog_run_xdp (prog, xdp);
Reading the memory sinfo->nr_frags could be a performance issue for our baseline case of no-multi-buffer. As you are reading a cache-line that you don't need to (and driver have not touch yet).
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
Quoted 23 lines
Quoted 20 lines · On Wed, 19 Aug 2020 15:13:48 +0200 Lorenzo Bianconi <[email protected]> wrote:
Update multi-buffer bit (mb) in
xdp_buffto notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP bufferSigned-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/marvell/mvneta.c | 3 +++ 1 file changed, 3 insertions(+)drivers/net/ethernet/marvell/mvneta.c +1
-0@@ -2170,11 +2170,14 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, struct bpf_prog *prog, struct xdp_buff *xdp, u32 frame_sz, struct mvneta_stats *stats) { + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);unsigned int len, data_len, sync;u32 ret, act;
Quoted 9 lines
drivers/net/ethernet/marvell/mvneta.c mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, · line 2181
Quoted 5 lines
drivers/net/ethernet/marvell/mvneta.c +2
-0len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction; data_len = xdp->data_end - xdp->data; + + xdp->mb = !!sinfo->nr_frags; act =bpf_prog_run_xdp (prog, xdp);Reading the memory
sinfo->nr_fragscould be a performance issue for our baseline case of no-multi-buffer. As you are reading a cache-line that you don't need to (and driver have not touch yet).
ack, I will rework it in v2 to remove this access.
Regards,
Lorenzo
Quoted 7 lines
Signature · 5 lines
-- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
In reply to Lorenzo BianconiQuoted 14 lines · Lorenzo Bianconi
Update multi-buffer bit (mb) in
xdp_buffto notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP bufferSigned-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/marvell/mvneta.c | 3 +++ 1 file changed, 3 insertions(+)drivers/net/ethernet/marvell/mvneta.c +0
-0@@ -2170,11 +2170,14 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, struct bpf_prog *prog, struct xdp_buff *xdp,
drivers/net/ethernet/marvell/mvneta.c mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, · line 2180
Quoted 10 lines
drivers/net/ethernet/marvell/mvneta.c +3
-0u32 frame_sz, struct mvneta_stats *stats) { + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);unsigned int len, data_len, sync;u32 ret, act; len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction; data_len = xdp->data_end - xdp->data; + + xdp->mb = !!sinfo->nr_frags;
But this set is not utilizing it from BPF side in any way. Personally I would like to see this as a part of work where BPF program would actually be taught how to rely on xdp->mb. Especially after John's comment in other patch.
Quoted 6 lines
drivers/net/ethernet/marvell/mvneta.c +0
-0act =bpf_prog_run_xdp (prog, xdp);/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */ Signature · 1 line
2.26.2
Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
Quoted 21 lines · Maciej Fijalkowski
Quoted 20 lines · Lorenzo Bianconi
Update multi-buffer bit (mb) in
xdp_buffto notify XDP/eBPF layer and XDP remote drivers if this is a "non-linear" XDP bufferSigned-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/ethernet/marvell/mvneta.c | 3 +++ 1 file changed, 3 insertions(+)drivers/net/ethernet/marvell/mvneta.c +1
-0@@ -2170,11 +2170,14 @@ mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, struct bpf_prog *prog, struct xdp_buff *xdp, u32 frame_sz, struct mvneta_stats *stats) { + struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);unsigned int len, data_len, sync;u32 ret, act;
Quoted 10 lines
drivers/net/ethernet/marvell/mvneta.c mvneta_run_xdp(struct mvneta_port *pp, struct mvneta_rx_queue *rxq, · line 2180
Quoted 4 lines
drivers/net/ethernet/marvell/mvneta.c +2
-0len = xdp->data_end - xdp->data_hard_start - pp->rx_offset_correction; data_len = xdp->data_end - xdp->data; + + xdp->mb = !!sinfo->nr_frags;But this set is not utilizing it from BPF side in any way. Personally I would like to see this as a part of work where BPF program would actually be taught how to rely on
xdp->mb. Especially after John's comment in other patch.
Sameeh is working on them. I did not include the patches since IMO they are not strictly related to this series. I will include Sameeh's patches in v2.
Regards,
Lorenzo
Quoted 7 lines
Quoted 6 lines
drivers/net/ethernet/marvell/mvneta.c +0
-0act =bpf_prog_run_xdp (prog, xdp);/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */ Signature · 1 line
2.26.2
PATCH 4/6 xdp: add multi-buff support to xdp_return_{buff/frame}
In reply to Lorenzo BianconiTake into account if the received xdp_buff/xdp_frame is non-linear recycling/returning the frame memory to the allocator
--- include/net/xdp.h | 17 +++++++++++++++-- net/core/xdp.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-)
include/net/xdp.h +15 -2
@@ -208,10 +208,23 @@ void __xdp_release_frame(void *data, struct xdp_mem_info *mem);static inline void xdp_release_frame (struct xdp_frame *xdpf) {struct xdp_mem_info *mem = &xdpf->mem; +struct skb_shared_info *sinfo; +int i;/* Curr only page_pool needs this */ -if (mem->type ==MEM_TYPE_PAGE_POOL ) -__xdp_release_frame (xdpf->data, mem); +if (mem->type !=MEM_TYPE_PAGE_POOL ) +return ; + +__xdp_release_frame (xdpf->data, mem); +if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_release_frame (page_address (page), mem); + } } int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
net/core/xdp.c +36 -0
@@ -370,19 +370,55 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct)void xdp_return_frame (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, false); +if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, false); + } }EXPORT_SYMBOL_GPL (xdp_return_frame);void xdp_return_frame_rx_napi (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, true); +if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, true); + } }EXPORT_SYMBOL_GPL (xdp_return_frame_rx_napi);void xdp_return_buff (struct xdp_buff *xdp) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdp->data, &xdp->rxq->mem, true); +if (!xdp->mb) +return ; + + sinfo =xdp_get_shared_info_from_buff (xdp); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdp->rxq->mem, true); + } }/* Only called for MEM_TYPE_PAGE_POOL see xdp.h */
Signature · 1 line
2.26.2
Re: [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame}
net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 376
Quoted 12 lines · On Wed, 19 Aug 2020 15:13:49 +0200 Lorenzo Bianconi <[email protected]> wrote:
net/core/xdp.c +3
-0@@ -370,19 +370,55 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct)void xdp_return_frame (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, false);
There is a use-after-free race here. The xdpf->data contains the shared_info (xdp_get_shared_info_from_frame(xdpf)). Thus you cannot free/return the page and use this data area below.
Quoted 8 lines
net/core/xdp.c +8
-0+if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, false);
net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 394
Quoted 10 lines
net/core/xdp.c +4
-0+ } }EXPORT_SYMBOL_GPL (xdp_return_frame);void xdp_return_frame_rx_napi (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, true);
Same issue.
Quoted 8 lines
net/core/xdp.c +8
-0+if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, true);
net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 412
Quoted 10 lines
net/core/xdp.c +4
-0+ } }EXPORT_SYMBOL_GPL (xdp_return_frame_rx_napi);void xdp_return_buff (struct xdp_buff *xdp) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdp->data, &xdp->rxq->mem, true);
Same issue.
Quoted 10 lines
net/core/xdp.c +9
-0+if (!xdp->mb) +return ; + + sinfo =xdp_get_shared_info_from_buff (xdp); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdp->rxq->mem, true); + } }
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame}
Quoted 9 lines
Quoted 6 lines · On Wed, 19 Aug 2020 15:13:49 +0200 Lorenzo Bianconi <[email protected]> wrote:
net/core/xdp.c +0
-0@@ -370,19 +370,55 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct)
Quoted 10 lines
net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 376
Quoted 6 lines
net/core/xdp.c +3
-0void xdp_return_frame (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, false);There is a use-after-free race here. The
xdpf->datacontains theshared_info(xdp_get_shared_info_from_frame(xdpf)). Thus you cannot free/return the page and use this data area below.
right, thx for pointing this out. I will fix it in v2.
Regards,
Lorenzo
Quoted 62 lines
Quoted 9 lines
net/core/xdp.c +8
-0+if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, false);net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 394
Quoted 10 lines
net/core/xdp.c +4
-0+ } }EXPORT_SYMBOL_GPL (xdp_return_frame);void xdp_return_frame_rx_napi (struct xdp_frame *xdpf) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdpf->data, &xdpf->mem, true);Same issue.
Quoted 8 lines
net/core/xdp.c +8
-0+if (!xdpf->mb) +return ; + + sinfo =xdp_get_shared_info_from_frame (xdpf); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdpf->mem, true);net/core/xdp.c static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct) · line 412
Quoted 10 lines
net/core/xdp.c +4
-0+ } }EXPORT_SYMBOL_GPL (xdp_return_frame_rx_napi);void xdp_return_buff (struct xdp_buff *xdp) { +struct skb_shared_info *sinfo; +int i; +__xdp_return (xdp->data, &xdp->rxq->mem, true);Same issue.
Quoted 10 lines
net/core/xdp.c +9
-0+if (!xdp->mb) +return ; + + sinfo =xdp_get_shared_info_from_buff (xdp); +for (i =0 ; i < sinfo->nr_frags; i++) { +struct page *page =skb_frag_page (&sinfo->frags[i]); + +__xdp_return (page_address (page), &xdp->rxq->mem, true); + } }Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
PATCH 5/6 net: mvneta: add multi buffer support to XDP_TX
In reply to Lorenzo BianconiIntroduce the capability to map non-linear xdp buffer running mvneta_xdp_submit_frame() for XDP_TX and XDP_REDIRECT
--- drivers/net/ethernet/marvell/mvneta.c | 79 +++++++++++++++++---------- 1 file changed, 49 insertions(+), 30 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +49 -30
@@ -1854,8 +1854,8 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp, bytes_compl += buf->skb->len; pkts_compl++;dev_kfree_skb_any (buf->skb); - }else if (buf->type ==MVNETA_TYPE_XDP_TX || - buf->type ==MVNETA_TYPE_XDP_NDO ) { + }else if ((buf->type ==MVNETA_TYPE_XDP_TX || + buf->type ==MVNETA_TYPE_XDP_NDO ) && buf->xdpf) {xdp_return_frame (buf->xdpf); } }
@@ -2040,43 +2040,62 @@ static int mvneta_xdp_submit_frame(struct mvneta_port *pp, struct mvneta_tx_queue *txq, struct xdp_frame *xdpf, bool dma_map) { - struct mvneta_tx_desc *tx_desc; -struct mvneta_tx_buf *buf; -dma_addr_t dma_addr; + struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); +int i, num_frames = xdpf->mb ? sinfo->nr_frags +1 :1 ; +struct mvneta_tx_desc *tx_desc =NULL ; +struct page *page; -if (txq->count >= txq->tx_stop_threshold) +if (txq->count + num_frames >= txq->tx_stop_threshold)return MVNETA_XDP_DROPPED ; - tx_desc =mvneta_txq_next_desc_get (txq); +for (i =0 ; i < num_frames; i++) { +struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; +skb_frag_t *frag = i ? &sinfo->frags[i -1 ] :NULL ; +int len = frag ?skb_frag_size (frag) : xdpf->len; +dma_addr_t dma_addr; - buf = &txq->buf[txq->txq_put_index]; -if (dma_map) { -/* ndo_xdp_xmit */ - dma_addr =dma_map_single (pp->dev->dev.parent, xdpf->data, - xdpf->len,DMA_TO_DEVICE ); -if (dma_mapping_error (pp->dev->dev.parent, dma_addr)) { -mvneta_txq_desc_put (txq); -return MVNETA_XDP_DROPPED ; + tx_desc =mvneta_txq_next_desc_get (txq); +if (dma_map) { +/* ndo_xdp_xmit */ +void *data; + + data = frag ?page_address (skb_frag_page (frag)) + : xdpf->data; + dma_addr =dma_map_single (pp->dev->dev.parent, data, + len,DMA_TO_DEVICE ); +if (dma_mapping_error (pp->dev->dev.parent, dma_addr)) { +for (; i >=0 ; i--) +mvneta_txq_desc_put (txq); +return MVNETA_XDP_DROPPED ; + } + buf->type =MVNETA_TYPE_XDP_NDO ; + }else { + page = frag ?skb_frag_page (frag) + :virt_to_page (xdpf->data); + dma_addr =page_pool_get_dma_addr (page); +if (!frag) + dma_addr +=sizeof (*xdpf) + xdpf->headroom; +dma_sync_single_for_device (pp->dev->dev.parent, + dma_addr, len, +DMA_BIDIRECTIONAL ); + buf->type =MVNETA_TYPE_XDP_TX ; } - buf->type =MVNETA_TYPE_XDP_NDO ; - }else { -struct page *page =virt_to_page (xdpf->data); + buf->xdpf = i ?NULL : xdpf; - dma_addr =page_pool_get_dma_addr (page) + -sizeof (*xdpf) + xdpf->headroom; -dma_sync_single_for_device (pp->dev->dev.parent, dma_addr, - xdpf->len,DMA_BIDIRECTIONAL ); - buf->type =MVNETA_TYPE_XDP_TX ; +if (!i) + tx_desc->command =MVNETA_TXD_F_DESC ; + tx_desc->buf_phys_addr = dma_addr; + tx_desc->data_size = len; + +mvneta_txq_inc_put (txq); } - buf->xdpf = xdpf; - tx_desc->command =MVNETA_TXD_FLZ_DESC ; - tx_desc->buf_phys_addr = dma_addr; - tx_desc->data_size = xdpf->len; +/*last descriptor */ +if (tx_desc) + tx_desc->command |=MVNETA_TXD_L_DESC |MVNETA_TXD_Z_PAD ; -mvneta_txq_inc_put (txq); - txq->pending++; - txq->count++; + txq->pending += num_frames; + txq->count += num_frames;return MVNETA_XDP_TX ; }
Signature · 1 line
2.26.2
PATCH 6/6 net: mvneta: enable jumbo frames for XDP
In reply to Lorenzo BianconiEnable the capability to receive jumbo frames even if the interface is running in XDP mode
--- drivers/net/ethernet/marvell/mvneta.c | 10 ---------- 1 file changed, 10 deletions(-)
drivers/net/ethernet/marvell/mvneta.c +0 -10
@@ -3735,11 +3735,6 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu) mtu =ALIGN (MVNETA_RX_PKT_SIZE (mtu),8 ); } -if (pp->xdp_prog && mtu >MVNETA_MAX_RX_BUF_SIZE ) { -netdev_info (dev,"Illegal MTU value %d for XDP mode\n" , mtu); -return -EINVAL ; - } - dev->mtu = mtu;if (!netif_running (dev)) {
@@ -4437,11 +4432,6 @@ static int mvneta_xdp_setup(struct net_device *dev, struct bpf_prog *prog,struct mvneta_port *pp =netdev_priv (dev);struct bpf_prog *old_prog; -if (prog && dev->mtu >MVNETA_MAX_RX_BUF_SIZE ) { -NL_SET_ERR_MSG_MOD (extack,"Jumbo frames not supported on XDP" ); -return -EOPNOTSUPP ; - } -if (pp->bm_priv) {NL_SET_ERR_MSG_MOD (extack,"Hardware Buffer Management not supported on XDP" );
Signature · 1 line
2.26.2
Jakub Kicinski
maintainerRe: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
Quoted 4 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>
Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
Quoted 9 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
Hi Jakub,
with this series mvneta supports xdp multi-buff on both rx and tx sides (XDP_TX and ndo_xpd_xmit()) so we can remove MTU limitation.
Regards,
Lorenzo
Jakub Kicinski
maintainerRe: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
Quoted 11 lines · On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
Quoted 8 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
with this series mvneta supports xdp multi-buff on both rx and tx sides (
XDP_TXandndo_xpd_xmit()) so we can remove MTU limitation.
Is there an API for programs to access the multi-buf frames?
John Fastabend
maintainerRe: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
Quoted 7 lines · Jakub Kicinski
Quoted 6 lines · On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
Quoted 6 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
with this series mvneta supports xdp multi-buff on both rx and tx sides (
XDP_TXandndo_xpd_xmit()) so we can remove MTU limitation.Is there an API for programs to access the multi-buf frames?
Hi Lorenzo,
This is not enough to support multi-buffer in my opinion. I have the same comment as Jakub. We need an API to pull in the multiple buffers otherwise we break the ability to parse the packets and that is a hard requirement to me. I don't want to lose visibility to get jumbo frames.
At minimum we need a bpf_xdp_pull_data() to adjust pointer. In the skmsg case we use this,
bpf_msg_pull_data(u32 start, u32 end, u64 flags)
Where start is the offset into the packet and end is the last byte we want to adjust start/end pointers to. This way we can walk pages if we want and avoid having to linearize the data unless the user actual asks us for a block that crosses a page range. Smart users then never do a start/end that crosses a page boundary if possible. I think the same would apply here.
XDP by default gives you the first page start/end to use freely. If you need to parse deeper into the payload then you call bpf_msg_pull_data with the byte offsets needed.
Also we would want performance numbers to see how good/bad this is compared to the base case.
Thanks,
John
Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
Quoted 36 lines · On Wed, 19 Aug 2020 14:58:05 -0700 John Fastabend <[email protected]>…
Quoted 7 lines · Jakub Kicinski
Quoted 6 lines · On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
Quoted 6 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
with this series mvneta supports xdp multi-buff on both rx and tx sides (
XDP_TXandndo_xpd_xmit()) so we can remove MTU limitation.Is there an API for programs to access the multi-buf frames?
Hi Lorenzo,
This is not enough to support multi-buffer in my opinion. I have the same comment as Jakub. We need an API to pull in the multiple buffers otherwise we break the ability to parse the packets and that is a hard requirement to me. I don't want to lose visibility to get jumbo frames.
At minimum we need a
bpf_xdp_pull_data()to adjust pointer. In the skmsg case we use this,
bpf_msg_pull_data(u32 start, u32 end, u64 flags)Where start is the offset into the packet and end is the last byte we want to adjust start/end pointers to. This way we can walk pages if we want and avoid having to linearize the data unless the user actual asks us for a block that crosses a page range. Smart users then never do a start/end that crosses a page boundary if possible. I think the same would apply here.
Quoted 3 lines
XDP by default gives you the first page start/end to use freely. If you need to parse deeper into the payload then you call
bpf_msg_pull_datawith the byte offsets needed.
I agree that we need a helper like this. (I also think Daniel have proposed this before). This would also be useful for Eric Dumazet / Google's header-split use-case[1]. As I understood from his talk[1], the NIC HW might not always split the packet correctly (due to HW limits). This helper could solve part of this challenge.
[1] https://netdevconf.info/0x14/session.html?talk-the-path-to-tcp-4k-mtu-and-rx-zerocopy
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
In reply to John FastabendQuoted 11 lines
Quoted 10 lines · Jakub Kicinski
Quoted 9 lines · On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
Quoted 8 lines · On Wed, 19 Aug 2020 15:13:51 +0200 Lorenzo Bianconi wrote:
Quoted 4 lines
Enable the capability to receive jumbo frames even if the interface is running in XDP mode
Signed-off-by Lorenzo Bianconi <[email protected]>Hm, already? Is all the infra in place? Or does it not imply multi-buffer.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
with this series mvneta supports xdp multi-buff on both rx and tx sides (
XDP_TXandndo_xpd_xmit()) so we can remove MTU limitation.Is there an API for programs to access the multi-buf frames?
Hi Lorenzo,
Hi Jakub and John,
Quoted 6 lines
This is not enough to support multi-buffer in my opinion. I have the same comment as Jakub. We need an API to pull in the multiple buffers otherwise we break the ability to parse the packets and that is a hard requirement to me. I don't want to lose visibility to get jumbo frames.
I have not been so clear in the commit message, sorry for that. This series aims to finalize xdp multi-buff support for mvneta driver only. Our plan is to work on the helpers/metadata in subsequent series since driver support is quite orthogonal. If you think we need the helpers in place before removing the mtu constraint, we could just drop last patch (6/6) and apply patches from 1/6 to 5/6 since they are preliminary to remove the mtu constraint. Do you agree?
Quoted 13 lines
At minimum we need a
bpf_xdp_pull_data()to adjust pointer. In the skmsg case we use this,
bpf_msg_pull_data(u32 start, u32 end, u64 flags)Where start is the offset into the packet and end is the last byte we want to adjust start/end pointers to. This way we can walk pages if we want and avoid having to linearize the data unless the user actual asks us for a block that crosses a page range. Smart users then never do a start/end that crosses a page boundary if possible. I think the same would apply here.
Quoted 3 lines
XDP by default gives you the first page start/end to use freely. If you need to parse deeper into the payload then you call
bpf_msg_pull_datawith the byte offsets needed.
Our first proposal is described here [0][1]. In particular, we are assuming the eBPF layer can access just the first fragment in the non-linear XDP buff and we will provide some non-linear xdp metadata (e.g. # of segments in the xdp_buffer or buffer total length) to the eBPF program attached to the interface. Anyway IMHO this mvneta series is not strictly related to this approach.
Regards,
Lorenzo
[0] https://github.com/xdp-project/xdp-project/blob/master/areas/core/xdp-multi-buffer01-design.org
[1] http://people.redhat.com/lbiancon/conference/NetDevConf2020-0x14/add-xdp-on-driver.html (XDP multi-buffers section)
Quoted 6 lines
Also we would want performance numbers to see how good/bad this is compared to the base case.
Thanks,
John
General issue (that I think must be resolved/discussed as part of this initial patchset).
When XDP_REDIRECT'ing a multi-buffer xdp_frame out of another driver's ndo_xdp_xmit(), what happens if the remote driver doesn't understand the multi-buffer format?
My guess it that it will only send the first part of the packet (in the main page). Fortunately we don't leak memory, because xdp_return_frame() handle freeing the other segments. I assume this isn't acceptable behavior... or maybe it is?
What are our options for handling this:
1. Add mb support in ndo_xdp_xmit in every driver?
2. Drop xdp->mb frames inside ndo_xdp_xmit (in every driver without support)?
3. Add core-code check before calling ndo_xdp_xmit()?
--Jesper
Quoted 10 lines · On Wed, 19 Aug 2020 15:13:45 +0200 Lorenzo Bianconi <[email protected]> wrote:
Finalize XDP multi-buffer support for mvneta driver introducing the capability to map non-linear buffers on tx side.
Introduce multi-buffer bit (mb) in xdp_frame/xdp_buffer to specify ifshared_infoarea has been properly initialized.
Initialize multi-buffer bit (mb) to 0 in all XDP-capable drivers. Add multi-buff support to xdp_return_{buff/frame} utility routines.Changes since RFC:
- squash multi-buffer bit initialization in a single patch
- add mvneta non-linear XDP buff support for tx side
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Quoted 4 lines
General issue (that I think must be resolved/discussed as part of this initial patchset).
I was thinking about this issue as well.
Quoted 5 lines
When XDP_REDIRECT'ing a multi-buffer
xdp_frameout of another driver'sndo_xdp_xmit(), what happens if the remote driver doesn't understand the multi-buffer format?
Quoted 8 lines
My guess it that it will only send the first part of the packet (in the main page). Fortunately we don't leak memory, because
xdp_return_frame()handle freeing the other segments. I assume this isn't acceptable behavior... or maybe it is?What are our options for handling this:
1. Add mb support in
ndo_xdp_xmitin every driver?
I guess this is the optimal approach.
Quoted 2 lines
2. Drop
xdp->mbframes insidendo_xdp_xmit(in every driver without support)?
Probably this is the easiest solution.
Anyway if we drop patch 6/6 this is not a real issue since the driver is not allowed yet to receive frames bigger than one page and we have time to address this issue in each driver.
Regards,
Lorenzo
Quoted 24 lines
3. Add core-code check before calling
ndo_xdp_xmit()?--Jesper
Quoted 10 lines · On Wed, 19 Aug 2020 15:13:45 +0200 Lorenzo Bianconi <[email protected]> wrote:
Finalize XDP multi-buffer support for mvneta driver introducing the capability to map non-linear buffers on tx side.
Introduce multi-buffer bit (mb) in xdp_frame/xdp_buffer to specify ifshared_infoarea has been properly initialized.
Initialize multi-buffer bit (mb) to 0 in all XDP-capable drivers. Add multi-buff support to xdp_return_{buff/frame} utility routines.Changes since RFC:
- squash multi-buffer bit initialization in a single patch
- add mvneta non-linear XDP buff support for tx side--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer