dpaa2-eth: execute xdp_do_flush() before napi_complete_done()
[ Upstream commit a3191c4d86c5d3bd35b00dfde6910b88391436a0 ] Make sure that xdp_do_flush() is always executed before napi_complete_done(). This is important for two reasons. First, a redirect to an XSKMAP assumes that a call to xdp_do_redirect() from napi context X on CPU Y will be followed by a xdp_do_flush() from the same napi context and CPU. This is not guaranteed if the napi_complete_done() is executed before xdp_do_flush(), as it tells the napi logic that it is fine to schedule napi context X on another CPU. Details from a production system triggering this bug using the veth driver can be found following the first link below. The second reason is that the XDP_REDIRECT logic in itself relies on being inside a single NAPI instance through to the xdp_do_flush() call for RCU protection of all in-kernel data structures. Details can be found in the second link below. Fixes: d678be1dc1ec ("dpaa2-eth: add XDP_REDIRECT support") Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com> Acked-by: Toke Høiland-Jørgensen <toke@redhat.com> Link: https://lore.kernel.org/r/20221220185903.1105011-1-sbohrer@cloudflare.com Link: https://lore.kernel.org/all/20210624160609.292325-1-toke@redhat.com/ Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
71a773ab79
commit
9e0d874c0a
@ -1868,10 +1868,15 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
|
||||
if (rx_cleaned >= budget ||
|
||||
txconf_cleaned >= DPAA2_ETH_TXCONF_PER_NAPI) {
|
||||
work_done = budget;
|
||||
if (ch->xdp.res & XDP_REDIRECT)
|
||||
xdp_do_flush();
|
||||
goto out;
|
||||
}
|
||||
} while (store_cleaned);
|
||||
|
||||
if (ch->xdp.res & XDP_REDIRECT)
|
||||
xdp_do_flush();
|
||||
|
||||
/* Update NET DIM with the values for this CDAN */
|
||||
dpaa2_io_update_net_dim(ch->dpio, ch->stats.frames_per_cdan,
|
||||
ch->stats.bytes_per_cdan);
|
||||
@ -1902,9 +1907,7 @@ out:
|
||||
txc_fq->dq_bytes = 0;
|
||||
}
|
||||
|
||||
if (ch->xdp.res & XDP_REDIRECT)
|
||||
xdp_do_flush_map();
|
||||
else if (rx_cleaned && ch->xdp.res & XDP_TX)
|
||||
if (rx_cleaned && ch->xdp.res & XDP_TX)
|
||||
dpaa2_eth_xdp_tx_flush(priv, ch, &priv->fq[flowid]);
|
||||
|
||||
return work_done;
|
||||
|
Loading…
x
Reference in New Issue
Block a user