On 03.06.2026 05:17, Rosen Penev wrote:
> 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 <[email protected]>
> Reviewed-by: Qinxin Xia <[email protected]>

Applied to dma-mapping-for-next, thanks!


> ---
>  v2: use params->npages in sg_alloc_table
>  kernel/dma/map_benchmark.c | 27 ++++++++++++---------------
>  1 file changed, 12 insertions(+), 15 deletions(-)
>
> diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c
> index 29eeb5fdf199..fdc070f419f6 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(&params->sgt, params->npages, GFP_KERNEL))
> -             goto free_buf;
> +             goto free_params;
>  
>       for_each_sgtable_sg(&params->sgt, sg, i) {
>               params->buf[i] = (void *)__get_free_page(GFP_KERNEL);
> @@ -166,9 +166,7 @@ static void *dma_sg_map_benchmark_prepare(struct 
> map_benchmark_data *map)
>               free_page((unsigned long)params->buf[i]);
>  
>       sg_free_table(&params->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(&params->sgt);
>  
> -     kfree(params->buf);
>       kfree(params);
>  }
>  

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


Reply via email to