[PATCHv2] dmaengine: idma64: use kzalloc_flex

Rosen Penev posted 1 patch 1 week, 6 days ago
drivers/dma/idma64.c | 30 ++++--------------------------
drivers/dma/idma64.h |  4 ++--
2 files changed, 6 insertions(+), 28 deletions(-)
[PATCHv2] dmaengine: idma64: use kzalloc_flex
Posted by Rosen Penev 1 week, 6 days ago
Simplifies allocations by using a flexible array member in this struct.

Remove idma64_alloc_desc. It now offers no readability advantages in
this single usage.

Add __counted_by to get extra runtime analysis.

Apply the exact same treatment to struct idma64_dma and devm_kzalloc.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 v2: allocate with GFP_NOWAIT. Was mistakenly removed.
 drivers/dma/idma64.c | 30 ++++--------------------------
 drivers/dma/idma64.h |  4 ++--
 2 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
index 5fcd1befc92d..d914f50ec309 100644
--- a/drivers/dma/idma64.c
+++ b/drivers/dma/idma64.c
@@ -192,23 +192,6 @@ static irqreturn_t idma64_irq(int irq, void *dev)

 /* ---------------------------------------------------------------------- */

-static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc)
-{
-	struct idma64_desc *desc;
-
-	desc = kzalloc_obj(*desc, GFP_NOWAIT);
-	if (!desc)
-		return NULL;
-
-	desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT);
-	if (!desc->hw) {
-		kfree(desc);
-		return NULL;
-	}
-
-	return desc;
-}
-
 static void idma64_desc_free(struct idma64_chan *idma64c,
 		struct idma64_desc *desc)
 {
@@ -223,7 +206,6 @@ static void idma64_desc_free(struct idma64_chan *idma64c,
 		} while (i);
 	}

-	kfree(desc->hw);
 	kfree(desc);
 }

@@ -307,10 +289,12 @@ static struct dma_async_tx_descriptor *idma64_prep_slave_sg(
 	struct scatterlist *sg;
 	unsigned int i;

-	desc = idma64_alloc_desc(sg_len);
+	desc = kzalloc_flex(*desc, hw, sg_len, GFP_NOWAIT);
 	if (!desc)
 		return NULL;

+	desc->ndesc = sg_len;
+
 	for_each_sg(sgl, sg, sg_len, i) {
 		struct idma64_hw_desc *hw = &desc->hw[i];

@@ -326,7 +310,6 @@ static struct dma_async_tx_descriptor *idma64_prep_slave_sg(
 		hw->len = sg_dma_len(sg);
 	}

-	desc->ndesc = sg_len;
 	desc->direction = direction;
 	desc->status = DMA_IN_PROGRESS;

@@ -541,18 +524,13 @@ static int idma64_probe(struct idma64_chip *chip)
 	unsigned short i;
 	int ret;

-	idma64 = devm_kzalloc(chip->dev, sizeof(*idma64), GFP_KERNEL);
+	idma64 = devm_kzalloc(chip->dev, struct_size(idma64, chan, nr_chan), GFP_KERNEL);
 	if (!idma64)
 		return -ENOMEM;

 	idma64->regs = chip->regs;
 	chip->idma64 = idma64;

-	idma64->chan = devm_kcalloc(chip->dev, nr_chan, sizeof(*idma64->chan),
-				    GFP_KERNEL);
-	if (!idma64->chan)
-		return -ENOMEM;
-
 	idma64->all_chan_mask = (1 << nr_chan) - 1;

 	/* Turn off iDMA controller */
diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h
index d013b54356aa..1a67dbb24db5 100644
--- a/drivers/dma/idma64.h
+++ b/drivers/dma/idma64.h
@@ -113,10 +113,10 @@ struct idma64_hw_desc {
 struct idma64_desc {
 	struct virt_dma_desc vdesc;
 	enum dma_transfer_direction direction;
-	struct idma64_hw_desc *hw;
 	unsigned int ndesc;
 	size_t length;
 	enum dma_status status;
+	struct idma64_hw_desc hw[] __counted_by(ndesc);
 };

 static inline struct idma64_desc *to_idma64_desc(struct virt_dma_desc *vdesc)
@@ -187,7 +187,7 @@ struct idma64 {

 	/* channels */
 	unsigned short all_chan_mask;
-	struct idma64_chan *chan;
+	struct idma64_chan chan[];
 };

 static inline struct idma64 *to_idma64(struct dma_device *ddev)
--
2.53.0
Re: [PATCHv2] dmaengine: idma64: use kzalloc_flex
Posted by Frank Li 4 days, 7 hours ago
On Fri, Mar 20, 2026 at 08:49:31PM -0700, Rosen Penev wrote:
> Simplifies allocations by using a flexible array member in this struct.
>
> Remove idma64_alloc_desc. It now offers no readability advantages in
> this single usage.
>
> Add __counted_by to get extra runtime analysis.
>
> Apply the exact same treatment to struct idma64_dma and devm_kzalloc.
>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  v2: allocate with GFP_NOWAIT. Was mistakenly removed.
>  drivers/dma/idma64.c | 30 ++++--------------------------
>  drivers/dma/idma64.h |  4 ++--
>  2 files changed, 6 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
> index 5fcd1befc92d..d914f50ec309 100644
> --- a/drivers/dma/idma64.c
> +++ b/drivers/dma/idma64.c
> @@ -192,23 +192,6 @@ static irqreturn_t idma64_irq(int irq, void *dev)
>
>  /* ---------------------------------------------------------------------- */
>
> -static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc)
> -{
> -	struct idma64_desc *desc;
> -
> -	desc = kzalloc_obj(*desc, GFP_NOWAIT);
> -	if (!desc)
> -		return NULL;
> -
> -	desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT);
> -	if (!desc->hw) {
> -		kfree(desc);
> -		return NULL;
> -	}
> -
> -	return desc;
> -}
> -
>  static void idma64_desc_free(struct idma64_chan *idma64c,
>  		struct idma64_desc *desc)
>  {
> @@ -223,7 +206,6 @@ static void idma64_desc_free(struct idma64_chan *idma64c,
>  		} while (i);
>  	}
>
> -	kfree(desc->hw);
>  	kfree(desc);
>  }
>
> @@ -307,10 +289,12 @@ static struct dma_async_tx_descriptor *idma64_prep_slave_sg(
>  	struct scatterlist *sg;
>  	unsigned int i;
>
> -	desc = idma64_alloc_desc(sg_len);
> +	desc = kzalloc_flex(*desc, hw, sg_len, GFP_NOWAIT);
>  	if (!desc)
>  		return NULL;
>
> +	desc->ndesc = sg_len;
> +

This patch is okay, but suggest use sg_nents_for_dma() later

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>