From: Rosen Penev Date: Wed, 3 Jun 2026 03:17:58 +0000 (-0700) Subject: dma: map_benchmark: turn dma_sg_map_param buf into a flexible array X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7318301e060e3f1207a34f2fca6cd86770dd9160;p=thirdparty%2Fkernel%2Flinux.git dma: map_benchmark: turn dma_sg_map_param buf into a flexible array The buf pointer was kmalloc_array()'d immediately after the parent struct allocation, with the count (granule, validated to 1..1024 by the ioctl) trivially available beforehand. Move buf to the struct tail as a flexible array member and fold the two allocations into a single kzalloc_flex(), dropping the kfree(params->buf) in both the prepare error path and unprepare. Add __counted_by for extra runtime analysis. Assisted-by: Claude:Opus-4.7 Signed-off-by: Rosen Penev Reviewed-by: Qinxin Xia Signed-off-by: Marek Szyprowski Link: https://lore.kernel.org/r/20260603031758.290538-1-rosenp@gmail.com --- diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c index 29eeb5fdf199c..fdc070f419f66 100644 --- a/kernel/dma/map_benchmark.c +++ b/kernel/dma/map_benchmark.c @@ -121,35 +121,35 @@ static struct map_benchmark_ops dma_single_map_benchmark_ops = { struct dma_sg_map_param { struct sg_table sgt; struct device *dev; - void **buf; u32 npages; u32 dma_dir; + void *buf[] __counted_by(npages); }; static void *dma_sg_map_benchmark_prepare(struct map_benchmark_data *map) { + struct dma_sg_map_param *params; struct scatterlist *sg; + u32 npages; int i; - struct dma_sg_map_param *params = kzalloc(sizeof(*params), GFP_KERNEL); - - if (!params) - return NULL; /* * Set the number of scatterlist entries based on the granule. * In SG mode, 'granule' represents the number of scatterlist entries. * Each scatterlist entry corresponds to a single page. */ - params->npages = map->bparam.granule; + npages = map->bparam.granule; + + params = kzalloc_flex(*params, buf, npages); + if (!params) + return NULL; + + params->npages = npages; params->dma_dir = map->bparam.dma_dir; params->dev = map->dev; - params->buf = kmalloc_array(params->npages, sizeof(*params->buf), - GFP_KERNEL); - if (!params->buf) - goto out; if (sg_alloc_table(¶ms->sgt, params->npages, GFP_KERNEL)) - goto free_buf; + goto free_params; for_each_sgtable_sg(¶ms->sgt, sg, i) { params->buf[i] = (void *)__get_free_page(GFP_KERNEL); @@ -166,9 +166,7 @@ free_page: free_page((unsigned long)params->buf[i]); sg_free_table(¶ms->sgt); -free_buf: - kfree(params->buf); -out: +free_params: kfree(params); return NULL; } @@ -183,7 +181,6 @@ static void dma_sg_map_benchmark_unprepare(void *mparam) sg_free_table(¶ms->sgt); - kfree(params->buf); kfree(params); }