public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Chao Yu <chao@kernel.org>
To: jejb@linux.ibm.com, martin.petersen@oracle.com
Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH] scsi: support packing multi-segment in UNMAP command
Date: Wed, 25 May 2022 09:34:52 +0800	[thread overview]
Message-ID: <138141eb-6bb9-88bc-cdb0-85f6df8b18cb@kernel.org> (raw)
In-Reply-To: <20220521113259.3953757-1-chao@kernel.org>

Ping,

Any comments?

Thanks,

On 2022/5/21 19:32, Chao Yu wrote:
> As SPEC describes that it can support unmapping one or more LBA range
> in single UNMAP command, however, previously we only pack one LBA
> range in UNMAP command by default no matter device gives the block
> limits that says it can support in-batch UNMAP.
> 
> This patch tries to set max_discard_segments config according to block
> limits of device, and supports in-batch UNMAP.
> 
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
>   drivers/scsi/sd.c | 30 +++++++++++++++++++-----------
>   drivers/scsi/sd.h |  1 +
>   2 files changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index dc6e55761fd1..be070457c78d 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -790,6 +790,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
>   	q->limits.discard_granularity =
>   		max(sdkp->physical_block_size,
>   		    sdkp->unmap_granularity * logical_block_size);
> +	blk_queue_max_discard_segments(q, sdkp->max_block_desc_count);
>   	sdkp->provisioning_mode = mode;
>   
>   	switch (mode) {
> @@ -837,10 +838,10 @@ static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
>   {
>   	struct scsi_device *sdp = cmd->device;
>   	struct request *rq = scsi_cmd_to_rq(cmd);
> +	struct bio *bio;
>   	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
> -	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
> -	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
> -	unsigned int data_len = 24;
> +	unsigned short segments = blk_rq_nr_discard_segments(rq);
> +	unsigned int data_len = 8 + 16 * segments, i = 0;
>   	char *buf;
>   
>   	rq->special_vec.bv_page = mempool_alloc(sd_page_pool, GFP_ATOMIC);
> @@ -853,13 +854,20 @@ static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
>   
>   	cmd->cmd_len = 10;
>   	cmd->cmnd[0] = UNMAP;
> -	cmd->cmnd[8] = 24;
> +	cmd->cmnd[8] = data_len;
>   
>   	buf = bvec_virt(&rq->special_vec);
> -	put_unaligned_be16(6 + 16, &buf[0]);
> -	put_unaligned_be16(16, &buf[2]);
> -	put_unaligned_be64(lba, &buf[8]);
> -	put_unaligned_be32(nr_blocks, &buf[16]);
> +	put_unaligned_be16(6 + 16 * segments, &buf[0]);
> +	put_unaligned_be16(16 * segments, &buf[2]);
> +
> +	__rq_for_each_bio(bio, rq) {
> +		u64 lba = sectors_to_logical(sdp, bio->bi_iter.bi_sector);
> +		u32 nr_blocks = sectors_to_logical(sdp, bio_sectors(bio));
> +
> +		put_unaligned_be64(lba, &buf[8 + 16 * i]);
> +		put_unaligned_be32(nr_blocks, &buf[8 + 16 * i + 8]);
> +		i++;
> +	}
>   
>   	cmd->allowed = sdkp->max_retries;
>   	cmd->transfersize = data_len;
> @@ -2859,7 +2867,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
>   	sdkp->opt_xfer_blocks = get_unaligned_be32(&buffer[12]);
>   
>   	if (buffer[3] == 0x3c) {
> -		unsigned int lba_count, desc_count;
> +		unsigned int lba_count;
>   
>   		sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]);
>   
> @@ -2867,9 +2875,9 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
>   			goto out;
>   
>   		lba_count = get_unaligned_be32(&buffer[20]);
> -		desc_count = get_unaligned_be32(&buffer[24]);
> +		sdkp->max_block_desc_count = get_unaligned_be32(&buffer[24]);
>   
> -		if (lba_count && desc_count)
> +		if (lba_count && sdkp->max_block_desc_count)
>   			sdkp->max_unmap_blocks = lba_count;
>   
>   		sdkp->unmap_granularity = get_unaligned_be32(&buffer[28]);
> diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
> index 0a33a4b68ffb..e396bcaf76ca 100644
> --- a/drivers/scsi/sd.h
> +++ b/drivers/scsi/sd.h
> @@ -99,6 +99,7 @@ struct scsi_disk {
>   	u32		opt_xfer_blocks;
>   	u32		max_ws_blocks;
>   	u32		max_unmap_blocks;
> +	u32		max_block_desc_count;
>   	u32		unmap_granularity;
>   	u32		unmap_alignment;
>   	u32		index;

  reply	other threads:[~2022-05-25  1:35 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-21 11:32 [RFC PATCH] scsi: support packing multi-segment in UNMAP command Chao Yu
2022-05-25  1:34 ` Chao Yu [this message]
2022-05-25  1:42   ` Martin K. Petersen
2022-05-25  1:58     ` Chao Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=138141eb-6bb9-88bc-cdb0-85f6df8b18cb@kernel.org \
    --to=chao@kernel.org \
    --cc=jejb@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox