mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
xsk: make xsk_buff_add_frag() really add the frag via __xdp_buff_add_frag()
Currently, xsk_buff_add_frag() only adds the frag to pool's linked list, not doing anything with the &xdp_buff. The drivers do that manually and the logic is the same. Make it really add an skb frag, just like xdp_buff_add_frag() does that, and freeing frags on error if needed. This allows to remove repeating code from i40e and ice and not add the same code again and again. Acked-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com> Link: https://patch.msgid.link/20241218174435.1445282-5-aleksander.lobakin@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
539c1fba1a
commit
51205f841a
|
|
@ -395,32 +395,6 @@ static void i40e_handle_xdp_result_zc(struct i40e_ring *rx_ring,
|
|||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
static int
|
||||
i40e_add_xsk_frag(struct i40e_ring *rx_ring, struct xdp_buff *first,
|
||||
struct xdp_buff *xdp, const unsigned int size)
|
||||
{
|
||||
struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(first);
|
||||
|
||||
if (!xdp_buff_has_frags(first)) {
|
||||
sinfo->nr_frags = 0;
|
||||
sinfo->xdp_frags_size = 0;
|
||||
xdp_buff_set_frags_flag(first);
|
||||
}
|
||||
|
||||
if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
|
||||
xsk_buff_free(first);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++,
|
||||
virt_to_page(xdp->data_hard_start),
|
||||
XDP_PACKET_HEADROOM, size);
|
||||
sinfo->xdp_frags_size += size;
|
||||
xsk_buff_add_frag(xdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_clean_rx_irq_zc - Consumes Rx packets from the hardware ring
|
||||
* @rx_ring: Rx ring
|
||||
|
|
@ -486,8 +460,10 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget)
|
|||
|
||||
if (!first)
|
||||
first = bi;
|
||||
else if (i40e_add_xsk_frag(rx_ring, first, bi, size))
|
||||
else if (!xsk_buff_add_frag(first, bi)) {
|
||||
xsk_buff_free(first);
|
||||
break;
|
||||
}
|
||||
|
||||
if (++next_to_process == count)
|
||||
next_to_process = 0;
|
||||
|
|
|
|||
|
|
@ -801,35 +801,6 @@ ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
|
|||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
ice_add_xsk_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *first,
|
||||
struct xdp_buff *xdp, const unsigned int size)
|
||||
{
|
||||
struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(first);
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
if (!xdp_buff_has_frags(first)) {
|
||||
sinfo->nr_frags = 0;
|
||||
sinfo->xdp_frags_size = 0;
|
||||
xdp_buff_set_frags_flag(first);
|
||||
}
|
||||
|
||||
if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
|
||||
xsk_buff_free(first);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++,
|
||||
virt_to_page(xdp->data_hard_start),
|
||||
XDP_PACKET_HEADROOM, size);
|
||||
sinfo->xdp_frags_size += size;
|
||||
xsk_buff_add_frag(xdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_clean_rx_irq_zc - consumes packets from the hardware ring
|
||||
* @rx_ring: AF_XDP Rx ring
|
||||
|
|
@ -895,7 +866,8 @@ int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring,
|
|||
|
||||
if (!first) {
|
||||
first = xdp;
|
||||
} else if (ice_add_xsk_frag(rx_ring, first, xdp, size)) {
|
||||
} else if (likely(size) && !xsk_buff_add_frag(first, xdp)) {
|
||||
xsk_buff_free(first);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,11 +136,21 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
|
|||
xp_free(xskb);
|
||||
}
|
||||
|
||||
static inline void xsk_buff_add_frag(struct xdp_buff *xdp)
|
||||
static inline bool xsk_buff_add_frag(struct xdp_buff *head,
|
||||
struct xdp_buff *xdp)
|
||||
{
|
||||
struct xdp_buff_xsk *frag = container_of(xdp, struct xdp_buff_xsk, xdp);
|
||||
const void *data = xdp->data;
|
||||
struct xdp_buff_xsk *frag;
|
||||
|
||||
if (!__xdp_buff_add_frag(head, virt_to_netmem(data),
|
||||
offset_in_page(data), xdp->data_end - data,
|
||||
xdp->frame_sz, false))
|
||||
return false;
|
||||
|
||||
frag = container_of(xdp, struct xdp_buff_xsk, xdp);
|
||||
list_add_tail(&frag->list_node, &frag->pool->xskb_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline struct xdp_buff *xsk_buff_get_frag(const struct xdp_buff *first)
|
||||
|
|
@ -357,8 +367,10 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
|
|||
{
|
||||
}
|
||||
|
||||
static inline void xsk_buff_add_frag(struct xdp_buff *xdp)
|
||||
static inline bool xsk_buff_add_frag(struct xdp_buff *head,
|
||||
struct xdp_buff *xdp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct xdp_buff *xsk_buff_get_frag(const struct xdp_buff *first)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user