* [PATCH V3 1/2] scsi: sd: Fix sd_config_write_same()
2017-09-05 11:55 [PATCH V3 0/2] sd fixes and cleanup Damien Le Moal
@ 2017-09-05 11:55 ` Damien Le Moal
2017-09-12 23:13 ` Bart Van Assche
2017-09-25 19:39 ` Martin K. Petersen
2017-09-05 11:55 ` [PATCH V3 2/2] scsi: sd: Use sectors_to_logical() Damien Le Moal
1 sibling, 2 replies; 6+ messages in thread
From: Damien Le Moal @ 2017-09-05 11:55 UTC (permalink / raw)
To: linux-scsi, Martin K . Petersen
Cc: Jens Axboe, Christoph Hellwig, Bart Van Assche
Reporting a maximum number of blocks that is not aligned on the device
physical size would cause a large write same request to be split into
physically unaligned chunks by __blkdev_issue_write_zeroes() and
__blkdev_issue_write_same(), even if the caller of these functions took
care to align its request to physical sectors.
So make sure the maximum reported is aligned to the device physical
block size. This is only an optional optimization for regular disks,
but this is mandatory to avoid failure of large write same requests
directed at sequential write required zones of host-managed ZBC disks.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
drivers/scsi/sd.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e2647f2d4430..0a824e9f4d63 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -898,6 +898,26 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
else
sdkp->zeroing_mode = SD_ZERO_WRITE;
+ if (sdkp->max_ws_blocks &&
+ sdkp->physical_block_size > logical_block_size) {
+ /*
+ * Reporting a maximum number of blocks that is not aligned
+ * on the device physical size would cause a large write same
+ * request to be split into physically unaligned chunks by
+ * __blkdev_issue_write_zeroes() and __blkdev_issue_write_same()
+ * even if the caller of these functions took care to align the
+ * large request. So make sure the maximum reported is aligned
+ * to the device physical block size. This is only an optional
+ * optimization for regular disks, but this is mandatory to
+ * avoid failure of large write same requests directed at
+ * sequential write required zones of host-managed ZBC disks.
+ */
+ sdkp->max_ws_blocks =
+ round_down(sdkp->max_ws_blocks,
+ bytes_to_logical(sdkp->device,
+ sdkp->physical_block_size));
+ }
+
out:
blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
(logical_block_size >> 9));
--
2.13.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V3 2/2] scsi: sd: Use sectors_to_logical()
2017-09-05 11:55 [PATCH V3 0/2] sd fixes and cleanup Damien Le Moal
2017-09-05 11:55 ` [PATCH V3 1/2] scsi: sd: Fix sd_config_write_same() Damien Le Moal
@ 2017-09-05 11:55 ` Damien Le Moal
2017-09-12 23:15 ` Bart Van Assche
1 sibling, 1 reply; 6+ messages in thread
From: Damien Le Moal @ 2017-09-05 11:55 UTC (permalink / raw)
To: linux-scsi, Martin K . Petersen
Cc: Jens Axboe, Christoph Hellwig, Bart Van Assche
Replace open coded conversions.
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
drivers/scsi/sd.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0a824e9f4d63..c5d05b1c58a5 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -738,8 +738,8 @@ static int sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = cmd->request;
- u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
- u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
+ u64 sector = sectors_to_logical(sdp, blk_rq_pos(rq));
+ u32 nr_sectors = sectors_to_logical(sdp, blk_rq_sectors(rq));
unsigned int data_len = 24;
char *buf;
@@ -772,8 +772,8 @@ static int sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = cmd->request;
- u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
- u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
+ u64 sector = sectors_to_logical(sdp, blk_rq_pos(rq));
+ u32 nr_sectors = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
@@ -802,8 +802,8 @@ static int sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap)
{
struct scsi_device *sdp = cmd->device;
struct request *rq = cmd->request;
- u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
- u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
+ u64 sector = sectors_to_logical(sdp, blk_rq_pos(rq));
+ u32 nr_sectors = sectors_to_logical(sdp, blk_rq_sectors(rq));
u32 data_len = sdp->sector_size;
rq->special_vec.bv_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
@@ -833,8 +833,8 @@ static int sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
struct request *rq = cmd->request;
struct scsi_device *sdp = cmd->device;
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
- u64 sector = blk_rq_pos(rq) >> (ilog2(sdp->sector_size) - 9);
- u32 nr_sectors = blk_rq_sectors(rq) >> (ilog2(sdp->sector_size) - 9);
+ u64 sector = sectors_to_logical(sdp, blk_rq_pos(rq));
+ u32 nr_sectors = sectors_to_logical(sdp, blk_rq_sectors(rq));
int ret;
if (!(rq->cmd_flags & REQ_NOUNMAP)) {
--
2.13.5
^ permalink raw reply related [flat|nested] 6+ messages in thread