enetc: unlock XDP_REDIRECT for XDP non-linear buffers
Subsystems (3)
cover 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.
Lorenzo Bianconi (3):
net: ethernet: enetc: unlock XDP_REDIRECT for XDP non-linear buffers
net: ethernet: enetc: get rid of xdp_redirect_sg counter
net: ethernet: enetc: do not always access skb_shared_info in the XDP
path
drivers/net/ethernet/freescale/enetc/enetc.c | 38 +++++++++---------- drivers/net/ethernet/freescale/enetc/enetc.h | 1 - .../ethernet/freescale/enetc/enetc_ethtool.c | 2 - 3 files changed, 18 insertions(+), 23 deletions(-)
Signature · 1 line
2.39.0
PATCH 1/3 net: ethernet: enetc: unlock XDP_REDIRECT for XDP non-linear buffers
Even if full XDP_REDIRECT is not supported yet for non-linear XDP buffers since we allow redirecting just into CPUMAPs, unlock XDP_REDIRECT for S/G XDP buffer and rely on XDP stack to properly take care of the frames.
--- drivers/net/ethernet/freescale/enetc/enetc.c | 24 ++++++++------------ 1 file changed, 10 insertions(+), 14 deletions(-)
drivers/net/ethernet/freescale/enetc/enetc.c +10 -14
@@ -1412,6 +1412,16 @@ static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,/* To be used for XDP_TX */ rx_swbd->len = size; +if (!xdp_buff_has_frags (xdp_buff)) { +xdp_buff_set_frags_flag (xdp_buff); + shinfo->xdp_frags_size = size; + }else { + shinfo->xdp_frags_size += size; + } + +if (page_is_pfmemalloc (rx_swbd->page)) +xdp_buff_set_frag_pfmemalloc (xdp_buff); +skb_frag_off_set (frag, rx_swbd->page_offset);skb_frag_size_set (frag, size);__skb_frag_set_page (frag, rx_swbd->page);
@@ -1584,20 +1594,6 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, }break ;case XDP_REDIRECT : -/* xdp_return_frame does not support S/G in the sense -* that it leaks the fragments (__xdp_return should not -* call page_frag_free only for the initial buffer). -* Until XDP_REDIRECT gains support for S/G let's keep -* the code structure in place, but dead. We drop the -* S/G frames ourselves to avoid memory leaks which -* would otherwise leave the kernel OOM. -*/ -if (unlikely (cleaned_cnt - orig_cleaned_cnt !=1 )) { -enetc_xdp_drop (rx_ring, orig_i, i); - rx_ring->stats.xdp_redirect_sg++; -break ; - } - err =xdp_do_redirect (rx_ring->ndev, &xdp_buff, prog);if (unlikely (err)) {enetc_xdp_drop (rx_ring, orig_i, i);
Signature · 1 line
2.39.0
PATCH 2/3 net: ethernet: enetc: get rid of xdp_redirect_sg counter
In reply to Lorenzo BianconiRemove xdp_redirect_sg counter and the related ethtool entry since it is no longer used.
--- drivers/net/ethernet/freescale/enetc/enetc.h | 1 - drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 2 -- 2 files changed, 3 deletions(-)
drivers/net/ethernet/freescale/enetc/enetc.h +0 -1
@@ -70,7 +70,6 @@ struct enetc_ring_stats {unsigned int xdp_tx_drops;unsigned int xdp_redirect;unsigned int xdp_redirect_failures; -unsigned int xdp_redirect_sg;unsigned int recycles;unsigned int recycle_failures;unsigned int win_drop;
drivers/net/ethernet/freescale/enetc/enetc_ethtool.c +0 -2
@@ -197,7 +197,6 @@ static const char rx_ring_stats[][ETH_GSTRING_LEN] = {"Rx ring %2d recycle failures" ,"Rx ring %2d redirects" , "Rx ring %2d redirect failures", - "Rx ring %2d redirect S/G", }; static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
@@ -291,7 +290,6 @@ static void enetc_get_ethtool_stats(struct net_device *ndev, data[o++] = priv->rx_ring[i]->stats.recycle_failures; data[o++] = priv->rx_ring[i]->stats.xdp_redirect; data[o++] = priv->rx_ring[i]->stats.xdp_redirect_failures; - data[o++] = priv->rx_ring[i]->stats.xdp_redirect_sg; }if (!enetc_si_is_pf (priv->si))
Signature · 1 line
2.39.0
PATCH 3/3 net: ethernet: enetc: do not always access skb_shared_info in the XDP path
In reply to Lorenzo BianconiMove XDP skb_shared_info structure initialization in from enetc_map_rx_buff_to_xdp() to enetc_add_rx_buff_to_xdp() and do not always access skb_shared_info in the xdp_buff/xdp_frame since it is located in a different cacheline with respect to hard_start and data xdp pointers. Rely on XDP_FLAGS_HAS_FRAGS flag to check if it really necessary to access non-linear part of the xdp_buff/xdp_frame.
--- drivers/net/ethernet/freescale/enetc/enetc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/ethernet/freescale/enetc/enetc.c +8 -6
@@ -1305,6 +1305,10 @@ static int enetc_xdp_frame_to_xdp_tx_swbd(struct enetc_bdr *tx_ring, xdp_tx_swbd->xdp_frame =NULL ; n++; + +if (!xdp_frame_has_frags (xdp_frame)) + goto out; + xdp_tx_swbd = &xdp_tx_arr[n]; 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, n++; xdp_tx_swbd = &xdp_tx_arr[n]; } - +out: xdp_tx_arr[n -1 ].is_eof = true; xdp_tx_arr[n -1 ].xdp_frame = xdp_frame;
@@ -1390,16 +1394,12 @@ static void enetc_map_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i, {struct enetc_rx_swbd *rx_swbd =enetc_get_rx_buff (rx_ring, i, size);void *hard_start =page_address (rx_swbd->page) + rx_swbd->page_offset; -struct skb_shared_info *shinfo;/* To be used for XDP_TX */ rx_swbd->len = size;xdp_prepare_buff (xdp_buff, hard_start - rx_ring->buffer_offset, rx_ring->buffer_offset, size, false); - - shinfo =xdp_get_shared_info_from_buff (xdp_buff); - shinfo->nr_frags =0 ; } static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,
@@ -1407,7 +1407,7 @@ static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i, {struct skb_shared_info *shinfo =xdp_get_shared_info_from_buff (xdp_buff);struct enetc_rx_swbd *rx_swbd =enetc_get_rx_buff (rx_ring, i, size); -skb_frag_t *frag = &shinfo->frags[shinfo->nr_frags]; +skb_frag_t *frag;/* To be used for XDP_TX */ rx_swbd->len = size;
@@ -1415,6 +1415,7 @@ static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,if (!xdp_buff_has_frags (xdp_buff)) {xdp_buff_set_frags_flag (xdp_buff); shinfo->xdp_frags_size = size; + shinfo->nr_frags =0 ; }else { shinfo->xdp_frags_size += size; }
@@ -1422,6 +1423,7 @@ static void enetc_add_rx_buff_to_xdp(struct enetc_bdr *rx_ring, int i,if (page_is_pfmemalloc (rx_swbd->page))xdp_buff_set_frag_pfmemalloc (xdp_buff); + frag = &shinfo->frags[shinfo->nr_frags];skb_frag_off_set (frag, rx_swbd->page_offset);skb_frag_size_set (frag, size);__skb_frag_set_page (frag, rx_swbd->page);
Signature · 1 line
2.39.0