All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bean Huo <huobean@gmail.com>
To: Bart Van Assche <bvanassche@acm.org>,
	"Martin K . Petersen" <martin.petersen@oracle.com>
Cc: Jaegeuk Kim <jaegeuk@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	linux-scsi@vger.kernel.org,
	"James E.J. Bottomley" <jejb@linux.ibm.com>,
	Bean Huo <beanhuo@micron.com>, Can Guo <cang@codeaurora.org>,
	Avri Altman <avri.altman@wdc.com>,
	Stanley Chu <stanley.chu@mediatek.com>,
	Asutosh Das <asutoshd@codeaurora.org>
Subject: Re: [PATCH v2 19/20] scsi: ufs: Implement polling support
Date: Tue, 30 Nov 2021 09:43:44 +0100	[thread overview]
Message-ID: <e0dc15c742c2f626a7149c3c44d53493fe1a9a44.camel@gmail.com> (raw)
In-Reply-To: <20211119195743.2817-20-bvanassche@acm.org>


Bart, 

We look forward to the support of UFSHCD polling, I did a review and
test. comments as below:


On Fri, 2021-11-19 at 11:57 -0800, Bart Van Assche wrote:
> The time spent in io_schedule() and also the interrupt latency are
> significant when submitting direct I/O to a UFS device. Hence this
> patch
> that implements polling support. User space software can enable
> polling by
> passing the RWF_HIPRI flag to the preadv2() system call or the
> IORING_SETUP_IOPOLL flag to the io_uring interface.
> 
> Although the block layer supports to partition the tag space for
> interrupt-based completions (HCTX_TYPE_DEFAULT) purposes and polling
> (HCTX_TYPE_POLL), the choice has been made to use the same hardware
> queue for both hctx types because partitioning the tag space would
> negatively affect performance.
> 
> On my test setup this patch increases IOPS from 2736 to 22000 (8x)
> for the
> following test:
> 
> for hipri in 0 1; do
>     fio --ioengine=io_uring --iodepth=1 --rw=randread \
>     --runtime=60 --time_based=1 --direct=1 --name=qd1 \
>     --filename=/dev/block/sda --ioscheduler=none --gtod_reduce=1 \
>     --norandommap --hipri=$hipri
> done

For 4KB random read, direct IO, and iodepth=1, we did not see an
improvement in IOPS due to this patch. Maybe the test case above is not
sufficient.


> 
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  drivers/scsi/ufs/ufshcd.c | 85 ++++++++++++++++++++++++++++++-------
> --
>  1 file changed, 65 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 9cf4a22f1950..14043d74389d 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -2629,6 +2629,36 @@ static inline bool is_device_wlun(struct
> scsi_device *sdev)
>  		ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN)
> ;
>  }
>  
> +/*
> + * Associate the UFS controller queue with the default and poll HCTX
> types.
> + * Initialize the mq_map[] arrays.
> + */
> +static int ufshcd_map_queues(struct Scsi_Host *shost)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < shost->nr_maps; i++) {
> +		struct blk_mq_queue_map *map = &shost->tag_set.map[i];
> +
> +		switch (i) {
> +		case HCTX_TYPE_DEFAULT:
> +		case HCTX_TYPE_POLL:
> +			map->nr_queues = 1;
> +			break;
> +		case HCTX_TYPE_READ:
> +			map->nr_queues = 0;
> +			break;
> +		default:
> +			WARN_ON_ONCE(true);
> +		}
> +		map->queue_offset = 0;
> +		ret = blk_mq_map_queues(map);
> +		WARN_ON_ONCE(ret);
> +	}
> +
> +	return 0;
> +}
> +
>  static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb
> *lrb, int i)
>  {
>  	struct utp_transfer_cmd_desc *cmd_descp = hba->ucdl_base_addr;
> @@ -2664,7 +2694,7 @@ static int ufshcd_queuecommand(struct Scsi_Host
> *host, struct scsi_cmnd *cmd)
>  	struct ufshcd_lrb *lrbp;
>  	int err = 0;
>  
> -	WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
> +	WARN_ONCE(tag < 0 || tag >= hba->nutrs, "Invalid tag %d\n",
> tag);
>  
>  	/*
>  	 * Allows the UFS error handler to wait for prior
> ufshcd_queuecommand()
> @@ -2925,7 +2955,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba
> *hba,
>  	}
>  	req = scsi_cmd_to_rq(scmd);
>  	tag = req->tag;
> -	WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
> +	WARN_ONCE(tag < 0 || tag >= hba->nutrs, "Invalid tag %d\n",
> tag)
probably this change should not in this patch?

>  	/*
>  	 * Start the request such that blk_mq_tag_idle() is called when
> the
>  	 * device management request finishes.
> @@ -5272,6 +5302,31 @@ static void __ufshcd_transfer_req_compl(struct
> ufs_hba *hba,
>  	}
>  }
>  
> +/*
> + * Returns > 0 if one or more commands have been completed or 0 if
> no
> + * requests have been completed.
> + */
> +static int ufshcd_poll(struct Scsi_Host *shost, unsigned int
> queue_num)
> +{
> +	struct ufs_hba *hba = shost_priv(shost);
> +	unsigned long completed_reqs, flags;
> +	u32 tr_doorbell;
> +
> +	spin_lock_irqsave(&hba->outstanding_lock, flags);
> +	tr_doorbell = ufshcd_readl(hba,
> REG_UTP_TRANSFER_REQ_DOOR_BELL);
> +	completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
> +	WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
> +		  "completed: %#lx; outstanding: %#lx\n",
> completed_reqs,
> +		  hba->outstanding_reqs);
> +	hba->outstanding_reqs &= ~completed_reqs;
> +	spin_unlock_irqrestore(&hba->outstanding_lock, flags);
> +
> +	if (completed_reqs)
> +		__ufshcd_transfer_req_compl(hba, completed_reqs);
> +
> +	return completed_reqs;
> +}
> +
>  /**
>   * ufshcd_transfer_req_compl - handle SCSI and query command
> completion
>   * @hba: per adapter instance
> @@ -5282,9 +5337,6 @@ static void __ufshcd_transfer_req_compl(struct
> ufs_hba *hba,
>   */
>  static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba)
>  {
> -	unsigned long completed_reqs, flags;
> -	u32 tr_doorbell;
> -
>  	/* Resetting interrupt aggregation counters first and reading
> the
>  	 * DOOR_BELL afterward allows us to handle all the completed
> requests.
>  	 * In order to prevent other interrupts starvation the DB is
> read once
> @@ -5299,21 +5351,9 @@ static irqreturn_t
> ufshcd_transfer_req_compl(struct ufs_hba *hba)
>  	if (ufs_fail_completion())
>  		return IRQ_HANDLED;
>  
> -	spin_lock_irqsave(&hba->outstanding_lock, flags);
> -	tr_doorbell = ufshcd_readl(hba,
> REG_UTP_TRANSFER_REQ_DOOR_BELL);
> -	completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
> -	WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
> -		  "completed: %#lx; outstanding: %#lx\n",
> completed_reqs,
> -		  hba->outstanding_reqs);
> -	hba->outstanding_reqs &= ~completed_reqs;
> -	spin_unlock_irqrestore(&hba->outstanding_lock, flags);
> +	ufshcd_poll(hba->host, 0);
>  
> -	if (completed_reqs) {
> -		__ufshcd_transfer_req_compl(hba, completed_reqs);
> -		return IRQ_HANDLED;
> -	} else {
> -		return IRQ_NONE;
> -	}
> +	return IRQ_HANDLED;
>  }
>  

ufshcd_transfer_req_compl() will never return IRQ_NONE,
but ufshcd_intr() needs this return to check the fake interrupt.


>  int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask)
> @@ -6564,6 +6604,8 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba
> *hba,
>  	spin_lock_irqsave(host->host_lock, flags);
>  
>  	task_tag = req->tag;
> +	WARN_ONCE(task_tag < 0 || task_tag >= hba->nutmrs, "Invalid tag
> %d\n",
> +		  task_tag);
>  	hba->tmf_rqs[req->tag] = req;
>  	treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
>  
> @@ -6705,7 +6747,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct
> ufs_hba *hba,
>  	}
>  	req = scsi_cmd_to_rq(scmd);
>  	tag = req->tag;
> -	WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
> +	WARN_ONCE(tag < 0 || tag >= hba->nutrs, "Invalid tag %d\n",
> tag);
>  	/*
>  	 * Start the request such that blk_mq_tag_idle() is called when
> the
>  	 * device management request finishes.
> @@ -8147,7 +8189,9 @@ static struct scsi_host_template
> ufshcd_driver_template = {
>  	.module			= THIS_MODULE,
>  	.name			= UFSHCD,
>  	.proc_name		= UFSHCD,
> +	.map_queues		= ufshcd_map_queues,
>  	.queuecommand		= ufshcd_queuecommand,
> +	.mq_poll		= ufshcd_poll,
>  	.slave_alloc		= ufshcd_slave_alloc,
>  	.slave_configure	= ufshcd_slave_configure,
>  	.slave_destroy		= ufshcd_slave_destroy,
> @@ -9437,6 +9481,7 @@ int ufshcd_alloc_host(struct device *dev,
> struct ufs_hba **hba_handle)
>  		err = -ENOMEM;
>  		goto out_error;
>  	}
> +	host->nr_maps = 3;

I don't understand why not directly uses HCTX_MAX_TYPES, 3 is already
maximum.

>  	hba = shost_priv(host);
>  	hba->host = host;
>  	hba->dev = dev;


  reply	other threads:[~2021-11-30  8:43 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-19 19:57 [PATCH v2 00/20] UFS patches for kernel v5.17 Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 01/20] block: Add a flag for internal commands Bart Van Assche
2021-11-22  8:46   ` John Garry
2021-11-22 17:38     ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 02/20] scsi: core: Unexport scsi_track_queue_full() Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 03/20] scsi: core: Fix scsi_device_max_queue_depth() Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 04/20] scsi: core: Fix a race between scsi_done() and scsi_times_out() Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 05/20] scsi: core: Add support for internal commands Bart Van Assche
2021-11-22  8:58   ` John Garry
2021-11-22 17:46     ` Bart Van Assche
2021-11-22 18:08       ` John Garry
2021-11-22 19:04       ` Bart Van Assche
2021-11-23  8:13       ` Hannes Reinecke
2021-11-23 17:46         ` Bart Van Assche
2021-11-23 19:18           ` Bart Van Assche
2021-11-24  6:33             ` Hannes Reinecke
2021-11-19 19:57 ` [PATCH v2 06/20] scsi: core: Add support for reserved tags Bart Van Assche
2021-11-22  8:15   ` John Garry
2021-11-22 17:25     ` Bart Van Assche
2021-11-22 18:13       ` John Garry
2021-11-19 19:57 ` [PATCH v2 07/20] scsi: ufs: Rename a function argument Bart Van Assche
2021-11-22 20:25   ` Bean Huo
2021-11-19 19:57 ` [PATCH v2 08/20] scsi: ufs: Remove is_rpmb_wlun() Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 09/20] scsi: ufs: Remove the sdev_rpmb member Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 10/20] scsi: ufs: Remove dead code Bart Van Assche
2021-11-24 11:11   ` Adrian Hunter
2021-11-29 19:12     ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 11/20] scsi: ufs: Switch to scsi_(get|put)_internal_cmd() Bart Van Assche
2021-11-23 12:20   ` Bean Huo
2021-11-23 17:54     ` Bart Van Assche
2021-11-23 19:41     ` Bart Van Assche
2021-11-24 18:18       ` Bean Huo
2021-11-24 11:02   ` Adrian Hunter
2021-11-24 11:15     ` Adrian Hunter
2021-11-29 19:32     ` Bart Van Assche
2021-11-30  6:41       ` Adrian Hunter
2021-11-30 17:51         ` Bart Van Assche
2021-11-30 19:15           ` Adrian Hunter
2021-11-30 19:21             ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 12/20] scsi: ufs: Rework ufshcd_change_queue_depth() Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 13/20] scsi: ufs: Fix a deadlock in the error handler Bart Van Assche
2021-11-30  8:54   ` Bean Huo
2021-11-30 17:52     ` Bart Van Assche
2021-11-30 19:32     ` Bart Van Assche
2021-12-01 13:44       ` Bean Huo
2021-12-01 18:31         ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 14/20] scsi: ufs: Introduce ufshcd_release_scsi_cmd() Bart Van Assche
2021-11-24 12:03   ` Adrian Hunter
2021-11-30 18:00     ` Bart Van Assche
2021-11-30 19:02       ` Adrian Hunter
2021-11-30 19:16         ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 15/20] scsi: ufs: Improve SCSI abort handling Bart Van Assche
2021-11-24 12:28   ` Adrian Hunter
2021-11-30  4:13     ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 16/20] scsi: ufs: Fix a kernel crash during shutdown Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 17/20] scsi: ufs: Stop using the clock scaling lock in the error handler Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 18/20] scsi: ufs: Optimize the command queueing code Bart Van Assche
2021-11-22 17:46   ` Asutosh Das (asd)
2021-11-22 18:13     ` Bart Van Assche
2021-11-22 23:02       ` Asutosh Das (asd)
2021-11-22 23:48         ` Bart Van Assche
2021-11-23 18:24           ` Asutosh Das (asd)
2021-12-01 18:33             ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 19/20] scsi: ufs: Implement polling support Bart Van Assche
2021-11-30  8:43   ` Bean Huo [this message]
2021-11-30  8:57     ` Avri Altman
2021-11-30  9:15       ` Bean Huo
2021-11-30 14:26     ` Bart Van Assche
2021-11-30 15:40       ` Bean Huo
2021-11-30 17:34         ` Bart Van Assche
2021-11-30 17:37     ` Bart Van Assche
2021-11-19 19:57 ` [PATCH v2 20/20] scsi: ufs: Fix race conditions related to driver data Bart Van Assche

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=e0dc15c742c2f626a7149c3c44d53493fe1a9a44.camel@gmail.com \
    --to=huobean@gmail.com \
    --cc=adrian.hunter@intel.com \
    --cc=asutoshd@codeaurora.org \
    --cc=avri.altman@wdc.com \
    --cc=beanhuo@micron.com \
    --cc=bvanassche@acm.org \
    --cc=cang@codeaurora.org \
    --cc=jaegeuk@kernel.org \
    --cc=jejb@linux.ibm.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=stanley.chu@mediatek.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.