Re: [PATCH] crypto: caam: fix netdev memory leak in dpaa2_caam_probe

From: Jianpeng Chang

Date: Sun Jan 18 2026 - 21:05:23 EST




在 2026/1/16 下午7:43, Breno Leitao 写道:
CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender and know the content is safe.

Hello Jianpeng,

On Fri, Jan 16, 2026 at 06:14:37PM +0800, Chang, Jianpeng (CN) wrote:
On 1/16/2026 5:46 PM, Breno Leitao wrote:
CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender and know the content is safe.

On Fri, Jan 16, 2026 at 09:44:55AM +0800, Jianpeng Chang wrote:
When commit 0e1a4d427f58 ("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: 0e1a4d427f58 ("crypto: caam: Unembed net_dev structure in dpaa2")
Signed-off-by: Jianpeng Chang <jianpeng.chang.cn@xxxxxxxxxxxxx>
---
drivers/crypto/caam/caamalg_qi2.c | 31 ++++++++++++++++---------------
drivers/crypto/caam/caamalg_qi2.h | 2 ++
2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c
index 107ccb2ade42..a66c62174a0f 100644
--- a/drivers/crypto/caam/caamalg_qi2.c
+++ b/drivers/crypto/caam/caamalg_qi2.c
@@ -4810,6 +4810,17 @@ static void dpaa2_dpseci_congestion_free(struct dpaa2_caam_priv *priv)
kfree(priv->cscn_mem);
}

+static void free_dpaa2_pcpu_netdev(struct dpaa2_caam_priv *priv, const cpumask_t *cpus)
c> +{
+ struct dpaa2_caam_priv_per_cpu *ppriv;
+ int i;
+
+ for_each_cpu(i, cpus) {
+ ppriv = per_cpu_ptr(priv->ppriv, i);
+ free_netdev(ppriv->net_dev);
+ }
+}

Why is the function being moved here? Please keep code movement separate
from functional changes, or at minimum explain why the move is necessary
in the commit message.
Thank you for the feedback.

I moved the function because I thought reusing existing code would be
cleaner in dpaa2_dpseci_free. I will add the explain in commit message.

For future reference, what's the preferred approach when needing to reuse a
simple function (4-line loop) defined later in the file - forward
declaration, move it with a separate change or just implement directly?

It is fine to implement directly, but, I am a bit confused with the
solution, let me back up a bit.

First, it seems the problem is real and thanks for fixing it.

Regarding the solution, I am wondering if it is not simpler to iterate
the priv->num_pairs and kfreeing them in dpaa2_dpseci_free(), similarly
to dpaa2_dpseci_disable().
Hi Leitao,

Thanks for you reply, I will implement directly instead of moving the function in v2.

I have considered using the approach of iterating through priv->num_pairs, but the index of num_pairs cannot represent the CPU number.

Consider a theoretical scenario where there are multiple CPUs and the cpu 2 is disabled. When iterating through num_pairs, we would get per_cpu_ptr(priv->ppriv, 2), but this would be meaningless.

This is not a critical issue, and I don't have a strong preference either way. I just think using a CPU mask to ensure precise cleanup might be more appropriate.
Furthermore, there are risks in using num_pairs. If we manually disable a CPU and then disable/enable the driver, we would encounter an oops, but that's a separate issue.

Thanks,
Jianpeng