55c9b35238b735ad4602b496fd006876b09486aa
[openwrt/staging/dangole.git] /
1 From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001
2 From: Yan Cangang <nalanzeyu@gmail.com>
3 Date: Sun, 20 Nov 2022 13:52:59 +0800
4 Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path
5
6 In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed,
7 the rhashtable ppe->l2_flows isn't destroyed. Fix it.
8
9 In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or
10 register_netdev() failed, have the same problem. Fix it.
11
12 Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
13 Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
14 Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
15 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
16 ---
17 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++----
18 drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++++--
19 drivers/net/ethernet/mediatek/mtk_ppe.h | 1 +
20 3 files changed, 23 insertions(+), 6 deletions(-)
21
22 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
23 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
24 @@ -4090,13 +4090,13 @@ static int mtk_probe(struct platform_dev
25 eth->soc->offload_version, i);
26 if (!eth->ppe[i]) {
27 err = -ENOMEM;
28 - goto err_deinit_mdio;
29 + goto err_deinit_ppe;
30 }
31 }
32
33 err = mtk_eth_offload_init(eth);
34 if (err)
35 - goto err_deinit_mdio;
36 + goto err_deinit_ppe;
37 }
38
39 for (i = 0; i < MTK_MAX_DEVS; i++) {
40 @@ -4106,7 +4106,7 @@ static int mtk_probe(struct platform_dev
41 err = register_netdev(eth->netdev[i]);
42 if (err) {
43 dev_err(eth->dev, "error bringing up device\n");
44 - goto err_deinit_mdio;
45 + goto err_deinit_ppe;
46 } else
47 netif_info(eth, probe, eth->netdev[i],
48 "mediatek frame engine at 0x%08lx, irq %d\n",
49 @@ -4126,7 +4126,8 @@ static int mtk_probe(struct platform_dev
50
51 return 0;
52
53 -err_deinit_mdio:
54 +err_deinit_ppe:
55 + mtk_ppe_deinit(eth);
56 mtk_mdio_cleanup(eth);
57 err_free_dev:
58 mtk_free_dev(eth);
59 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
60 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
61 @@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
62 MTK_PPE_ENTRIES * soc->foe_entry_size,
63 &ppe->foe_phys, GFP_KERNEL);
64 if (!foe)
65 - return NULL;
66 + goto err_free_l2_flows;
67
68 ppe->foe_table = foe;
69
70 @@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
71 sizeof(*ppe->foe_flow);
72 ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
73 if (!ppe->foe_flow)
74 - return NULL;
75 + goto err_free_l2_flows;
76
77 mtk_ppe_debugfs_init(ppe, index);
78
79 return ppe;
80 +
81 +err_free_l2_flows:
82 + rhashtable_destroy(&ppe->l2_flows);
83 + return NULL;
84 +}
85 +
86 +void mtk_ppe_deinit(struct mtk_eth *eth)
87 +{
88 + int i;
89 +
90 + for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) {
91 + if (!eth->ppe[i])
92 + return;
93 + rhashtable_destroy(&eth->ppe[i]->l2_flows);
94 + }
95 }
96
97 static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
98 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
99 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
100 @@ -304,6 +304,7 @@ struct mtk_ppe {
101
102 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
103 int version, int index);
104 +void mtk_ppe_deinit(struct mtk_eth *eth);
105 void mtk_ppe_start(struct mtk_ppe *ppe);
106 int mtk_ppe_stop(struct mtk_ppe *ppe);
107