Skip to content

Commit 468a195

Browse files
mfijalkoanguy11
authored andcommitted
ice: stop storing XDP verdict within ice_rx_buf
Idea behind having ice_rx_buf::act was to simplify and speed up the Rx data path by walking through buffers that were representing cleaned HW Rx descriptors. Since it caused us a major headache recently and we rolled back to old approach that 'puts' Rx buffers right after running XDP prog/creating skb, this is useless now and should be removed. Get rid of ice_rx_buf::act and related logic. We still need to take care of a corner case where XDP program releases a particular fragment. Make ice_run_xdp() to return its result and use it within ice_put_rx_mbuf(). Fixes: 2fba7dc ("ice: Add support for XDP multi-buffer on Rx side") Reviewed-by: Przemek Kitszel <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Maciej Fijalkowski <[email protected]> Tested-by: Chandan Kumar Rout <[email protected]> (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 11c4aa0 commit 468a195

File tree

3 files changed

+36
-70
lines changed

3 files changed

+36
-70
lines changed

drivers/net/ethernet/intel/ice/ice_txrx.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -527,15 +527,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring)
527527
* @xdp: xdp_buff used as input to the XDP program
528528
* @xdp_prog: XDP program to run
529529
* @xdp_ring: ring to be used for XDP_TX action
530-
* @rx_buf: Rx buffer to store the XDP action
531530
* @eop_desc: Last descriptor in packet to read metadata from
532531
*
533532
* Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
534533
*/
535-
static void
534+
static u32
536535
ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
537536
struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
538-
struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
537+
union ice_32b_rx_flex_desc *eop_desc)
539538
{
540539
unsigned int ret = ICE_XDP_PASS;
541540
u32 act;
@@ -574,7 +573,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
574573
ret = ICE_XDP_CONSUMED;
575574
}
576575
exit:
577-
ice_set_rx_bufs_act(xdp, rx_ring, ret);
576+
return ret;
578577
}
579578

580579
/**
@@ -860,10 +859,8 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
860859
xdp_buff_set_frags_flag(xdp);
861860
}
862861

863-
if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
864-
ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED);
862+
if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS))
865863
return -ENOMEM;
866-
}
867864

868865
__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page,
869866
rx_buf->page_offset, size);
@@ -1075,12 +1072,12 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
10751072
rx_buf->page_offset + headlen, size,
10761073
xdp->frame_sz);
10771074
} else {
1078-
/* buffer is unused, change the act that should be taken later
1079-
* on; data was copied onto skb's linear part so there's no
1075+
/* buffer is unused, restore biased page count in Rx buffer;
1076+
* data was copied onto skb's linear part so there's no
10801077
* need for adjusting page offset and we can reuse this buffer
10811078
* as-is
10821079
*/
1083-
rx_buf->act = ICE_SKB_CONSUMED;
1080+
rx_buf->pagecnt_bias++;
10841081
}
10851082

10861083
if (unlikely(xdp_buff_has_frags(xdp))) {
@@ -1133,29 +1130,34 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf)
11331130
* @xdp: XDP buffer carrying linear + frags part
11341131
* @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage
11351132
* @ntc: a current next_to_clean value to be stored at rx_ring
1133+
* @verdict: return code from XDP program execution
11361134
*
11371135
* Walk through gathered fragments and satisfy internal page
11381136
* recycle mechanism; we take here an action related to verdict
11391137
* returned by XDP program;
11401138
*/
11411139
static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
1142-
u32 *xdp_xmit, u32 ntc)
1140+
u32 *xdp_xmit, u32 ntc, u32 verdict)
11431141
{
11441142
u32 nr_frags = rx_ring->nr_frags + 1;
11451143
u32 idx = rx_ring->first_desc;
11461144
u32 cnt = rx_ring->count;
1145+
u32 post_xdp_frags = 1;
11471146
struct ice_rx_buf *buf;
11481147
int i;
11491148

1150-
for (i = 0; i < nr_frags; i++) {
1149+
if (unlikely(xdp_buff_has_frags(xdp)))
1150+
post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags;
1151+
1152+
for (i = 0; i < post_xdp_frags; i++) {
11511153
buf = &rx_ring->rx_buf[idx];
11521154

1153-
if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) {
1155+
if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) {
11541156
ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
1155-
*xdp_xmit |= buf->act;
1156-
} else if (buf->act & ICE_XDP_CONSUMED) {
1157+
*xdp_xmit |= verdict;
1158+
} else if (verdict & ICE_XDP_CONSUMED) {
11571159
buf->pagecnt_bias++;
1158-
} else if (buf->act == ICE_XDP_PASS) {
1160+
} else if (verdict == ICE_XDP_PASS) {
11591161
ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
11601162
}
11611163

@@ -1164,6 +1166,17 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
11641166
if (++idx == cnt)
11651167
idx = 0;
11661168
}
1169+
/* handle buffers that represented frags released by XDP prog;
1170+
* for these we keep pagecnt_bias as-is; refcount from struct page
1171+
* has been decremented within XDP prog and we do not have to increase
1172+
* the biased refcnt
1173+
*/
1174+
for (; i < nr_frags; i++) {
1175+
buf = &rx_ring->rx_buf[idx];
1176+
ice_put_rx_buf(rx_ring, buf);
1177+
if (++idx == cnt)
1178+
idx = 0;
1179+
}
11671180

11681181
xdp->data = NULL;
11691182
rx_ring->first_desc = ntc;
@@ -1190,9 +1203,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
11901203
struct ice_tx_ring *xdp_ring = NULL;
11911204
struct bpf_prog *xdp_prog = NULL;
11921205
u32 ntc = rx_ring->next_to_clean;
1206+
u32 cached_ntu, xdp_verdict;
11931207
u32 cnt = rx_ring->count;
11941208
u32 xdp_xmit = 0;
1195-
u32 cached_ntu;
11961209
bool failure;
11971210

11981211
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
@@ -1255,7 +1268,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
12551268
xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
12561269
xdp_buff_clear_frags_flag(xdp);
12571270
} else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
1258-
ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc);
1271+
ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED);
12591272
break;
12601273
}
12611274
if (++ntc == cnt)
@@ -1266,13 +1279,13 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
12661279
continue;
12671280

12681281
ice_get_pgcnts(rx_ring);
1269-
ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
1270-
if (rx_buf->act == ICE_XDP_PASS)
1282+
xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc);
1283+
if (xdp_verdict == ICE_XDP_PASS)
12711284
goto construct_skb;
12721285
total_rx_bytes += xdp_get_buff_len(xdp);
12731286
total_rx_pkts++;
12741287

1275-
ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
1288+
ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
12761289

12771290
continue;
12781291
construct_skb:
@@ -1283,12 +1296,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
12831296
/* exit if we failed to retrieve a buffer */
12841297
if (!skb) {
12851298
rx_ring->ring_stats->rx_stats.alloc_page_failed++;
1286-
rx_buf->act = ICE_XDP_CONSUMED;
1287-
if (unlikely(xdp_buff_has_frags(xdp)))
1288-
ice_set_rx_bufs_act(xdp, rx_ring,
1289-
ICE_XDP_CONSUMED);
1299+
xdp_verdict = ICE_XDP_CONSUMED;
12901300
}
1291-
ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
1301+
ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
12921302

12931303
if (!skb)
12941304
break;

drivers/net/ethernet/intel/ice/ice_txrx.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ struct ice_rx_buf {
201201
struct page *page;
202202
unsigned int page_offset;
203203
unsigned int pgcnt;
204-
unsigned int act;
205204
unsigned int pagecnt_bias;
206205
};
207206

drivers/net/ethernet/intel/ice/ice_txrx_lib.h

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,6 @@
55
#define _ICE_TXRX_LIB_H_
66
#include "ice.h"
77

8-
/**
9-
* ice_set_rx_bufs_act - propagate Rx buffer action to frags
10-
* @xdp: XDP buffer representing frame (linear and frags part)
11-
* @rx_ring: Rx ring struct
12-
* act: action to store onto Rx buffers related to XDP buffer parts
13-
*
14-
* Set action that should be taken before putting Rx buffer from first frag
15-
* to the last.
16-
*/
17-
static inline void
18-
ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring,
19-
const unsigned int act)
20-
{
21-
u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
22-
u32 nr_frags = rx_ring->nr_frags + 1;
23-
u32 idx = rx_ring->first_desc;
24-
u32 cnt = rx_ring->count;
25-
struct ice_rx_buf *buf;
26-
27-
for (int i = 0; i < nr_frags; i++) {
28-
buf = &rx_ring->rx_buf[idx];
29-
buf->act = act;
30-
31-
if (++idx == cnt)
32-
idx = 0;
33-
}
34-
35-
/* adjust pagecnt_bias on frags freed by XDP prog */
36-
if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) {
37-
u32 delta = rx_ring->nr_frags - sinfo_frags;
38-
39-
while (delta) {
40-
if (idx == 0)
41-
idx = cnt - 1;
42-
else
43-
idx--;
44-
buf = &rx_ring->rx_buf[idx];
45-
buf->pagecnt_bias--;
46-
delta--;
47-
}
48-
}
49-
}
50-
518
/**
529
* ice_test_staterr - tests bits in Rx descriptor status and error fields
5310
* @status_err_n: Rx descriptor status_error0 or status_error1 bits

0 commit comments

Comments
 (0)