Skip to content

Commit

Permalink
scsi: sd_zbc: Cleanup sd_zbc_alloc_report_buffer()
Browse files Browse the repository at this point in the history
There is no need to arbitrarily limit the size of a report zone to the
number of zones defined by SD_ZBC_REPORT_MAX_ZONES. Rather, simply
calculate the report buffer size needed for the requested number of
zones without exceeding the device total number of zones. This buffer
size limitation to the hardware maximum transfer size and page mapping
capabilities is kept unchanged. Starting with this initial buffer size,
the allocation is optimized by iterating over decreasing buffer size
until the allocation succeeds (each iteration is allowed to fail fast
using the __GFP_NORETRY flag). This ensures forward progress for zone
reports and avoids failures of zones revalidation under memory pressure.

While at it, also replace the hard coded 512 B sector size with the
SECTOR_SIZE macro.

Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Damien Le Moal authored and Jens Axboe committed Nov 13, 2019
1 parent 6d09c40 commit 23a5086
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions drivers/scsi/sd_zbc.c
Original file line number Diff line number Diff line change
@@ -104,11 +104,6 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
return 0;
}

/*
* Maximum number of zones to get with one report zones command.
*/
#define SD_ZBC_REPORT_MAX_ZONES 8192U

/**
* Allocate a buffer for report zones reply.
* @sdkp: The target disk
@@ -138,17 +133,24 @@ static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp,
* 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);
nr_zones = min(nr_zones, sdkp->nr_zones);
bufsize = roundup((nr_zones + 1) * 64, SECTOR_SIZE);
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 = vzalloc(bufsize);
if (buf)
*buflen = bufsize;
while (bufsize >= SECTOR_SIZE) {
buf = __vmalloc(bufsize,
GFP_KERNEL | __GFP_ZERO | __GFP_NORETRY,
PAGE_KERNEL);
if (buf) {
*buflen = bufsize;
return buf;
}
bufsize >>= 1;
}

return buf;
return NULL;
}

/**

0 comments on commit 23a5086

Please sign in to comment.