On 6/27/19 11:09 PM, Christoph Hellwig wrote: >> @@ -79,6 +80,7 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf, >> put_unaligned_be32(buflen, &cmd[10]); >> if (partial) >> cmd[14] = ZBC_REPORT_ZONE_PARTIAL; >> + >> memset(buf, 0, buflen); >> >> result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, > > Spurious whitespace change. Fixed. >> +static void *sd_zbc_alloc_report_buffer(struct request_queue *q, >> + unsigned int nr_zones, size_t *buflen, >> + gfp_t gfp_mask) >> +{ >> + size_t bufsize; >> + void *buf; >> + >> + /* >> + * Report zone buffer size should be at most 64B times the number of >> + * zones requested plus the 64B reply header, but should be at least >> + * SECTOR_SIZE for ATA devices. >> + * Make sure that this size does not exceed the hardware capabilities. >> + * Furthermore, since the report zone command cannot be split, make >> + * sure that the allocated buffer can always be mapped by limiting the >> + * number of pages allocated to the HBA max segments limit. >> + */ >> + nr_zones = min(nr_zones, SD_ZBC_REPORT_MAX_ZONES); >> + bufsize = roundup((nr_zones + 1) * 64, 512); >> + bufsize = min_t(size_t, bufsize, >> + queue_max_hw_sectors(q) << SECTOR_SHIFT); >> + bufsize = min_t(size_t, bufsize, queue_max_segments(q) << PAGE_SHIFT); >> + >> + buf = __vmalloc(bufsize, gfp_mask, PAGE_KERNEL); > > __vmalloc is odd in that it takes a gfp parameter, but can't actually > use it for the page table allocations. So you'll need to do > memalloc_noio_save here, or even better do that in the block layer and > remove the gfp_t parameter from ->report_zones. Yes, indeed. However, removing the gfp_flags from report_zones method would limit possibilities to only GFP_NOIO or GFP_KERNEL (default vmalloc). What if the caller is an FS and needs GFP_NOFS, or any other reclaim flags ? Handling all possibilities does not seem reasonable. Handling only GFP_KERNEL and GFP_IO is easy, but that would mean that the caller of blkdev_report_zones would need to do itself calls to whatever memalloc_noXX_save/restore() it needs. Is that OK ? Currently, blkdev_report_zones() uses only either GFP_KERNEL (general case, fs, dm and user ioctl), or GFP_NOIO for revalidate, disk scan and dm-zoned error path. So removing the flag from the report zones method while keeping it in the block layer API to distinguished these cases is simple, but I am not sure if that will not pause problems for some users. Thoughts ? -- Damien Le Moal Western Digital Research