[PATCH] maengine: xilinx: use kzalloc_flex
From: Rosen Penev <hidden>
Date: 2026-03-08 22:07:46
Also in:
dmaengine, linux-hardening, lkml
Subsystem:
dma generic offload engine subsystem, the rest, xilinx xdma driver · Maintainers:
Vinod Koul, Linus Torvalds, Lizhi Hou, Brian Xu, Raj Kumar Rampelli
Changing descs to a flexible array member allows one fewer allocation. Aadded __counted_by for extra runtime analysis. Changed error path to a simple kfree. descs in all paths are not allocated. No reason to call xdma_free_desc. A single kfree is enough. Signed-off-by: Rosen Penev <redacted> --- drivers/dma/xilinx/xdma.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c
index d02a4dac2291..14fbc7200a6d 100644
--- a/drivers/dma/xilinx/xdma.c
+++ b/drivers/dma/xilinx/xdma.c@@ -80,7 +80,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
@@ -90,12 +89,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;
@@ -105,6 +104,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)
@@ -254,7 +254,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); }
@@ -275,26 +274,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)
@@ -314,7 +309,7 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, bool cyclic) return sw_desc; failed: - xdma_free_desc(&sw_desc->vdesc); + kfree(desc); return NULL; }
--
2.53.0