Skip to content

Commit b8aef65

Browse files
mfijalkoborkmann
authored andcommitted
i40e, xsk: Terminate Rx side of NAPI when XSK Rx queue gets full
When XSK pool uses need_wakeup feature, correlate -ENOBUFS that was returned from xdp_do_redirect() with a XSK Rx queue being full. In such case, terminate the Rx processing that is being done on the current HW Rx ring and let the user space consume descriptors from XSK Rx queue so that there is room that driver can use later on. Introduce new internal return code I40E_XDP_EXIT that will indicate case described above. Note that it does not affect Tx processing that is bound to the same NAPI context, nor the other Rx rings. Signed-off-by: Maciej Fijalkowski <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 50ae066 commit b8aef65

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

drivers/net/ethernet/intel/i40e/i40e_txrx_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val);
2020
#define I40E_XDP_CONSUMED BIT(0)
2121
#define I40E_XDP_TX BIT(1)
2222
#define I40E_XDP_REDIR BIT(2)
23+
#define I40E_XDP_EXIT BIT(3)
2324

2425
/*
2526
* build_ctob - Builds the Tx descriptor (cmd, offset and type) qword

drivers/net/ethernet/intel/i40e/i40e_xsk.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,13 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
161161

162162
if (likely(act == XDP_REDIRECT)) {
163163
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
164-
if (err)
165-
goto out_failure;
166-
return I40E_XDP_REDIR;
164+
if (!err)
165+
return I40E_XDP_REDIR;
166+
if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err == -ENOBUFS)
167+
result = I40E_XDP_EXIT;
168+
else
169+
result = I40E_XDP_CONSUMED;
170+
goto out_failure;
167171
}
168172

169173
switch (act) {
@@ -175,16 +179,17 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
175179
if (result == I40E_XDP_CONSUMED)
176180
goto out_failure;
177181
break;
182+
case XDP_DROP:
183+
result = I40E_XDP_CONSUMED;
184+
break;
178185
default:
179186
bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act);
180187
fallthrough;
181188
case XDP_ABORTED:
189+
result = I40E_XDP_CONSUMED;
182190
out_failure:
183191
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
184192
fallthrough; /* handle aborts by dropping packet */
185-
case XDP_DROP:
186-
result = I40E_XDP_CONSUMED;
187-
break;
188193
}
189194
return result;
190195
}
@@ -271,7 +276,8 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring *rx_ring,
271276
unsigned int *rx_packets,
272277
unsigned int *rx_bytes,
273278
unsigned int size,
274-
unsigned int xdp_res)
279+
unsigned int xdp_res,
280+
bool *failure)
275281
{
276282
struct sk_buff *skb;
277283

@@ -281,11 +287,15 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring *rx_ring,
281287
if (likely(xdp_res == I40E_XDP_REDIR) || xdp_res == I40E_XDP_TX)
282288
return;
283289

290+
if (xdp_res == I40E_XDP_EXIT) {
291+
*failure = true;
292+
return;
293+
}
294+
284295
if (xdp_res == I40E_XDP_CONSUMED) {
285296
xsk_buff_free(xdp_buff);
286297
return;
287298
}
288-
289299
if (xdp_res == I40E_XDP_PASS) {
290300
/* NB! We are not checking for errors using
291301
* i40e_test_staterr with
@@ -371,7 +381,9 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
371381

372382
xdp_res = i40e_run_xdp_zc(rx_ring, bi);
373383
i40e_handle_xdp_result_zc(rx_ring, bi, rx_desc, &rx_packets,
374-
&rx_bytes, size, xdp_res);
384+
&rx_bytes, size, xdp_res, &failure);
385+
if (failure)
386+
break;
375387
total_rx_packets += rx_packets;
376388
total_rx_bytes += rx_bytes;
377389
xdp_xmit |= xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR);
@@ -382,7 +394,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
382394
cleaned_count = (next_to_clean - rx_ring->next_to_use - 1) & count_mask;
383395

384396
if (cleaned_count >= I40E_RX_BUFFER_WRITE)
385-
failure = !i40e_alloc_rx_buffers_zc(rx_ring, cleaned_count);
397+
failure |= !i40e_alloc_rx_buffers_zc(rx_ring, cleaned_count);
386398

387399
i40e_finalize_xdp_rx(rx_ring, xdp_xmit);
388400
i40e_update_rx_stats(rx_ring, total_rx_bytes, total_rx_packets);

0 commit comments

Comments
 (0)