net: ethernet: mtk_eth_soc: fix memory leak in error path
authorYan Cangang <nalanzeyu@gmail.com>
Sun, 20 Nov 2022 05:52:59 +0000 (13:52 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 23 Nov 2022 04:16:45 +0000 (20:16 -0800)
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: 33fc42de3327 ("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>
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mediatek/mtk_ppe.c
drivers/net/ethernet/mediatek/mtk_ppe.h

index ae073b4..1d36619 100644 (file)
@@ -4147,13 +4147,13 @@ static int mtk_probe(struct platform_device *pdev)
                                                   eth->soc->offload_version, i);
                        if (!eth->ppe[i]) {
                                err = -ENOMEM;
-                               goto err_deinit_mdio;
+                               goto err_deinit_ppe;
                        }
                }
 
                err = mtk_eth_offload_init(eth);
                if (err)
-                       goto err_deinit_mdio;
+                       goto err_deinit_ppe;
        }
 
        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]);
                if (err) {
                        dev_err(eth->dev, "error bringing up device\n");
-                       goto err_deinit_mdio;
+                       goto err_deinit_ppe;
                } else
                        netif_info(eth, probe, eth->netdev[i],
                                   "mediatek frame engine at 0x%08lx, irq %d\n",
@@ -4181,7 +4181,8 @@ static int mtk_probe(struct platform_device *pdev)
 
        return 0;
 
-err_deinit_mdio:
+err_deinit_ppe:
+       mtk_ppe_deinit(eth);
        mtk_mdio_cleanup(eth);
 err_free_dev:
        mtk_free_dev(eth);
index 2d8ca99..784ecb2 100644 (file)
@@ -737,7 +737,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
                                  MTK_PPE_ENTRIES * soc->foe_entry_size,
                                  &ppe->foe_phys, GFP_KERNEL);
        if (!foe)
-               return NULL;
+               goto err_free_l2_flows;
 
        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);
        ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
        if (!ppe->foe_flow)
-               return NULL;
+               goto err_free_l2_flows;
 
        mtk_ppe_debugfs_init(ppe, index);
 
        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(&eth->ppe[i]->l2_flows);
+       }
 }
 
 static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
index 0b7a67a..a09c325 100644 (file)
@@ -304,6 +304,7 @@ struct mtk_ppe {
 
 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
                             int version, int index);
+void mtk_ppe_deinit(struct mtk_eth *eth);
 void mtk_ppe_start(struct mtk_ppe *ppe);
 int mtk_ppe_stop(struct mtk_ppe *ppe);