@@ -1305,6 +1305,10 @@ static int enetc_xdp_frame_to_xdp_tx_swbd(struct enetc_bdr *tx_ring,
1305
1305
xdp_tx_swbd -> xdp_frame = NULL ;
1306
1306
1307
1307
n ++ ;
1308
+
1309
+ if (!xdp_frame_has_frags (xdp_frame ))
1310
+ goto out ;
1311
+
1308
1312
xdp_tx_swbd = & xdp_tx_arr [n ];
1309
1313
1310
1314
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,
1334
1338
n ++ ;
1335
1339
xdp_tx_swbd = & xdp_tx_arr [n ];
1336
1340
}
1337
-
1341
+ out :
1338
1342
xdp_tx_arr [n - 1 ].is_eof = true;
1339
1343
xdp_tx_arr [n - 1 ].xdp_frame = xdp_frame ;
1340
1344
@@ -1390,28 +1394,36 @@ static void enetc_map_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,
1390
1394
{
1391
1395
struct enetc_rx_swbd * rx_swbd = enetc_get_rx_buff (rx_ring , i , size );
1392
1396
void * hard_start = page_address (rx_swbd -> page ) + rx_swbd -> page_offset ;
1393
- struct skb_shared_info * shinfo ;
1394
1397
1395
1398
/* To be used for XDP_TX */
1396
1399
rx_swbd -> len = size ;
1397
1400
1398
1401
xdp_prepare_buff (xdp_buff , hard_start - rx_ring -> buffer_offset ,
1399
1402
rx_ring -> buffer_offset , size , false);
1400
-
1401
- shinfo = xdp_get_shared_info_from_buff (xdp_buff );
1402
- shinfo -> nr_frags = 0 ;
1403
1403
}
1404
1404
1405
1405
static void enetc_add_rx_buff_to_xdp (struct enetc_bdr * rx_ring , int i ,
1406
1406
u16 size , struct xdp_buff * xdp_buff )
1407
1407
{
1408
1408
struct skb_shared_info * shinfo = xdp_get_shared_info_from_buff (xdp_buff );
1409
1409
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 ;
1411
1411
1412
1412
/* To be used for XDP_TX */
1413
1413
rx_swbd -> len = size ;
1414
1414
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 ];
1415
1427
skb_frag_off_set (frag , rx_swbd -> page_offset );
1416
1428
skb_frag_size_set (frag , size );
1417
1429
__skb_frag_set_page (frag , rx_swbd -> page );
@@ -1584,20 +1596,6 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
1584
1596
}
1585
1597
break ;
1586
1598
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
-
1601
1599
err = xdp_do_redirect (rx_ring -> ndev , & xdp_buff , prog );
1602
1600
if (unlikely (err )) {
1603
1601
enetc_xdp_drop (rx_ring , orig_i , i );
0 commit comments