drivers/crypto/caam/caamalg_qi2.c | 31 ++++++++++++++++--------------- drivers/crypto/caam/caamalg_qi2.h | 2 ++ 2 files changed, 18 insertions(+), 15 deletions(-)
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@windriver.com>
---
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)
+{
+ 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);
+ }
+}
+
static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)
{
struct device *dev = priv->dev;
@@ -4822,6 +4833,9 @@ static void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv)
dev_err(dev, "dpseci_reset() failed\n");
}
+ free_dpaa2_pcpu_netdev(priv, priv->clean_mask);
+ free_cpumask_var(priv->clean_mask);
+
dpaa2_dpseci_congestion_free(priv);
dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
}
@@ -4991,17 +5005,6 @@ static int dpaa2_dpseci_congestion_setup(struct dpaa2_caam_priv *priv,
return err;
}
-static void free_dpaa2_pcpu_netdev(struct dpaa2_caam_priv *priv, const cpumask_t *cpus)
-{
- 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);
- }
-}
-
static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
{
struct device *dev = &ls_dev->dev;
@@ -5126,8 +5129,8 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
DPAA2_CAAM_NAPI_WEIGHT);
}
- err = 0;
- goto free_cpumask;
+ priv->clean_mask = clean_mask;
+ return 0;
err_alloc_netdev:
free_dpaa2_pcpu_netdev(priv, clean_mask);
@@ -5136,7 +5139,6 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
err_get_vers:
dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
err_open:
-free_cpumask:
free_cpumask_var(clean_mask);
err_cpumask:
return err;
@@ -5182,7 +5184,6 @@ static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv)
ppriv = per_cpu_ptr(priv->ppriv, i);
napi_disable(&ppriv->napi);
netif_napi_del(&ppriv->napi);
- free_netdev(ppriv->net_dev);
}
return 0;
diff --git a/drivers/crypto/caam/caamalg_qi2.h b/drivers/crypto/caam/caamalg_qi2.h
index 61d1219a202f..8e65b4b28c7b 100644
--- a/drivers/crypto/caam/caamalg_qi2.h
+++ b/drivers/crypto/caam/caamalg_qi2.h
@@ -42,6 +42,7 @@
* @mc_io: pointer to MC portal's I/O object
* @domain: IOMMU domain
* @ppriv: per CPU pointers to privata data
+ * @clean_mask: CPU mask of CPUs that have allocated netdevs
*/
struct dpaa2_caam_priv {
int dpsec_id;
@@ -65,6 +66,7 @@ struct dpaa2_caam_priv {
struct dpaa2_caam_priv_per_cpu __percpu *ppriv;
struct dentry *dfs_root;
+ cpumask_var_t clean_mask;
};
/**
--
2.52.0
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@windriver.com>
> ---
> 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)
> +{
> + 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.
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@windriver.com>
>> ---
>> 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)
>> +{
>> + 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?
Thanks for the guidance.
Regards,
Jianpeng
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@windriver.com>
> > > ---
> > > 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().
在 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@windriver.com>
>>>> ---
>>>> 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
Hi Jianpeng,
kernel test robot noticed the following build errors:
[auto build test ERROR on herbert-cryptodev-2.6/master]
[also build test ERROR on herbert-crypto-2.6/master linus/master v6.19-rc5 next-20260115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jianpeng-Chang/crypto-caam-fix-netdev-memory-leak-in-dpaa2_caam_probe/20260116-094800
base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link: https://lore.kernel.org/r/20260116014455.2575351-1-jianpeng.chang.cn%40windriver.com
patch subject: [PATCH] crypto: caam: fix netdev memory leak in dpaa2_caam_probe
config: x86_64-buildonly-randconfig-004-20260116 (https://download.01.org/0day-ci/archive/20260116/202601161604.ynMta3vK-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260116/202601161604.ynMta3vK-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601161604.ynMta3vK-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/crypto/caam/caamalg_qi2.c:5132:19: error: array type 'cpumask_var_t' (aka 'struct cpumask[1]') is not assignable
5132 | priv->clean_mask = clean_mask;
| ~~~~~~~~~~~~~~~~ ^
1 error generated.
vim +5132 drivers/crypto/caam/caamalg_qi2.c
5007
5008 static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
5009 {
5010 struct device *dev = &ls_dev->dev;
5011 struct dpaa2_caam_priv *priv;
5012 struct dpaa2_caam_priv_per_cpu *ppriv;
5013 cpumask_var_t clean_mask;
5014 int err, cpu;
5015 u8 i;
5016
5017 err = -ENOMEM;
5018 if (!zalloc_cpumask_var(&clean_mask, GFP_KERNEL))
5019 goto err_cpumask;
5020
5021 priv = dev_get_drvdata(dev);
5022
5023 priv->dev = dev;
5024 priv->dpsec_id = ls_dev->obj_desc.id;
5025
5026 /* Get a handle for the DPSECI this interface is associate with */
5027 err = dpseci_open(priv->mc_io, 0, priv->dpsec_id, &ls_dev->mc_handle);
5028 if (err) {
5029 dev_err(dev, "dpseci_open() failed: %d\n", err);
5030 goto err_open;
5031 }
5032
5033 err = dpseci_get_api_version(priv->mc_io, 0, &priv->major_ver,
5034 &priv->minor_ver);
5035 if (err) {
5036 dev_err(dev, "dpseci_get_api_version() failed\n");
5037 goto err_get_vers;
5038 }
5039
5040 dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver);
5041
5042 if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) {
5043 err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle);
5044 if (err) {
5045 dev_err(dev, "dpseci_reset() failed\n");
5046 goto err_get_vers;
5047 }
5048 }
5049
5050 err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle,
5051 &priv->dpseci_attr);
5052 if (err) {
5053 dev_err(dev, "dpseci_get_attributes() failed\n");
5054 goto err_get_vers;
5055 }
5056
5057 err = dpseci_get_sec_attr(priv->mc_io, 0, ls_dev->mc_handle,
5058 &priv->sec_attr);
5059 if (err) {
5060 dev_err(dev, "dpseci_get_sec_attr() failed\n");
5061 goto err_get_vers;
5062 }
5063
5064 err = dpaa2_dpseci_congestion_setup(priv, ls_dev->mc_handle);
5065 if (err) {
5066 dev_err(dev, "setup_congestion() failed\n");
5067 goto err_get_vers;
5068 }
5069
5070 priv->num_pairs = min(priv->dpseci_attr.num_rx_queues,
5071 priv->dpseci_attr.num_tx_queues);
5072 if (priv->num_pairs > num_online_cpus()) {
5073 dev_warn(dev, "%d queues won't be used\n",
5074 priv->num_pairs - num_online_cpus());
5075 priv->num_pairs = num_online_cpus();
5076 }
5077
5078 for (i = 0; i < priv->dpseci_attr.num_rx_queues; i++) {
5079 err = dpseci_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
5080 &priv->rx_queue_attr[i]);
5081 if (err) {
5082 dev_err(dev, "dpseci_get_rx_queue() failed\n");
5083 goto err_get_rx_queue;
5084 }
5085 }
5086
5087 for (i = 0; i < priv->dpseci_attr.num_tx_queues; i++) {
5088 err = dpseci_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
5089 &priv->tx_queue_attr[i]);
5090 if (err) {
5091 dev_err(dev, "dpseci_get_tx_queue() failed\n");
5092 goto err_get_rx_queue;
5093 }
5094 }
5095
5096 i = 0;
5097 for_each_online_cpu(cpu) {
5098 u8 j;
5099
5100 j = i % priv->num_pairs;
5101
5102 ppriv = per_cpu_ptr(priv->ppriv, cpu);
5103 ppriv->req_fqid = priv->tx_queue_attr[j].fqid;
5104
5105 /*
5106 * Allow all cores to enqueue, while only some of them
5107 * will take part in dequeuing.
5108 */
5109 if (++i > priv->num_pairs)
5110 continue;
5111
5112 ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid;
5113 ppriv->prio = j;
5114
5115 dev_dbg(dev, "pair %d: rx queue %d, tx queue %d\n", j,
5116 priv->rx_queue_attr[j].fqid,
5117 priv->tx_queue_attr[j].fqid);
5118
5119 ppriv->net_dev = alloc_netdev_dummy(0);
5120 if (!ppriv->net_dev) {
5121 err = -ENOMEM;
5122 goto err_alloc_netdev;
5123 }
5124 cpumask_set_cpu(cpu, clean_mask);
5125 ppriv->net_dev->dev = *dev;
5126
5127 netif_napi_add_tx_weight(ppriv->net_dev, &ppriv->napi,
5128 dpaa2_dpseci_poll,
5129 DPAA2_CAAM_NAPI_WEIGHT);
5130 }
5131
> 5132 priv->clean_mask = clean_mask;
5133 return 0;
5134
5135 err_alloc_netdev:
5136 free_dpaa2_pcpu_netdev(priv, clean_mask);
5137 err_get_rx_queue:
5138 dpaa2_dpseci_congestion_free(priv);
5139 err_get_vers:
5140 dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
5141 err_open:
5142 free_cpumask_var(clean_mask);
5143 err_cpumask:
5144 return err;
5145 }
5146
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On 1/16/2026 4:19 PM, kernel test robot 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.
>
> Hi Jianpeng,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on herbert-cryptodev-2.6/master]
> [also build test ERROR on herbert-crypto-2.6/master linus/master v6.19-rc5 next-20260115]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Jianpeng-Chang/crypto-caam-fix-netdev-memory-leak-in-dpaa2_caam_probe/20260116-094800
> base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
> patch link: https://lore.kernel.org/r/20260116014455.2575351-1-jianpeng.chang.cn%40windriver.com
> patch subject: [PATCH] crypto: caam: fix netdev memory leak in dpaa2_caam_probe
> config: x86_64-buildonly-randconfig-004-20260116 (https://download.01.org/0day-ci/archive/20260116/202601161604.ynMta3vK-lkp@intel.com/config)
> compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260116/202601161604.ynMta3vK-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202601161604.ynMta3vK-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
>>> drivers/crypto/caam/caamalg_qi2.c:5132:19: error: array type 'cpumask_var_t' (aka 'struct cpumask[1]') is not assignable
> 5132 | priv->clean_mask = clean_mask;
> | ~~~~~~~~~~~~~~~~ ^
> 1 error generated.
Tested only with CONFIG_CPUMASK_OFFSTACK enabled.
Please ignore this patch. I will resend the patch with the error fixed.
Sorry for the inconvenience.
Regards,
Jianpeng
>
>
> vim +5132 drivers/crypto/caam/caamalg_qi2.c
>
> 5007
> 5008 static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev)
> 5009 {
> 5010 struct device *dev = &ls_dev->dev;
> 5011 struct dpaa2_caam_priv *priv;
> 5012 struct dpaa2_caam_priv_per_cpu *ppriv;
> 5013 cpumask_var_t clean_mask;
> 5014 int err, cpu;
> 5015 u8 i;
> 5016
> 5017 err = -ENOMEM;
> 5018 if (!zalloc_cpumask_var(&clean_mask, GFP_KERNEL))
> 5019 goto err_cpumask;
> 5020
> 5021 priv = dev_get_drvdata(dev);
> 5022
> 5023 priv->dev = dev;
> 5024 priv->dpsec_id = ls_dev->obj_desc.id;
> 5025
> 5026 /* Get a handle for the DPSECI this interface is associate with */
> 5027 err = dpseci_open(priv->mc_io, 0, priv->dpsec_id, &ls_dev->mc_handle);
> 5028 if (err) {
> 5029 dev_err(dev, "dpseci_open() failed: %d\n", err);
> 5030 goto err_open;
> 5031 }
> 5032
> 5033 err = dpseci_get_api_version(priv->mc_io, 0, &priv->major_ver,
> 5034 &priv->minor_ver);
> 5035 if (err) {
> 5036 dev_err(dev, "dpseci_get_api_version() failed\n");
> 5037 goto err_get_vers;
> 5038 }
> 5039
> 5040 dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver);
> 5041
> 5042 if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) {
> 5043 err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle);
> 5044 if (err) {
> 5045 dev_err(dev, "dpseci_reset() failed\n");
> 5046 goto err_get_vers;
> 5047 }
> 5048 }
> 5049
> 5050 err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle,
> 5051 &priv->dpseci_attr);
> 5052 if (err) {
> 5053 dev_err(dev, "dpseci_get_attributes() failed\n");
> 5054 goto err_get_vers;
> 5055 }
> 5056
> 5057 err = dpseci_get_sec_attr(priv->mc_io, 0, ls_dev->mc_handle,
> 5058 &priv->sec_attr);
> 5059 if (err) {
> 5060 dev_err(dev, "dpseci_get_sec_attr() failed\n");
> 5061 goto err_get_vers;
> 5062 }
> 5063
> 5064 err = dpaa2_dpseci_congestion_setup(priv, ls_dev->mc_handle);
> 5065 if (err) {
> 5066 dev_err(dev, "setup_congestion() failed\n");
> 5067 goto err_get_vers;
> 5068 }
> 5069
> 5070 priv->num_pairs = min(priv->dpseci_attr.num_rx_queues,
> 5071 priv->dpseci_attr.num_tx_queues);
> 5072 if (priv->num_pairs > num_online_cpus()) {
> 5073 dev_warn(dev, "%d queues won't be used\n",
> 5074 priv->num_pairs - num_online_cpus());
> 5075 priv->num_pairs = num_online_cpus();
> 5076 }
> 5077
> 5078 for (i = 0; i < priv->dpseci_attr.num_rx_queues; i++) {
> 5079 err = dpseci_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
> 5080 &priv->rx_queue_attr[i]);
> 5081 if (err) {
> 5082 dev_err(dev, "dpseci_get_rx_queue() failed\n");
> 5083 goto err_get_rx_queue;
> 5084 }
> 5085 }
> 5086
> 5087 for (i = 0; i < priv->dpseci_attr.num_tx_queues; i++) {
> 5088 err = dpseci_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, i,
> 5089 &priv->tx_queue_attr[i]);
> 5090 if (err) {
> 5091 dev_err(dev, "dpseci_get_tx_queue() failed\n");
> 5092 goto err_get_rx_queue;
> 5093 }
> 5094 }
> 5095
> 5096 i = 0;
> 5097 for_each_online_cpu(cpu) {
> 5098 u8 j;
> 5099
> 5100 j = i % priv->num_pairs;
> 5101
> 5102 ppriv = per_cpu_ptr(priv->ppriv, cpu);
> 5103 ppriv->req_fqid = priv->tx_queue_attr[j].fqid;
> 5104
> 5105 /*
> 5106 * Allow all cores to enqueue, while only some of them
> 5107 * will take part in dequeuing.
> 5108 */
> 5109 if (++i > priv->num_pairs)
> 5110 continue;
> 5111
> 5112 ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid;
> 5113 ppriv->prio = j;
> 5114
> 5115 dev_dbg(dev, "pair %d: rx queue %d, tx queue %d\n", j,
> 5116 priv->rx_queue_attr[j].fqid,
> 5117 priv->tx_queue_attr[j].fqid);
> 5118
> 5119 ppriv->net_dev = alloc_netdev_dummy(0);
> 5120 if (!ppriv->net_dev) {
> 5121 err = -ENOMEM;
> 5122 goto err_alloc_netdev;
> 5123 }
> 5124 cpumask_set_cpu(cpu, clean_mask);
> 5125 ppriv->net_dev->dev = *dev;
> 5126
> 5127 netif_napi_add_tx_weight(ppriv->net_dev, &ppriv->napi,
> 5128 dpaa2_dpseci_poll,
> 5129 DPAA2_CAAM_NAPI_WEIGHT);
> 5130 }
> 5131
>> 5132 priv->clean_mask = clean_mask;
> 5133 return 0;
> 5134
> 5135 err_alloc_netdev:
> 5136 free_dpaa2_pcpu_netdev(priv, clean_mask);
> 5137 err_get_rx_queue:
> 5138 dpaa2_dpseci_congestion_free(priv);
> 5139 err_get_vers:
> 5140 dpseci_close(priv->mc_io, 0, ls_dev->mc_handle);
> 5141 err_open:
> 5142 free_cpumask_var(clean_mask);
> 5143 err_cpumask:
> 5144 return err;
> 5145 }
> 5146
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.