mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-08 02:15:20 +02:00
ice: fix truesize operations for PAGE_SIZE >= 8192
[ Upstream commitd53d4dcce6
] When working on multi-buffer packet on arch that has PAGE_SIZE >= 8192, truesize is calculated and stored in xdp_buff::frame_sz per each processed Rx buffer. This means that frame_sz will contain the truesize based on last received buffer, but commit1dc1a7e7f4
("ice: Centrallize Rx buffer recycling") assumed this value will be constant for each buffer, which breaks the page recycling scheme and mess up the way we update the page::page_offset. To fix this, let us work on constant truesize when PAGE_SIZE >= 8192 instead of basing this on size of a packet read from Rx descriptor. This way we can simplify the code and avoid calculating truesize per each received frame and on top of that when using xdp_update_skb_shared_info(), current formula for truesize update will be valid. This means ice_rx_frame_truesize() can be removed altogether. Furthermore, first call to it within ice_clean_rx_irq() for 4k PAGE_SIZE was redundant as xdp_buff::frame_sz is initialized via xdp_init_buff() in ice_vsi_cfg_rxq(). This should have been removed at the point where xdp_buff struct started to be a member of ice_rx_ring and it was no longer a stack based variable. There are two fixes tags as my understanding is that the first one exposed us to broken truesize and page_offset handling and then second introduced broken skb_shared_info update in ice_{construct,build}_skb(). Reported-and-tested-by: Luiz Capitulino <luizcap@redhat.com> Closes: https://lore.kernel.org/netdev/8f9e2a5c-fd30-4206-9311-946a06d031bb@redhat.com/ Fixes:1dc1a7e7f4
("ice: Centrallize Rx buffer recycling") Fixes:2fba7dc515
("ice: Add support for XDP multi-buffer on Rx side") Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
e9a1df12d5
commit
c864bf0166
|
@ -519,6 +519,25 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_frame_sz - calculate xdp_buff::frame_sz
|
||||
* @rx_ring: the ring being configured
|
||||
*
|
||||
* Return frame size based on underlying PAGE_SIZE
|
||||
*/
|
||||
static unsigned int ice_get_frame_sz(struct ice_rx_ring *rx_ring)
|
||||
{
|
||||
unsigned int frame_sz;
|
||||
|
||||
#if (PAGE_SIZE >= 8192)
|
||||
frame_sz = rx_ring->rx_buf_len;
|
||||
#else
|
||||
frame_sz = ice_rx_pg_size(rx_ring) / 2;
|
||||
#endif
|
||||
|
||||
return frame_sz;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_cfg_rxq - Configure an Rx queue
|
||||
* @ring: the ring being configured
|
||||
|
@ -582,7 +601,7 @@ int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
|
|||
}
|
||||
}
|
||||
|
||||
xdp_init_buff(&ring->xdp, ice_rx_pg_size(ring) / 2, &ring->xdp_rxq);
|
||||
xdp_init_buff(&ring->xdp, ice_get_frame_sz(ring), &ring->xdp_rxq);
|
||||
ring->xdp.data = NULL;
|
||||
err = ice_setup_rx_ctx(ring);
|
||||
if (err) {
|
||||
|
|
|
@ -521,30 +521,6 @@ err:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_rx_frame_truesize
|
||||
* @rx_ring: ptr to Rx ring
|
||||
* @size: size
|
||||
*
|
||||
* calculate the truesize with taking into the account PAGE_SIZE of
|
||||
* underlying arch
|
||||
*/
|
||||
static unsigned int
|
||||
ice_rx_frame_truesize(struct ice_rx_ring *rx_ring, const unsigned int size)
|
||||
{
|
||||
unsigned int truesize;
|
||||
|
||||
#if (PAGE_SIZE < 8192)
|
||||
truesize = ice_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
|
||||
#else
|
||||
truesize = rx_ring->rx_offset ?
|
||||
SKB_DATA_ALIGN(rx_ring->rx_offset + size) +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
|
||||
SKB_DATA_ALIGN(size);
|
||||
#endif
|
||||
return truesize;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_run_xdp - Executes an XDP program on initialized xdp_buff
|
||||
* @rx_ring: Rx ring
|
||||
|
@ -1152,11 +1128,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
|
|||
bool failure;
|
||||
u32 first;
|
||||
|
||||
/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
|
||||
#if (PAGE_SIZE < 8192)
|
||||
xdp->frame_sz = ice_rx_frame_truesize(rx_ring, 0);
|
||||
#endif
|
||||
|
||||
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
|
||||
if (xdp_prog) {
|
||||
xdp_ring = rx_ring->xdp_ring;
|
||||
|
@ -1216,10 +1187,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
|
|||
hard_start = page_address(rx_buf->page) + rx_buf->page_offset -
|
||||
offset;
|
||||
xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
|
||||
#if (PAGE_SIZE > 4096)
|
||||
/* At larger PAGE_SIZE, frame_sz depend on len size */
|
||||
xdp->frame_sz = ice_rx_frame_truesize(rx_ring, size);
|
||||
#endif
|
||||
xdp_buff_clear_frags_flag(xdp);
|
||||
} else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user