Skip to content

Commit afd50da

Browse files
committed
Merge branch 'enetc-unlock-xdp_redirect-for-xdp-non-linear-buffers'
Lorenzo Bianconi says: ==================== enetc: unlock XDP_REDIRECT for XDP non-linear buffers Unlock XDP_REDIRECT for S/G XDP buffer and rely on XDP stack to properly take care of the frames. Rely on XDP_FLAGS_HAS_FRAGS flag to check if it really necessary to access non-linear part of the xdp_buff/xdp_frame. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 4aea86b + c7030d1 commit afd50da

File tree

3 files changed

+18
-23
lines changed

3 files changed

+18
-23
lines changed

drivers/net/ethernet/freescale/enetc/enetc.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,10 @@ static int enetc_xdp_frame_to_xdp_tx_swbd(struct enetc_bdr *tx_ring,
13051305
xdp_tx_swbd->xdp_frame = NULL;
13061306

13071307
n++;
1308+
1309+
if (!xdp_frame_has_frags(xdp_frame))
1310+
goto out;
1311+
13081312
xdp_tx_swbd = &xdp_tx_arr[n];
13091313

13101314
shinfo = xdp_get_shared_info_from_frame(xdp_frame);
@@ -1334,7 +1338,7 @@ static int enetc_xdp_frame_to_xdp_tx_swbd(struct enetc_bdr *tx_ring,
13341338
n++;
13351339
xdp_tx_swbd = &xdp_tx_arr[n];
13361340
}
1337-
1341+
out:
13381342
xdp_tx_arr[n - 1].is_eof = true;
13391343
xdp_tx_arr[n - 1].xdp_frame = xdp_frame;
13401344

@@ -1390,28 +1394,36 @@ static void enetc_map_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,
13901394
{
13911395
struct enetc_rx_swbd *rx_swbd = enetc_get_rx_buff(rx_ring, i, size);
13921396
void *hard_start = page_address(rx_swbd->page) + rx_swbd->page_offset;
1393-
struct skb_shared_info *shinfo;
13941397

13951398
/* To be used for XDP_TX */
13961399
rx_swbd->len = size;
13971400

13981401
xdp_prepare_buff(xdp_buff, hard_start - rx_ring->buffer_offset,
13991402
rx_ring->buffer_offset, size, false);
1400-
1401-
shinfo = xdp_get_shared_info_from_buff(xdp_buff);
1402-
shinfo->nr_frags = 0;
14031403
}
14041404

14051405
static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,
14061406
u16 size, struct xdp_buff *xdp_buff)
14071407
{
14081408
struct skb_shared_info *shinfo = xdp_get_shared_info_from_buff(xdp_buff);
14091409
struct enetc_rx_swbd *rx_swbd = enetc_get_rx_buff(rx_ring, i, size);
1410-
skb_frag_t *frag = &shinfo->frags[shinfo->nr_frags];
1410+
skb_frag_t *frag;
14111411

14121412
/* To be used for XDP_TX */
14131413
rx_swbd->len = size;
14141414

1415+
if (!xdp_buff_has_frags(xdp_buff)) {
1416+
xdp_buff_set_frags_flag(xdp_buff);
1417+
shinfo->xdp_frags_size = size;
1418+
shinfo->nr_frags = 0;
1419+
} else {
1420+
shinfo->xdp_frags_size += size;
1421+
}
1422+
1423+
if (page_is_pfmemalloc(rx_swbd->page))
1424+
xdp_buff_set_frag_pfmemalloc(xdp_buff);
1425+
1426+
frag = &shinfo->frags[shinfo->nr_frags];
14151427
skb_frag_off_set(frag, rx_swbd->page_offset);
14161428
skb_frag_size_set(frag, size);
14171429
__skb_frag_set_page(frag, rx_swbd->page);
@@ -1584,20 +1596,6 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
15841596
}
15851597
break;
15861598
case XDP_REDIRECT:
1587-
/* xdp_return_frame does not support S/G in the sense
1588-
* that it leaks the fragments (__xdp_return should not
1589-
* call page_frag_free only for the initial buffer).
1590-
* Until XDP_REDIRECT gains support for S/G let's keep
1591-
* the code structure in place, but dead. We drop the
1592-
* S/G frames ourselves to avoid memory leaks which
1593-
* would otherwise leave the kernel OOM.
1594-
*/
1595-
if (unlikely(cleaned_cnt - orig_cleaned_cnt != 1)) {
1596-
enetc_xdp_drop(rx_ring, orig_i, i);
1597-
rx_ring->stats.xdp_redirect_sg++;
1598-
break;
1599-
}
1600-
16011599
err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog);
16021600
if (unlikely(err)) {
16031601
enetc_xdp_drop(rx_ring, orig_i, i);

drivers/net/ethernet/freescale/enetc/enetc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ struct enetc_ring_stats {
7070
unsigned int xdp_tx_drops;
7171
unsigned int xdp_redirect;
7272
unsigned int xdp_redirect_failures;
73-
unsigned int xdp_redirect_sg;
7473
unsigned int recycles;
7574
unsigned int recycle_failures;
7675
unsigned int win_drop;

drivers/net/ethernet/freescale/enetc/enetc_ethtool.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
197197
"Rx ring %2d recycle failures",
198198
"Rx ring %2d redirects",
199199
"Rx ring %2d redirect failures",
200-
"Rx ring %2d redirect S/G",
201200
};
202201

203202
static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
@@ -291,7 +290,6 @@ static void enetc_get_ethtool_stats(struct net_device *ndev,
291290
data[o++] = priv->rx_ring[i]->stats.recycle_failures;
292291
data[o++] = priv->rx_ring[i]->stats.xdp_redirect;
293292
data[o++] = priv->rx_ring[i]->stats.xdp_redirect_failures;
294-
data[o++] = priv->rx_ring[i]->stats.xdp_redirect_sg;
295293
}
296294

297295
if (!enetc_si_is_pf(priv->si))

0 commit comments

Comments
 (0)