On 2021/02/17 22:52, Johannes Thumshirn wrote: > Dan reported we're passing in GFP_NOIO to kvmalloc() which will then > fallback to doing kmalloc() instead of an optional vmalloc() if the size > exceeds kmalloc()s limits. This will break with drives that have zone > numbers exceeding PAGE_SIZE/sizeof(u32). > > Instead of passing in GFP_NOIO, enter an implicit GFP_NOIO allocation > scope. > > Link: https://lore.kernel.org/r/YCuvSfKw4qEQBr/t@mwanda > Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx> > Cc: Damien Le Moal <Damien.LeMoal@xxxxxxx> > Fixes: 5795eb443060: ("scsi: sd_zbc: emulate ZONE_APPEND commands") > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@xxxxxxx> > --- > drivers/scsi/sd_zbc.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c > index cf07b7f93579..87a7274e4632 100644 > --- a/drivers/scsi/sd_zbc.c > +++ b/drivers/scsi/sd_zbc.c > @@ -688,6 +688,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) > unsigned int nr_zones = sdkp->rev_nr_zones; > u32 max_append; > int ret = 0; > + unsigned int flags; > > /* > * For all zoned disks, initialize zone append emulation data if not > @@ -720,16 +721,19 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) > disk->queue->nr_zones == nr_zones) > goto unlock; > > + flags = memalloc_noio_save(); > sdkp->zone_blocks = zone_blocks; > sdkp->nr_zones = nr_zones; > - sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_NOIO); > + sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); > if (!sdkp->rev_wp_offset) { > ret = -ENOMEM; > + memalloc_noio_restore(flags); > goto unlock; > } > > ret = blk_revalidate_disk_zones(disk, sd_zbc_revalidate_zones_cb); > > + memalloc_noio_restore(flags); > kvfree(sdkp->rev_wp_offset); > sdkp->rev_wp_offset = NULL; > > Looks good to me. Reviewed-by: Damien Le Moal <damien.lemoal@xxxxxxx> -- Damien Le Moal Western Digital Research