Subject dmaengine: hsu: use kzalloc_flex() to simplify code
On Tue, Apr 14, 2026 at 08:27:53PM -0700, Rosen Penev wrote: > Simplifies allocations by using a flexible array member in this struct. %s/this struct/struct hsu_dma_sg and struct hsu_dma. Frank > > Remove hsu_dma_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 hsu_dma and devm_kzalloc(). > > Signed-off-by: Rosen Penev <[email protected]> > --- > v4: move back counting variable assignment, as requested. > v3: update description. > v2: address review comments. > drivers/dma/hsu/hsu.c | 43 +++++++++++-------------------------------- > drivers/dma/hsu/hsu.h | 4 ++-- > 2 files changed, 13 insertions(+), 34 deletions(-) > > diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c > index f62d60d7bc6b..b1dd4fd1109b 100644 > --- a/drivers/dma/hsu/hsu.c > +++ b/drivers/dma/hsu/hsu.c > @@ -241,28 +241,10 @@ int hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned > short nr, u32 status) > } > EXPORT_SYMBOL_GPL(hsu_dma_do_irq); > > -static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents) > -{ > - struct hsu_dma_desc *desc; > - > - desc = kzalloc_obj(*desc, GFP_NOWAIT); > - if (!desc) > - return NULL; > - > - desc->sg = kzalloc_objs(*desc->sg, nents, GFP_NOWAIT); > - if (!desc->sg) { > - kfree(desc); > - return NULL; > - } > - > - return desc; > -} > - > static void hsu_dma_desc_free(struct virt_dma_desc *vdesc) > { > struct hsu_dma_desc *desc = to_hsu_dma_desc(vdesc); > > - kfree(desc->sg); > kfree(desc); > } > > @@ -276,10 +258,15 @@ static struct dma_async_tx_descriptor > *hsu_dma_prep_slave_sg( > struct scatterlist *sg; > unsigned int i; > > - desc = hsu_dma_alloc_desc(sg_len); > + desc = kzalloc_flex(*desc, sg, sg_len, GFP_NOWAIT); > if (!desc) > return NULL; > > + desc->nents = sg_len; > + desc->direction = direction; > + /* desc->active = 0 by kzalloc */ > + desc->status = DMA_IN_PROGRESS; > + > for_each_sg(sgl, sg, sg_len, i) { > desc->sg[i].addr = sg_dma_address(sg); > desc->sg[i].len = sg_dma_len(sg); > @@ -287,11 +274,6 @@ static struct dma_async_tx_descriptor > *hsu_dma_prep_slave_sg( > desc->length += sg_dma_len(sg); > } > > - desc->nents = sg_len; > - desc->direction = direction; > - /* desc->active = 0 by kzalloc */ > - desc->status = DMA_IN_PROGRESS; > - > return vchan_tx_prep(&hsuc->vchan, &desc->vdesc, flags); > } > > @@ -428,22 +410,19 @@ int hsu_dma_probe(struct hsu_dma_chip *chip) > { > struct hsu_dma *hsu; > void __iomem *addr = chip->regs + chip->offset; > + unsigned short nr_channels; > unsigned short i; > int ret; > > - hsu = devm_kzalloc(chip->dev, sizeof(*hsu), GFP_KERNEL); > + /* Calculate nr_channels from the IO space length */ > + nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH; > + hsu = devm_kzalloc(chip->dev, struct_size(hsu, chan, nr_channels), > GFP_KERNEL); > if (!hsu) > return -ENOMEM; > > chip->hsu = hsu; > > - /* Calculate nr_channels from the IO space length */ > - hsu->nr_channels = (chip->length - chip->offset) / HSU_DMA_CHAN_LENGTH; > - > - hsu->chan = devm_kcalloc(chip->dev, hsu->nr_channels, > - sizeof(*hsu->chan), GFP_KERNEL); > - if (!hsu->chan) > - return -ENOMEM; > + hsu->nr_channels = nr_channels; > > INIT_LIST_HEAD(&hsu->dma.channels); > for (i = 0; i < hsu->nr_channels; i++) { > diff --git a/drivers/dma/hsu/hsu.h b/drivers/dma/hsu/hsu.h > index 3bca577b98a1..f6ca1014bccf 100644 > --- a/drivers/dma/hsu/hsu.h > +++ b/drivers/dma/hsu/hsu.h > @@ -71,11 +71,11 @@ struct hsu_dma_sg { > struct hsu_dma_desc { > struct virt_dma_desc vdesc; > enum dma_transfer_direction direction; > - struct hsu_dma_sg *sg; > unsigned int nents; > size_t length; > unsigned int active; > enum dma_status status; > + struct hsu_dma_sg sg[] __counted_by(nents); > }; > > static inline struct hsu_dma_desc *to_hsu_dma_desc(struct virt_dma_desc > *vdesc) > @@ -115,8 +115,8 @@ struct hsu_dma { > struct dma_device dma; > > /* channels */ > - struct hsu_dma_chan *chan; > unsigned short nr_channels; > + struct hsu_dma_chan chan[] __counted_by(nr_channels); > }; > > static inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev) > -- > 2.53.0 >

