mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
net: ethernet: mtk_eth_soc: fix memory leak in error path
In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed,
the rhashtable ppe->l2_flows isn't destroyed. Fix it.
In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or
register_netdev() failed, have the same problem. Fix it.
Fixes: 33fc42de33 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
8110437e59
commit
603ea5e7ff
|
|
@ -4147,13 +4147,13 @@ static int mtk_probe(struct platform_device *pdev)
|
||||||
eth->soc->offload_version, i);
|
eth->soc->offload_version, i);
|
||||||
if (!eth->ppe[i]) {
|
if (!eth->ppe[i]) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_deinit_mdio;
|
goto err_deinit_ppe;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mtk_eth_offload_init(eth);
|
err = mtk_eth_offload_init(eth);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_deinit_mdio;
|
goto err_deinit_ppe;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MTK_MAX_DEVS; i++) {
|
for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||||
|
|
@ -4163,7 +4163,7 @@ static int mtk_probe(struct platform_device *pdev)
|
||||||
err = register_netdev(eth->netdev[i]);
|
err = register_netdev(eth->netdev[i]);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(eth->dev, "error bringing up device\n");
|
dev_err(eth->dev, "error bringing up device\n");
|
||||||
goto err_deinit_mdio;
|
goto err_deinit_ppe;
|
||||||
} else
|
} else
|
||||||
netif_info(eth, probe, eth->netdev[i],
|
netif_info(eth, probe, eth->netdev[i],
|
||||||
"mediatek frame engine at 0x%08lx, irq %d\n",
|
"mediatek frame engine at 0x%08lx, irq %d\n",
|
||||||
|
|
@ -4181,7 +4181,8 @@ static int mtk_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_deinit_mdio:
|
err_deinit_ppe:
|
||||||
|
mtk_ppe_deinit(eth);
|
||||||
mtk_mdio_cleanup(eth);
|
mtk_mdio_cleanup(eth);
|
||||||
err_free_dev:
|
err_free_dev:
|
||||||
mtk_free_dev(eth);
|
mtk_free_dev(eth);
|
||||||
|
|
|
||||||
|
|
@ -737,7 +737,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
|
||||||
MTK_PPE_ENTRIES * soc->foe_entry_size,
|
MTK_PPE_ENTRIES * soc->foe_entry_size,
|
||||||
&ppe->foe_phys, GFP_KERNEL);
|
&ppe->foe_phys, GFP_KERNEL);
|
||||||
if (!foe)
|
if (!foe)
|
||||||
return NULL;
|
goto err_free_l2_flows;
|
||||||
|
|
||||||
ppe->foe_table = foe;
|
ppe->foe_table = foe;
|
||||||
|
|
||||||
|
|
@ -745,11 +745,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
|
||||||
sizeof(*ppe->foe_flow);
|
sizeof(*ppe->foe_flow);
|
||||||
ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
|
ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
|
||||||
if (!ppe->foe_flow)
|
if (!ppe->foe_flow)
|
||||||
return NULL;
|
goto err_free_l2_flows;
|
||||||
|
|
||||||
mtk_ppe_debugfs_init(ppe, index);
|
mtk_ppe_debugfs_init(ppe, index);
|
||||||
|
|
||||||
return ppe;
|
return ppe;
|
||||||
|
|
||||||
|
err_free_l2_flows:
|
||||||
|
rhashtable_destroy(&ppe->l2_flows);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mtk_ppe_deinit(struct mtk_eth *eth)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) {
|
||||||
|
if (!eth->ppe[i])
|
||||||
|
return;
|
||||||
|
rhashtable_destroy(ð->ppe[i]->l2_flows);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
|
static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ struct mtk_ppe {
|
||||||
|
|
||||||
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
|
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
|
||||||
int version, int index);
|
int version, int index);
|
||||||
|
void mtk_ppe_deinit(struct mtk_eth *eth);
|
||||||
void mtk_ppe_start(struct mtk_ppe *ppe);
|
void mtk_ppe_start(struct mtk_ppe *ppe);
|
||||||
int mtk_ppe_stop(struct mtk_ppe *ppe);
|
int mtk_ppe_stop(struct mtk_ppe *ppe);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user