Skip to content

Commit 700f11e

Browse files
HoratiuVulturkuba-moo
authored andcommitted
lan966x: Don't use xdp_frame when action is XDP_TX
When the action of an xdp program was XDP_TX, lan966x was creating a xdp_frame and use this one to send the frame back. But it is also possible to send back the frame without needing a xdp_frame, because it is possible to send it back using the page. And then once the frame is transmitted is possible to use directly page_pool_recycle_direct as lan966x is using page pools. This would save some CPU usage on this path, which results in higher number of transmitted frames. Bellow are the statistics: Frame size: Improvement: 64 ~8% 256 ~11% 512 ~8% 1000 ~0% 1500 ~0% Signed-off-by: Horatiu Vultur <[email protected]> Reviewed-by: Alexander Lobakin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent ee3392e commit 700f11e

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ static void lan966x_fdma_stop_netdev(struct lan966x *lan966x)
390390
static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
391391
{
392392
struct lan966x_tx *tx = &lan966x->tx;
393+
struct lan966x_rx *rx = &lan966x->rx;
393394
struct lan966x_tx_dcb_buf *dcb_buf;
394395
struct xdp_frame_bulk bq;
395396
struct lan966x_db *db;
@@ -432,7 +433,8 @@ static void lan966x_fdma_tx_clear_buf(struct lan966x *lan966x, int weight)
432433
if (dcb_buf->xdp_ndo)
433434
xdp_return_frame_bulk(dcb_buf->data.xdpf, &bq);
434435
else
435-
xdp_return_frame_rx_napi(dcb_buf->data.xdpf);
436+
page_pool_recycle_direct(rx->page_pool,
437+
dcb_buf->data.page);
436438
}
437439

438440
clear = true;
@@ -699,15 +701,14 @@ static void lan966x_fdma_tx_start(struct lan966x_tx *tx, int next_to_use)
699701
tx->last_in_use = next_to_use;
700702
}
701703

702-
int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
703-
struct xdp_frame *xdpf,
704-
struct page *page,
705-
bool dma_map)
704+
int lan966x_fdma_xmit_xdpf(struct lan966x_port *port, void *ptr, u32 len)
706705
{
707706
struct lan966x *lan966x = port->lan966x;
708707
struct lan966x_tx_dcb_buf *next_dcb_buf;
709708
struct lan966x_tx *tx = &lan966x->tx;
709+
struct xdp_frame *xdpf;
710710
dma_addr_t dma_addr;
711+
struct page *page;
711712
int next_to_use;
712713
__be32 *ifh;
713714
int ret = 0;
@@ -722,8 +723,13 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
722723
goto out;
723724
}
724725

726+
/* Get the next buffer */
727+
next_dcb_buf = &tx->dcbs_buf[next_to_use];
728+
725729
/* Generate new IFH */
726-
if (dma_map) {
730+
if (!len) {
731+
xdpf = ptr;
732+
727733
if (xdpf->headroom < IFH_LEN_BYTES) {
728734
ret = NETDEV_TX_OK;
729735
goto out;
@@ -743,11 +749,16 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
743749
goto out;
744750
}
745751

752+
next_dcb_buf->data.xdpf = xdpf;
753+
next_dcb_buf->len = xdpf->len + IFH_LEN_BYTES;
754+
746755
/* Setup next dcb */
747756
lan966x_fdma_tx_setup_dcb(tx, next_to_use,
748757
xdpf->len + IFH_LEN_BYTES,
749758
dma_addr);
750759
} else {
760+
page = ptr;
761+
751762
ifh = page_address(page) + XDP_PACKET_HEADROOM;
752763
memset(ifh, 0x0, sizeof(__be32) * IFH_LEN);
753764
lan966x_ifh_set_bypass(ifh, 1);
@@ -756,21 +767,21 @@ int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
756767
dma_addr = page_pool_get_dma_addr(page);
757768
dma_sync_single_for_device(lan966x->dev,
758769
dma_addr + XDP_PACKET_HEADROOM,
759-
xdpf->len + IFH_LEN_BYTES,
770+
len + IFH_LEN_BYTES,
760771
DMA_TO_DEVICE);
761772

773+
next_dcb_buf->data.page = page;
774+
next_dcb_buf->len = len + IFH_LEN_BYTES;
775+
762776
/* Setup next dcb */
763777
lan966x_fdma_tx_setup_dcb(tx, next_to_use,
764-
xdpf->len + IFH_LEN_BYTES,
778+
len + IFH_LEN_BYTES,
765779
dma_addr + XDP_PACKET_HEADROOM);
766780
}
767781

768782
/* Fill up the buffer */
769-
next_dcb_buf = &tx->dcbs_buf[next_to_use];
770783
next_dcb_buf->use_skb = false;
771-
next_dcb_buf->data.xdpf = xdpf;
772-
next_dcb_buf->xdp_ndo = dma_map;
773-
next_dcb_buf->len = xdpf->len + IFH_LEN_BYTES;
784+
next_dcb_buf->xdp_ndo = !len;
774785
next_dcb_buf->dma_addr = dma_addr;
775786
next_dcb_buf->used = true;
776787
next_dcb_buf->ptp = false;

drivers/net/ethernet/microchip/lan966x/lan966x_main.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ struct lan966x_tx_dcb_buf {
243243
union {
244244
struct sk_buff *skb;
245245
struct xdp_frame *xdpf;
246+
struct page *page;
246247
} data;
247248
u32 len;
248249
u32 used : 1;
@@ -541,10 +542,7 @@ int lan966x_ptp_setup_traps(struct lan966x_port *port, struct ifreq *ifr);
541542
int lan966x_ptp_del_traps(struct lan966x_port *port);
542543

543544
int lan966x_fdma_xmit(struct sk_buff *skb, __be32 *ifh, struct net_device *dev);
544-
int lan966x_fdma_xmit_xdpf(struct lan966x_port *port,
545-
struct xdp_frame *frame,
546-
struct page *page,
547-
bool dma_map);
545+
int lan966x_fdma_xmit_xdpf(struct lan966x_port *port, void *ptr, u32 len);
548546
int lan966x_fdma_change_mtu(struct lan966x *lan966x);
549547
void lan966x_fdma_netdev_init(struct lan966x *lan966x, struct net_device *dev);
550548
void lan966x_fdma_netdev_deinit(struct lan966x *lan966x, struct net_device *dev);

drivers/net/ethernet/microchip/lan966x/lan966x_xdp.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int lan966x_xdp_xmit(struct net_device *dev,
6262
struct xdp_frame *xdpf = frames[i];
6363
int err;
6464

65-
err = lan966x_fdma_xmit_xdpf(port, xdpf, NULL, true);
65+
err = lan966x_fdma_xmit_xdpf(port, xdpf, 0);
6666
if (err)
6767
break;
6868

@@ -76,7 +76,6 @@ int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
7676
{
7777
struct bpf_prog *xdp_prog = port->xdp_prog;
7878
struct lan966x *lan966x = port->lan966x;
79-
struct xdp_frame *xdpf;
8079
struct xdp_buff xdp;
8180
u32 act;
8281

@@ -90,11 +89,8 @@ int lan966x_xdp_run(struct lan966x_port *port, struct page *page, u32 data_len)
9089
case XDP_PASS:
9190
return FDMA_PASS;
9291
case XDP_TX:
93-
xdpf = xdp_convert_buff_to_frame(&xdp);
94-
if (!xdpf)
95-
return FDMA_DROP;
96-
97-
return lan966x_fdma_xmit_xdpf(port, xdpf, page, false) ?
92+
return lan966x_fdma_xmit_xdpf(port, page,
93+
data_len - IFH_LEN_BYTES) ?
9894
FDMA_DROP : FDMA_TX;
9995
case XDP_REDIRECT:
10096
if (xdp_do_redirect(port->dev, &xdp, xdp_prog))

0 commit comments

Comments
 (0)