On Mon, Oct 05, 2026 at 12:26:21PM -0700, Rosen Penev wrote: > Change desc_blocks to a flexible array member so the descriptor and > its block array are allocated together, removing one allocation and > its error handling. > > Add __counted_by for extra runtime analysis, and set dblk_num right > after allocation which is already done by kzalloc_flex() for GCC >= 15. > > Assisted-by: LLM > Signed-off-by: Rosen Penev <[email protected]> > ---
Reviewed-by: Frank Li <[email protected]> > drivers/dma/xilinx/xdma.c | 15 +++++---------- > 1 file changed, 5 insertions(+), 10 deletions(-) > > diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c > index 8d4a5d14e8db..16d202722245 100644 > --- a/drivers/dma/xilinx/xdma.c > +++ b/drivers/dma/xilinx/xdma.c > @@ -81,7 +81,6 @@ struct xdma_chan { > * @vdesc: Virtual DMA descriptor > * @chan: DMA channel pointer > * @dir: Transferring direction of the request > - * @desc_blocks: Hardware descriptor blocks > * @dblk_num: Number of hardware descriptor blocks > * @desc_num: Number of hardware descriptors > * @completed_desc_num: Completed hardware descriptors > @@ -91,12 +90,12 @@ struct xdma_chan { > * @period_size: Size of a period in bytes in cyclic transfers > * @frames_left: Number of frames left in interleaved DMA transfer > * @error: tx error flag > + * @desc_blocks: Hardware descriptor blocks > */ > struct xdma_desc { > struct virt_dma_desc vdesc; > struct xdma_chan *chan; > enum dma_transfer_direction dir; > - struct xdma_desc_block *desc_blocks; > u32 dblk_num; > u32 desc_num; > u32 completed_desc_num; > @@ -106,6 +105,7 @@ struct xdma_desc { > u32 period_size; > u32 frames_left; > bool error; > + struct xdma_desc_block desc_blocks[] __counted_by(dblk_num); > }; > > #define XDMA_DEV_STATUS_REG_DMA BIT(0) > @@ -255,7 +255,6 @@ static void xdma_free_desc(struct virt_dma_desc *vdesc) > sw_desc->desc_blocks[i].virt_addr, > sw_desc->desc_blocks[i].dma_addr); > } > - kfree(sw_desc->desc_blocks); > kfree(sw_desc); > } > > @@ -276,26 +275,22 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, > bool cyclic) > void *addr; > int i, j; > > - sw_desc = kzalloc_obj(*sw_desc, GFP_NOWAIT); > + dblk_num = DIV_ROUND_UP(desc_num, XDMA_DESC_ADJACENT); > + sw_desc = kzalloc_flex(*sw_desc, desc_blocks, dblk_num, GFP_NOWAIT); > if (!sw_desc) > return NULL; > > + sw_desc->dblk_num = dblk_num; > sw_desc->chan = chan; > sw_desc->desc_num = desc_num; > sw_desc->cyclic = cyclic; > sw_desc->error = false; > - dblk_num = DIV_ROUND_UP(desc_num, XDMA_DESC_ADJACENT); > - sw_desc->desc_blocks = kzalloc_objs(*sw_desc->desc_blocks, dblk_num, > - GFP_NOWAIT); > - if (!sw_desc->desc_blocks) > - goto failed; > > if (cyclic) > control = XDMA_DESC_CONTROL_CYCLIC; > else > control = XDMA_DESC_CONTROL(1, 0); > > - sw_desc->dblk_num = dblk_num; > for (i = 0; i < sw_desc->dblk_num; i++) { > addr = dma_pool_alloc(chan->desc_pool, GFP_NOWAIT, &dma_addr); > if (!addr) > -- > 2.56.0 >

