Skip to content

Commit 7d43252

Browse files
Jianpeng Changherbertx
authored andcommitted
crypto: caam - fix netdev memory leak in dpaa2_caam_probe
When commit 0e1a4d4 ("crypto: caam: Unembed net_dev structure in dpaa2") converted embedded net_device to dynamically allocated pointers, it added cleanup in dpaa2_dpseci_disable() but missed adding cleanup in dpaa2_dpseci_free() for error paths. This causes memory leaks when dpaa2_dpseci_dpio_setup() fails during probe due to DPIO devices not being ready yet. The kernel's deferred probe mechanism handles the retry successfully, but the netdevs allocated during the failed probe attempt are never freed, resulting in kmemleak reports showing multiple leaked netdev-related allocations all traced back to dpaa2_caam_probe(). Fix this by preserving the CPU mask of allocated netdevs during setup and using it for cleanup in dpaa2_dpseci_free(). This approach ensures that only the CPUs that actually had netdevs allocated will be cleaned up, avoiding potential issues with CPU hotplug scenarios. Fixes: 0e1a4d4 ("crypto: caam: Unembed net_dev structure in dpaa2") Signed-off-by: Jianpeng Chang <jianpeng.chang.cn@windriver.com> Reviewed-by: Breno Leitao <leitao@debian.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 6d0de60 commit 7d43252

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

drivers/crypto/caam/caamalg_qi2.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4814,14 +4814,21 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)
48144814
{
48154815
struct device *dev = priv->dev;
48164816
struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev);
4817-
int err;
4817+
struct dpaa2_caam_priv_per_cpu *ppriv;
4818+
int i, err;
48184819

48194820
if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) {
48204821
err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle);
48214822
if (err)
48224823
dev_err(dev, "dpseci_reset() failed\n");
48234824
}
48244825

4826+
for_each_cpu(i, priv->clean_mask) {
4827+
ppriv = per_cpu_ptr(priv->ppriv, i);
4828+
free_netdev(ppriv->net_dev);
4829+
}
4830+
free_cpumask_var(priv->clean_mask);
4831+
48254832
dpaa2_dpseci_congestion_free(priv);
48264833
dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
48274834
}
@@ -5007,16 +5014,15 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
50075014
struct device *dev = &ls_dev->dev;
50085015
struct dpaa2_caam_priv *priv;
50095016
struct dpaa2_caam_priv_per_cpu *ppriv;
5010-
cpumask_var_t clean_mask;
50115017
int err, cpu;
50125018
u8 i;
50135019

50145020
err = -ENOMEM;
5015-
if (!zalloc_cpumask_var(&clean_mask, GFP_KERNEL))
5016-
goto err_cpumask;
5017-
50185021
priv = dev_get_drvdata(dev);
50195022

5023+
if (!zalloc_cpumask_var(&priv->clean_mask, GFP_KERNEL))
5024+
goto err_cpumask;
5025+
50205026
priv->dev = dev;
50215027
priv->dpsec_id = ls_dev->obj_desc.id;
50225028

@@ -5118,26 +5124,24 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
51185124
err = -ENOMEM;
51195125
goto err_alloc_netdev;
51205126
}
5121-
cpumask_set_cpu(cpu, clean_mask);
5127+
cpumask_set_cpu(cpu, priv->clean_mask);
51225128
ppriv->net_dev->dev = *dev;
51235129

51245130
netif_napi_add_tx_weight(ppriv->net_dev, &ppriv->napi,
51255131
dpaa2_dpseci_poll,
51265132
DPAA2_CAAM_NAPI_WEIGHT);
51275133
}
51285134

5129-
err = 0;
5130-
goto free_cpumask;
5135+
return 0;
51315136

51325137
err_alloc_netdev:
5133-
free_dpaa2_pcpu_netdev(priv, clean_mask);
5138+
free_dpaa2_pcpu_netdev(priv, priv->clean_mask);
51345139
err_get_rx_queue:
51355140
dpaa2_dpseci_congestion_free(priv);
51365141
err_get_vers:
51375142
dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
51385143
err_open:
5139-
free_cpumask:
5140-
free_cpumask_var(clean_mask);
5144+
free_cpumask_var(priv->clean_mask);
51415145
err_cpumask:
51425146
return err;
51435147
}
@@ -5182,7 +5186,6 @@ static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv)
51825186
ppriv = per_cpu_ptr(priv->ppriv, i);
51835187
napi_disable(&ppriv->napi);
51845188
netif_napi_del(&ppriv->napi);
5185-
free_netdev(ppriv->net_dev);
51865189
}
51875190

51885191
return 0;

drivers/crypto/caam/caamalg_qi2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
* @mc_io: pointer to MC portal's I/O object
4343
* @domain: IOMMU domain
4444
* @ppriv: per CPU pointers to privata data
45+
* @clean_mask: CPU mask of CPUs that have allocated netdevs
4546
*/
4647
struct dpaa2_caam_priv {
4748
int dpsec_id;
@@ -65,6 +66,7 @@ struct dpaa2_caam_priv {
6566

6667
struct dpaa2_caam_priv_per_cpu __percpu *ppriv;
6768
struct dentry *dfs_root;
69+
cpumask_var_t clean_mask;
6870
};
6971

7072
/**

0 commit comments

Comments
 (0)