dpaa2-eth: fix xdp_rxq_info leak

[ Upstream commit 2def09ead4ad5907988b655d1e1454003aaf8297 ]

The driver registered xdp_rxq_info structures via xdp_rxq_info_reg()
but failed to properly unregister them in error paths and during
removal.

Fixes: d678be1dc1 ("dpaa2-eth: add XDP_REDIRECT support")
Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Link: https://patch.msgid.link/20250626133003.80136-1-wangfushuai@baidu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Fushuai Wang
2025-06-26 21:30:03 +08:00
committed by Greg Kroah-Hartman
parent 31afd30797
commit 7e6423f80b

View File

@@ -3928,6 +3928,7 @@ static int dpaa2_eth_setup_rx_flow(struct dpaa2_eth_priv *priv,
MEM_TYPE_PAGE_ORDER0, NULL); MEM_TYPE_PAGE_ORDER0, NULL);
if (err) { if (err) {
dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n"); dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n");
xdp_rxq_info_unreg(&fq->channel->xdp_rxq);
return err; return err;
} }
@@ -4421,17 +4422,25 @@ static int dpaa2_eth_bind_dpni(struct dpaa2_eth_priv *priv)
return -EINVAL; return -EINVAL;
} }
if (err) if (err)
return err; goto out;
} }
err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token, err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token,
DPNI_QUEUE_TX, &priv->tx_qdid); DPNI_QUEUE_TX, &priv->tx_qdid);
if (err) { if (err) {
dev_err(dev, "dpni_get_qdid() failed\n"); dev_err(dev, "dpni_get_qdid() failed\n");
return err; goto out;
} }
return 0; return 0;
out:
while (i--) {
if (priv->fq[i].type == DPAA2_RX_FQ &&
xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
}
return err;
} }
/* Allocate rings for storing incoming frame descriptors */ /* Allocate rings for storing incoming frame descriptors */
@@ -4813,6 +4822,17 @@ static void dpaa2_eth_del_ch_napi(struct dpaa2_eth_priv *priv)
} }
} }
static void dpaa2_eth_free_rx_xdp_rxq(struct dpaa2_eth_priv *priv)
{
int i;
for (i = 0; i < priv->num_fqs; i++) {
if (priv->fq[i].type == DPAA2_RX_FQ &&
xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
}
}
static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
{ {
struct device *dev; struct device *dev;
@@ -5016,6 +5036,7 @@ err_alloc_percpu_extras:
free_percpu(priv->percpu_stats); free_percpu(priv->percpu_stats);
err_alloc_percpu_stats: err_alloc_percpu_stats:
dpaa2_eth_del_ch_napi(priv); dpaa2_eth_del_ch_napi(priv);
dpaa2_eth_free_rx_xdp_rxq(priv);
err_bind: err_bind:
dpaa2_eth_free_dpbps(priv); dpaa2_eth_free_dpbps(priv);
err_dpbp_setup: err_dpbp_setup:
@@ -5068,6 +5089,7 @@ static void dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
free_percpu(priv->percpu_extras); free_percpu(priv->percpu_extras);
dpaa2_eth_del_ch_napi(priv); dpaa2_eth_del_ch_napi(priv);
dpaa2_eth_free_rx_xdp_rxq(priv);
dpaa2_eth_free_dpbps(priv); dpaa2_eth_free_dpbps(priv);
dpaa2_eth_free_dpio(priv); dpaa2_eth_free_dpio(priv);
dpaa2_eth_free_dpni(priv); dpaa2_eth_free_dpni(priv);