Skip to content

Commit abeeec4

Browse files
Jakub Kicinskidavem330
authored andcommitted
nfp: complete the XDP TX ring only when it's full
Since XDP TX ring holds "spare" RX buffers anyway, we don't have to rush the completion. We can wait until ring fills up completely before trying to reclaim buffers. If RX poll has ended an no buffer has been queued for XDP TX we have no guarantee we will see another interrupt, so run the reclaim there as well, to make sure TX statistics won't become stale. This should help us reclaim more buffers per single queue controller register read. Note that the XDP completion is very trivial, it only adds up the sizes of transmitted frames for statistics so the latency spike should be acceptable. In case user sets the ring sizes to something crazy, limit the completion to 2k entries. The check if the ring is empty at the beginning of xdp_complete() is no longer needed - the callers will perform it. Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ddb98d9 commit abeeec4

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
#define NFP_NET_RX_DESCS_DEFAULT 4096 /* Default # of Rx descs per ring */
103103

104104
#define NFP_NET_FL_BATCH 16 /* Add freelist in this Batch size */
105+
#define NFP_NET_XDP_MAX_COMPLETE 2048 /* XDP bufs to reclaim in NAPI poll */
105106

106107
/* Offload definitions */
107108
#define NFP_NET_N_VXLAN_PORTS (NFP_NET_CFG_VXLAN_SZ / sizeof(__be16))

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,27 +1001,30 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
10011001
tx_ring->rd_p, tx_ring->wr_p, tx_ring->cnt);
10021002
}
10031003

1004-
static void nfp_net_xdp_complete(struct nfp_net_tx_ring *tx_ring)
1004+
static bool nfp_net_xdp_complete(struct nfp_net_tx_ring *tx_ring)
10051005
{
10061006
struct nfp_net_r_vector *r_vec = tx_ring->r_vec;
10071007
u32 done_pkts = 0, done_bytes = 0;
1008+
bool done_all;
10081009
int idx, todo;
10091010
u32 qcp_rd_p;
10101011

1011-
if (tx_ring->wr_p == tx_ring->rd_p)
1012-
return;
1013-
10141012
/* Work out how many descriptors have been transmitted */
10151013
qcp_rd_p = nfp_qcp_rd_ptr_read(tx_ring->qcp_q);
10161014

10171015
if (qcp_rd_p == tx_ring->qcp_rd_p)
1018-
return;
1016+
return true;
10191017

10201018
if (qcp_rd_p > tx_ring->qcp_rd_p)
10211019
todo = qcp_rd_p - tx_ring->qcp_rd_p;
10221020
else
10231021
todo = qcp_rd_p + tx_ring->cnt - tx_ring->qcp_rd_p;
10241022

1023+
done_all = todo <= NFP_NET_XDP_MAX_COMPLETE;
1024+
todo = min(todo, NFP_NET_XDP_MAX_COMPLETE);
1025+
1026+
tx_ring->qcp_rd_p = (tx_ring->qcp_rd_p + todo) & (tx_ring->cnt - 1);
1027+
10251028
done_pkts = todo;
10261029
while (todo--) {
10271030
idx = tx_ring->rd_p & (tx_ring->cnt - 1);
@@ -1030,16 +1033,16 @@ static void nfp_net_xdp_complete(struct nfp_net_tx_ring *tx_ring)
10301033
done_bytes += tx_ring->txbufs[idx].real_len;
10311034
}
10321035

1033-
tx_ring->qcp_rd_p = qcp_rd_p;
1034-
10351036
u64_stats_update_begin(&r_vec->tx_sync);
10361037
r_vec->tx_bytes += done_bytes;
10371038
r_vec->tx_pkts += done_pkts;
10381039
u64_stats_update_end(&r_vec->tx_sync);
10391040

10401041
WARN_ONCE(tx_ring->wr_p - tx_ring->rd_p > tx_ring->cnt,
1041-
"TX ring corruption rd_p=%u wr_p=%u cnt=%u\n",
1042+
"XDP TX ring corruption rd_p=%u wr_p=%u cnt=%u\n",
10421043
tx_ring->rd_p, tx_ring->wr_p, tx_ring->cnt);
1044+
1045+
return done_all;
10431046
}
10441047

10451048
/**
@@ -1500,15 +1503,23 @@ static bool
15001503
nfp_net_tx_xdp_buf(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring,
15011504
struct nfp_net_tx_ring *tx_ring,
15021505
struct nfp_net_rx_buf *rxbuf, unsigned int dma_off,
1503-
unsigned int pkt_len)
1506+
unsigned int pkt_len, bool *completed)
15041507
{
15051508
struct nfp_net_tx_buf *txbuf;
15061509
struct nfp_net_tx_desc *txd;
15071510
int wr_idx;
15081511

15091512
if (unlikely(nfp_net_tx_full(tx_ring, 1))) {
1510-
nfp_net_rx_drop(dp, rx_ring->r_vec, rx_ring, rxbuf, NULL);
1511-
return false;
1513+
if (!*completed) {
1514+
nfp_net_xdp_complete(tx_ring);
1515+
*completed = true;
1516+
}
1517+
1518+
if (unlikely(nfp_net_tx_full(tx_ring, 1))) {
1519+
nfp_net_rx_drop(dp, rx_ring->r_vec, rx_ring, rxbuf,
1520+
NULL);
1521+
return false;
1522+
}
15121523
}
15131524

15141525
wr_idx = tx_ring->wr_p & (tx_ring->cnt - 1);
@@ -1580,6 +1591,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
15801591
struct nfp_net_dp *dp = &r_vec->nfp_net->dp;
15811592
struct nfp_net_tx_ring *tx_ring;
15821593
struct bpf_prog *xdp_prog;
1594+
bool xdp_tx_cmpl = false;
15831595
unsigned int true_bufsz;
15841596
struct sk_buff *skb;
15851597
int pkts_polled = 0;
@@ -1690,7 +1702,8 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
16901702
if (unlikely(!nfp_net_tx_xdp_buf(dp, rx_ring,
16911703
tx_ring, rxbuf,
16921704
dma_off,
1693-
pkt_len)))
1705+
pkt_len,
1706+
&xdp_tx_cmpl)))
16941707
trace_xdp_exception(dp->netdev,
16951708
xdp_prog, act);
16961709
continue;
@@ -1738,8 +1751,14 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
17381751
napi_gro_receive(&rx_ring->r_vec->napi, skb);
17391752
}
17401753

1741-
if (xdp_prog && tx_ring->wr_ptr_add)
1742-
nfp_net_tx_xmit_more_flush(tx_ring);
1754+
if (xdp_prog) {
1755+
if (tx_ring->wr_ptr_add)
1756+
nfp_net_tx_xmit_more_flush(tx_ring);
1757+
else if (unlikely(tx_ring->wr_p != tx_ring->rd_p) &&
1758+
!xdp_tx_cmpl)
1759+
if (!nfp_net_xdp_complete(tx_ring))
1760+
pkts_polled = budget;
1761+
}
17431762
rcu_read_unlock();
17441763

17451764
return pkts_polled;
@@ -1760,11 +1779,8 @@ static int nfp_net_poll(struct napi_struct *napi, int budget)
17601779

17611780
if (r_vec->tx_ring)
17621781
nfp_net_tx_complete(r_vec->tx_ring);
1763-
if (r_vec->rx_ring) {
1782+
if (r_vec->rx_ring)
17641783
pkts_polled = nfp_net_rx(r_vec->rx_ring, budget);
1765-
if (r_vec->xdp_ring)
1766-
nfp_net_xdp_complete(r_vec->xdp_ring);
1767-
}
17681784

17691785
if (pkts_polled < budget)
17701786
if (napi_complete_done(napi, pkts_polled))

0 commit comments

Comments
 (0)