Re: [PATCH] md/raid0: use kvzalloc/kvfree for strip_zone and devlist allocations

Li Nan <[email protected]>
Newsgroups gmane.linux.raid,gmane.linux.kernel,gmane.linux.kernel.mm
Message-ID <[email protected]>

在 2026/3/9 7:42, Gregory Price 写道:
> syzbot reported a WARNING at mm/page_alloc.c:__alloc_frozen_pages_noprof()
> triggered by create_strip_zones() in the RAID0 driver.
> 
> When raid_disks is large, the allocation size exceeds MAX_PAGE_ORDER (4MB
> on x86), causing WARN_ON_ONCE_GFP(order > MAX_PAGE_ORDER).
> 
> Convert the strip_zone and devlist allocations from kzalloc/kzalloc_objs to
> kvzalloc/kvzalloc_objs, which first attempts a contiguous allocation with
> __GFP_NOWARN and then falls back to vmalloc for large sizes. Convert the
> corresponding kfree calls to kvfree.
> 
> Both arrays are pure metadata lookup tables (arrays of pointers and zone
> descriptors) accessed only via indexing, so they do not require physically
> contiguous memory.
> 
> Reported-by: [email protected]
> Signed-off-by: Gregory Price <[email protected]>
> ---
>   drivers/md/raid0.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
> index ef0045db409f..5e38a51e349a 100644
> --- a/drivers/md/raid0.c
> +++ b/drivers/md/raid0.c
> @@ -143,13 +143,13 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
>   	}
>   
>   	err = -ENOMEM;
> -	conf->strip_zone = kzalloc_objs(struct strip_zone, conf->nr_strip_zones);
> +	conf->strip_zone = kvzalloc_objs(struct strip_zone, conf->nr_strip_zones);
>   	if (!conf->strip_zone)
>   		goto abort;
> -	conf->devlist = kzalloc(array3_size(sizeof(struct md_rdev *),
> -					    conf->nr_strip_zones,
> -					    mddev->raid_disks),
> -				GFP_KERNEL);
> +	conf->devlist = kvzalloc(array3_size(sizeof(struct md_rdev *),
> +					     conf->nr_strip_zones,
> +					     mddev->raid_disks),
> +				 GFP_KERNEL);
>   	if (!conf->devlist)
>   		goto abort;
>   
> @@ -291,8 +291,8 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
>   
>   	return 0;
>   abort:
> -	kfree(conf->strip_zone);
> -	kfree(conf->devlist);
> +	kvfree(conf->strip_zone);
> +	kvfree(conf->devlist);
>   	kfree(conf);
>   	*private_conf = ERR_PTR(err);
>   	return err;
> @@ -373,8 +373,8 @@ static void raid0_free(struct mddev *mddev, void *priv)
>   {
>   	struct r0conf *conf = priv;
>   
> -	kfree(conf->strip_zone);
> -	kfree(conf->devlist);
> +	kvfree(conf->strip_zone);
> +	kvfree(conf->devlist);
>   	kfree(conf);
>   }
>   


LGTM

Reviewed-by: Li Nan <[email protected]>

-- 
Thanks,
Nan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.