bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support
@ 2020-08-19 13:13 Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame Lorenzo Bianconi
                   ` (6 more replies)
  0 siblings, 7 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

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(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-23 14:08   ` Shay Agroskin
  2020-08-19 13:13 ` [PATCH net-next 2/6] xdp: initialize xdp_buff mb bit to 0 in all XDP drivers Lorenzo Bianconi
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

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

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 include/net/xdp.h | 8 ++++++--
 net/core/xdp.c    | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/xdp.h b/include/net/xdp.h
index 3814fb631d52..42f439f9fcda 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -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;
 }
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 48aba933a5a8..884f140fc3be 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -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);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH net-next 2/6] xdp: initialize xdp_buff mb bit to 0 in all XDP drivers
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Lorenzo Bianconi
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

Initialize multi-buffer bit (mb) to 0 in all XDP-capable drivers.
This is a preliminary patch to enable xdp multi-buffer support.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 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(+)

diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 2a6c9725e092..02a32196c226 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -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;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 2704a4709bc7..63dde7a369b7 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -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();
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index c1378b5c780c..28448033750d 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -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();
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 457106e761be..3e7b1cf94c09 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -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);
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 3e5c566ceb01..7d5a8afa8a4c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -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;
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index 9d0d6b0025cf..d96a9525942a 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -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)) {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2f8a4cfc5fa1..46409f66d04d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -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;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index a428113e6d54..f96fe937f4e9 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -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)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 2a8a5842eaef..d02e08eb3df8 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -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;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index b50c567ef508..0bbc666511ba 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -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
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 65828af120b7..098e0b47812e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -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 *
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 39ee23e8c0bf..0bfccf2a7b1c 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -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) {
diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c
index a2494bf85007..14a54094ca08 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_fp.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c
@@ -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
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 59a43d586967..8fd6023995d4 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -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();
diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 25db667fa879..c73108ce0a32 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -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);
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 9b17bbbe102f..53a55c540adc 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -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);
diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index 1247d35d42ef..703d079fd479 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -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)
diff --git a/drivers/net/hyperv/netvsc_bpf.c b/drivers/net/hyperv/netvsc_bpf.c
index 440486d9c999..a4bafc64997f 100644
--- a/drivers/net/hyperv/netvsc_bpf.c
+++ b/drivers/net/hyperv/netvsc_bpf.c
@@ -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);
 
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3c11a77f5709..317fe5c8db60 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -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);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index e56cd562a664..71734f4eb8be 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -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;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 0ada48edf749..3bee68f59e19 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -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++;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 458be6882b98..02ed7f26097d 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -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) {
diff --git a/net/core/dev.c b/net/core/dev.c
index 7df6c9617321..a00aa737ce29 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -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;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 2/6] xdp: initialize xdp_buff mb bit to 0 in all XDP drivers Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-20  8:02   ` Jesper Dangaard Brouer
  2020-08-20 19:38   ` Maciej Fijalkowski
  2020-08-19 13:13 ` [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame} Lorenzo Bianconi
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and
XDP remote drivers if this is a "non-linear" XDP buffer

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/marvell/mvneta.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 832bbb8b05c8..36a3defa63fa 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -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 */
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame}
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
                   ` (2 preceding siblings ...)
  2020-08-19 13:13 ` [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-20  7:52   ` Jesper Dangaard Brouer
  2020-08-19 13:13 ` [PATCH net-next 5/6] net: mvneta: add multi buffer support to XDP_TX Lorenzo Bianconi
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

Take into account if the received xdp_buff/xdp_frame is non-linear
recycling/returning the frame memory to the allocator

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 include/net/xdp.h | 17 +++++++++++++++--
 net/core/xdp.c    | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/include/net/xdp.h b/include/net/xdp.h
index 42f439f9fcda..37c4522fc1bb 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -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,
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 884f140fc3be..006b24b5d276 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -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 */
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH net-next 5/6] net: mvneta: add multi buffer support to XDP_TX
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
                   ` (3 preceding siblings ...)
  2020-08-19 13:13 ` [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame} Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-19 13:13 ` [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP Lorenzo Bianconi
  2020-08-20 13:16 ` [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Jesper Dangaard Brouer
  6 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

Introduce the capability to map non-linear xdp buffer running
mvneta_xdp_submit_frame() for XDP_TX and XDP_REDIRECT

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/marvell/mvneta.c | 79 +++++++++++++++++----------
 1 file changed, 49 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 36a3defa63fa..efac4a5e0439 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -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;
 }
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
                   ` (4 preceding siblings ...)
  2020-08-19 13:13 ` [PATCH net-next 5/6] net: mvneta: add multi buffer support to XDP_TX Lorenzo Bianconi
@ 2020-08-19 13:13 ` Lorenzo Bianconi
  2020-08-19 19:23   ` Jakub Kicinski
  2020-08-20 13:16 ` [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Jesper Dangaard Brouer
  6 siblings, 1 reply; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 13:13 UTC (permalink / raw)
  To: netdev; +Cc: bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

Enable the capability to receive jumbo frames even if the interface is
running in XDP mode

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/marvell/mvneta.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index efac4a5e0439..42f7614cd67c 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -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");
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 13:13 ` [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP Lorenzo Bianconi
@ 2020-08-19 19:23   ` Jakub Kicinski
  2020-08-19 20:22     ` Lorenzo Bianconi
  0 siblings, 1 reply; 24+ messages in thread
From: Jakub Kicinski @ 2020-08-19 19:23 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj

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 <lorenzo@kernel.org>

Hm, already? Is all the infra in place? Or does it not imply
multi-buffer.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 19:23   ` Jakub Kicinski
@ 2020-08-19 20:22     ` Lorenzo Bianconi
  2020-08-19 21:14       ` Jakub Kicinski
  0 siblings, 1 reply; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-19 20:22 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Lorenzo Bianconi, netdev, bpf, davem, brouer, echaudro, sameehj

[-- Attachment #1: Type: text/plain, Size: 487 bytes --]

> 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 <lorenzo@kernel.org>
> 
> 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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 20:22     ` Lorenzo Bianconi
@ 2020-08-19 21:14       ` Jakub Kicinski
  2020-08-19 21:58         ` John Fastabend
  0 siblings, 1 reply; 24+ messages in thread
From: Jakub Kicinski @ 2020-08-19 21:14 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Lorenzo Bianconi, netdev, bpf, davem, brouer, echaudro, sameehj

On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
> > 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 <lorenzo@kernel.org>  
> > 
> > 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_TX
> and ndo_xpd_xmit()) so we can remove MTU limitation.

Is there an API for programs to access the multi-buf frames?

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 21:14       ` Jakub Kicinski
@ 2020-08-19 21:58         ` John Fastabend
  2020-08-20  7:47           ` Jesper Dangaard Brouer
  2020-08-20  7:54           ` Lorenzo Bianconi
  0 siblings, 2 replies; 24+ messages in thread
From: John Fastabend @ 2020-08-19 21:58 UTC (permalink / raw)
  To: Jakub Kicinski, Lorenzo Bianconi
  Cc: Lorenzo Bianconi, netdev, bpf, davem, brouer, echaudro, sameehj

Jakub Kicinski wrote:
> On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
> > > 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 <lorenzo@kernel.org>  
> > > 
> > > 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_TX
> > and ndo_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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 21:58         ` John Fastabend
@ 2020-08-20  7:47           ` Jesper Dangaard Brouer
  2020-08-20  7:54           ` Lorenzo Bianconi
  1 sibling, 0 replies; 24+ messages in thread
From: Jesper Dangaard Brouer @ 2020-08-20  7:47 UTC (permalink / raw)
  To: John Fastabend
  Cc: Jakub Kicinski, Lorenzo Bianconi, Lorenzo Bianconi, netdev, bpf,
	davem, echaudro, sameehj, brouer, Eric Dumazet

On Wed, 19 Aug 2020 14:58:05 -0700
John Fastabend <john.fastabend@gmail.com> wrote:

> Jakub Kicinski wrote:
> > On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:  
> > > > 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 <lorenzo@kernel.org>    
> > > > 
> > > > 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_TX
> > > and ndo_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.

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
-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame}
  2020-08-19 13:13 ` [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame} Lorenzo Bianconi
@ 2020-08-20  7:52   ` Jesper Dangaard Brouer
  2020-08-20  7:56     ` Lorenzo Bianconi
  0 siblings, 1 reply; 24+ messages in thread
From: Jesper Dangaard Brouer @ 2020-08-20  7:52 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, echaudro, sameehj, kuba, brouer

On Wed, 19 Aug 2020 15:13:49 +0200
Lorenzo Bianconi <lorenzo@kernel.org> wrote:

> diff --git a/net/core/xdp.c b/net/core/xdp.c
> index 884f140fc3be..006b24b5d276 100644
> --- a/net/core/xdp.c
> +++ b/net/core/xdp.c
> @@ -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.

> +	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);

Same issue.

> +	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);

Same issue.

> +	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);
> +	}
>  }



-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP
  2020-08-19 21:58         ` John Fastabend
  2020-08-20  7:47           ` Jesper Dangaard Brouer
@ 2020-08-20  7:54           ` Lorenzo Bianconi
  1 sibling, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-20  7:54 UTC (permalink / raw)
  To: John Fastabend
  Cc: Jakub Kicinski, Lorenzo Bianconi, netdev, bpf, davem, brouer,
	echaudro, sameehj

[-- Attachment #1: Type: text/plain, Size: 3002 bytes --]

> Jakub Kicinski wrote:
> > On Wed, 19 Aug 2020 22:22:23 +0200 Lorenzo Bianconi wrote:
> > > > 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 <lorenzo@kernel.org>  
> > > > 
> > > > 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_TX
> > > and ndo_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,

> 
> 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?

> 
> 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.

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)

> 
> Also we would want performance numbers to see how good/bad this is
> compared to the base case.
> 
> Thanks,
> John

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame}
  2020-08-20  7:52   ` Jesper Dangaard Brouer
@ 2020-08-20  7:56     ` Lorenzo Bianconi
  0 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-20  7:56 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev, bpf, davem, lorenzo.bianconi, echaudro, sameehj, kuba

[-- Attachment #1: Type: text/plain, Size: 2347 bytes --]

> On Wed, 19 Aug 2020 15:13:49 +0200
> Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> 
> > diff --git a/net/core/xdp.c b/net/core/xdp.c
> > index 884f140fc3be..006b24b5d276 100644
> > --- a/net/core/xdp.c
> > +++ b/net/core/xdp.c
> > @@ -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.

right, thx for pointing this out. I will fix it in v2.

Regards,
Lorenzo

> 
> > +	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);
> 
> Same issue.
> 
> > +	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);
> 
> Same issue.
> 
> > +	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);
> > +	}
> >  }
> 
> 
> 
> -- 
> Best regards,
>   Jesper Dangaard Brouer
>   MSc.CS, Principal Kernel Engineer at Red Hat
>   LinkedIn: http://www.linkedin.com/in/brouer
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
  2020-08-19 13:13 ` [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Lorenzo Bianconi
@ 2020-08-20  8:02   ` Jesper Dangaard Brouer
  2020-08-20  8:11     ` Lorenzo Bianconi
  2020-08-20 19:38   ` Maciej Fijalkowski
  1 sibling, 1 reply; 24+ messages in thread
From: Jesper Dangaard Brouer @ 2020-08-20  8:02 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, echaudro, sameehj, kuba, brouer

On Wed, 19 Aug 2020 15:13:48 +0200
Lorenzo Bianconi <lorenzo@kernel.org> wrote:

> Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and
> XDP remote drivers if this is a "non-linear" XDP buffer
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/marvell/mvneta.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index 832bbb8b05c8..36a3defa63fa 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -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);

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).

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
  2020-08-20  8:02   ` Jesper Dangaard Brouer
@ 2020-08-20  8:11     ` Lorenzo Bianconi
  0 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-20  8:11 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: netdev, bpf, davem, lorenzo.bianconi, echaudro, sameehj, kuba

[-- Attachment #1: Type: text/plain, Size: 1650 bytes --]

> On Wed, 19 Aug 2020 15:13:48 +0200
> Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> 
> > Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and
> > XDP remote drivers if this is a "non-linear" XDP buffer
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/ethernet/marvell/mvneta.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> > index 832bbb8b05c8..36a3defa63fa 100644
> > --- a/drivers/net/ethernet/marvell/mvneta.c
> > +++ b/drivers/net/ethernet/marvell/mvneta.c
> > @@ -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);
> 
> 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).

ack, I will rework it in v2 to remove this access.

Regards,
Lorenzo

> 
> -- 
> Best regards,
>   Jesper Dangaard Brouer
>   MSc.CS, Principal Kernel Engineer at Red Hat
>   LinkedIn: http://www.linkedin.com/in/brouer
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support
  2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
                   ` (5 preceding siblings ...)
  2020-08-19 13:13 ` [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP Lorenzo Bianconi
@ 2020-08-20 13:16 ` Jesper Dangaard Brouer
  2020-08-20 13:36   ` Lorenzo Bianconi
  6 siblings, 1 reply; 24+ messages in thread
From: Jesper Dangaard Brouer @ 2020-08-20 13:16 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, echaudro, sameehj, kuba, brouer


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

On Wed, 19 Aug 2020 15:13:45 +0200 Lorenzo Bianconi <lorenzo@kernel.org> 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 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

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support
  2020-08-20 13:16 ` [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Jesper Dangaard Brouer
@ 2020-08-20 13:36   ` Lorenzo Bianconi
  0 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-20 13:36 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: Lorenzo Bianconi, Network Development, BPF-dev-list,
	David S. Miller, Eelco Chaudron, Jubran, Samih, Jakub Kicinski

>
>
> General issue (that I think must be resolved/discussed as part of this initial
> patchset).

I was thinking about this issue as well.

>
> 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?

I guess this is the optimal approach.

>
> 2. Drop xdp->mb frames inside ndo_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

>
> 3. Add core-code check before calling ndo_xdp_xmit()?
>
> --Jesper
>
> On Wed, 19 Aug 2020 15:13:45 +0200 Lorenzo Bianconi <lorenzo@kernel.org> 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 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
>
> --
> Best regards,
>   Jesper Dangaard Brouer
>   MSc.CS, Principal Kernel Engineer at Red Hat
>   LinkedIn: http://www.linkedin.com/in/brouer
>


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
  2020-08-19 13:13 ` [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Lorenzo Bianconi
  2020-08-20  8:02   ` Jesper Dangaard Brouer
@ 2020-08-20 19:38   ` Maciej Fijalkowski
  2020-08-21  7:43     ` Lorenzo Bianconi
  1 sibling, 1 reply; 24+ messages in thread
From: Maciej Fijalkowski @ 2020-08-20 19:38 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba

On Wed, Aug 19, 2020 at 03:13:48PM +0200, Lorenzo Bianconi wrote:
> Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and
> XDP remote drivers if this is a "non-linear" XDP buffer
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/ethernet/marvell/mvneta.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> index 832bbb8b05c8..36a3defa63fa 100644
> --- a/drivers/net/ethernet/marvell/mvneta.c
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -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;

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.

>  	act = bpf_prog_run_xdp(prog, xdp);
>  
>  	/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
> -- 
> 2.26.2
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer
  2020-08-20 19:38   ` Maciej Fijalkowski
@ 2020-08-21  7:43     ` Lorenzo Bianconi
  0 siblings, 0 replies; 24+ messages in thread
From: Lorenzo Bianconi @ 2020-08-21  7:43 UTC (permalink / raw)
  To: Maciej Fijalkowski
  Cc: Lorenzo Bianconi, netdev, bpf, davem, brouer, echaudro, sameehj, kuba

[-- Attachment #1: Type: text/plain, Size: 1766 bytes --]

On Aug 20, Maciej Fijalkowski wrote:
> On Wed, Aug 19, 2020 at 03:13:48PM +0200, Lorenzo Bianconi wrote:
> > Update multi-buffer bit (mb) in xdp_buff to notify XDP/eBPF layer and
> > XDP remote drivers if this is a "non-linear" XDP buffer
> > 
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/ethernet/marvell/mvneta.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> > index 832bbb8b05c8..36a3defa63fa 100644
> > --- a/drivers/net/ethernet/marvell/mvneta.c
> > +++ b/drivers/net/ethernet/marvell/mvneta.c
> > @@ -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;
> 
> 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

> >  	act = bpf_prog_run_xdp(prog, xdp);
> >  
> >  	/* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
> > -- 
> > 2.26.2
> > 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
  2020-08-19 13:13 ` [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame Lorenzo Bianconi
@ 2020-08-23 14:08   ` Shay Agroskin
  2020-08-24  8:44     ` Jesper Dangaard Brouer
  0 siblings, 1 reply; 24+ messages in thread
From: Shay Agroskin @ 2020-08-23 14:08 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: netdev, bpf, davem, lorenzo.bianconi, brouer, echaudro, sameehj, kuba


Lorenzo Bianconi <lorenzo@kernel.org> writes:

> 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
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  include/net/xdp.h | 8 ++++++--
>  net/core/xdp.c    | 1 +
>  2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/xdp.h b/include/net/xdp.h
> index 3814fb631d52..42f439f9fcda 100644
> --- a/include/net/xdp.h
> +++ b/include/net/xdp.h
> @@ -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 */

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
>  	/* 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;
>  }
> diff --git a/net/core/xdp.c b/net/core/xdp.c
> index 48aba933a5a8..884f140fc3be 100644
> --- a/net/core/xdp.c
> +++ b/net/core/xdp.c
> @@ -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);


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
  2020-08-23 14:08   ` Shay Agroskin
@ 2020-08-24  8:44     ` Jesper Dangaard Brouer
  2020-08-26  9:47       ` Shay Agroskin
  0 siblings, 1 reply; 24+ messages in thread
From: Jesper Dangaard Brouer @ 2020-08-24  8:44 UTC (permalink / raw)
  To: Shay Agroskin
  Cc: Lorenzo Bianconi, netdev, bpf, davem, lorenzo.bianconi, echaudro,
	sameehj, kuba, brouer

On Sun, 23 Aug 2020 17:08:30 +0300
Shay Agroskin <shayagr@amazon.com> wrote:

> > diff --git a/include/net/xdp.h b/include/net/xdp.h
> > index 3814fb631d52..42f439f9fcda 100644
> > --- a/include/net/xdp.h
> > +++ b/include/net/xdp.h
> > @@ -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 */  
> 
> 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 
> ?

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.

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame
  2020-08-24  8:44     ` Jesper Dangaard Brouer
@ 2020-08-26  9:47       ` Shay Agroskin
  0 siblings, 0 replies; 24+ messages in thread
From: Shay Agroskin @ 2020-08-26  9:47 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: Lorenzo Bianconi, netdev, bpf, davem, lorenzo.bianconi, echaudro,
	sameehj, kuba


Jesper Dangaard Brouer <brouer@redhat.com> writes:

> On Sun, 23 Aug 2020 17:08:30 +0300
> Shay Agroskin <shayagr@amazon.com> wrote:
>
>> > diff --git a/include/net/xdp.h b/include/net/xdp.h
>> > index 3814fb631d52..42f439f9fcda 100644
>> > --- a/include/net/xdp.h
>> > +++ b/include/net/xdp.h
>> > @@ -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 */  
>> 
>> 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 
>> ?
>
> 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2020-08-26  9:48 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-19 13:13 [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Lorenzo Bianconi
2020-08-19 13:13 ` [PATCH net-next 1/6] xdp: introduce mb in xdp_buff/xdp_frame Lorenzo Bianconi
2020-08-23 14:08   ` Shay Agroskin
2020-08-24  8:44     ` Jesper Dangaard Brouer
2020-08-26  9:47       ` Shay Agroskin
2020-08-19 13:13 ` [PATCH net-next 2/6] xdp: initialize xdp_buff mb bit to 0 in all XDP drivers Lorenzo Bianconi
2020-08-19 13:13 ` [PATCH net-next 3/6] net: mvneta: update mb bit before passing the xdp buffer to eBPF layer Lorenzo Bianconi
2020-08-20  8:02   ` Jesper Dangaard Brouer
2020-08-20  8:11     ` Lorenzo Bianconi
2020-08-20 19:38   ` Maciej Fijalkowski
2020-08-21  7:43     ` Lorenzo Bianconi
2020-08-19 13:13 ` [PATCH net-next 4/6] xdp: add multi-buff support to xdp_return_{buff/frame} Lorenzo Bianconi
2020-08-20  7:52   ` Jesper Dangaard Brouer
2020-08-20  7:56     ` Lorenzo Bianconi
2020-08-19 13:13 ` [PATCH net-next 5/6] net: mvneta: add multi buffer support to XDP_TX Lorenzo Bianconi
2020-08-19 13:13 ` [PATCH net-next 6/6] net: mvneta: enable jumbo frames for XDP Lorenzo Bianconi
2020-08-19 19:23   ` Jakub Kicinski
2020-08-19 20:22     ` Lorenzo Bianconi
2020-08-19 21:14       ` Jakub Kicinski
2020-08-19 21:58         ` John Fastabend
2020-08-20  7:47           ` Jesper Dangaard Brouer
2020-08-20  7:54           ` Lorenzo Bianconi
2020-08-20 13:16 ` [PATCH net-next 0/6] mvneta: introduce XDP multi-buffer support Jesper Dangaard Brouer
2020-08-20 13:36   ` Lorenzo Bianconi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).