Re: [PATCH v2 3/4] scsi_debug : iouring iopoll support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



See my comment further down.

On 2020-12-02 10:40 p.m., Kashyap Desai wrote:
Add support of iouring iopoll interface in scsi_debug.
This feature requires shared hosttag support in kernel and driver.

Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx>
Acked-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>
Tested-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>

Cc: dgilbert@xxxxxxxxxxxx
Cc: linux-block@xxxxxxxxxxxxxxx
---
  drivers/scsi/scsi_debug.c | 130 ++++++++++++++++++++++++++++++++++++++
  1 file changed, 130 insertions(+)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 24c0f7ec0351..4ced913f2b39 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -829,6 +829,7 @@ static int sdeb_zbc_max_open = DEF_ZBC_MAX_OPEN_ZONES;
  static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES;
static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */
+static int poll_queues; /* iouring iopoll interface.*/
  static struct sdebug_queue *sdebug_q_arr;  /* ptr to array of submit queues */
static DEFINE_RWLOCK(atomic_rw);
@@ -5432,6 +5433,14 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
  	cmnd->host_scribble = (unsigned char *)sqcp;
  	sd_dp = sqcp->sd_dp;
  	spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+
+	/* Do not complete IO from default completion path.
+	 * Let it to be on queue.
+	 * Completion should happen from mq_poll interface.
+	 */
+	if ((sqp - sdebug_q_arr) >= (submit_queues - poll_queues))
+		return 0;
+
  	if (!sd_dp) {
  		sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC);
  		if (!sd_dp) {
@@ -5615,6 +5624,7 @@ module_param_named(sector_size, sdebug_sector_size, int, S_IRUGO);
  module_param_named(statistics, sdebug_statistics, bool, S_IRUGO | S_IWUSR);
  module_param_named(strict, sdebug_strict, bool, S_IRUGO | S_IWUSR);
  module_param_named(submit_queues, submit_queues, int, S_IRUGO);
+module_param_named(poll_queues, poll_queues, int, S_IRUGO);
  module_param_named(tur_ms_to_ready, sdeb_tur_ms_to_ready, int, S_IRUGO);
  module_param_named(unmap_alignment, sdebug_unmap_alignment, int, S_IRUGO);
  module_param_named(unmap_granularity, sdebug_unmap_granularity, int, S_IRUGO);
@@ -5677,6 +5687,7 @@ MODULE_PARM_DESC(opt_xferlen_exp, "optimal transfer length granularity exponent
  MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)");
  MODULE_PARM_DESC(per_host_store, "If set, next positive add_host will get new store (def=0)");
  MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
+MODULE_PARM_DESC(poll_queues, "support for iouring iopoll queues (1 to max(submit_queues - 1)");
  MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
  MODULE_PARM_DESC(random, "If set, uniformly randomize command duration between 0 and delay_in_ns");
  MODULE_PARM_DESC(removable, "claim to have removable media (def=0)");
@@ -7200,6 +7211,104 @@ static int resp_not_ready(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
  	return check_condition_result;
  }
+static int sdebug_map_queues(struct Scsi_Host *shost)
+{
+	int i, qoff;
+
+	if (shost->nr_hw_queues == 1)
+		return 0;
+
+	for (i = 0, qoff = 0; i < HCTX_MAX_TYPES; i++) {
+		struct blk_mq_queue_map *map = &shost->tag_set.map[i];
+
+		map->nr_queues  = 0;
+
+		if (i == HCTX_TYPE_DEFAULT)
+			map->nr_queues = submit_queues - poll_queues;
+		else if (i == HCTX_TYPE_POLL)
+			map->nr_queues = poll_queues;
+
+		if (!map->nr_queues) {
+			BUG_ON(i == HCTX_TYPE_DEFAULT);
+			continue;
+		}
+
+		map->queue_offset = qoff;
+		blk_mq_map_queues(map);
+
+		qoff += map->nr_queues;
+	}
+
+	return 0;
+
+}
+
+static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
+{
+	int qc_idx;
+	int retiring = 0;
+	unsigned long iflags;
+	struct sdebug_queue *sqp;
+	struct sdebug_queued_cmd *sqcp;
+	struct scsi_cmnd *scp;
+	struct sdebug_dev_info *devip;
+	int num_entries = 0;
+
+	sqp = sdebug_q_arr + queue_num;
+
+	do {
+		spin_lock_irqsave(&sqp->qc_lock, iflags);
+		qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue);
+		if (unlikely((qc_idx < 0) || (qc_idx >= sdebug_max_queue)))
+			goto out;

If you are rolling this patchset again, perhaps you could change the "if"
above to:
		if (likely(qc_idx >= sdebug_max_queue))

since find_first_bit() returns unsigned long. Also, if we are polling,
unless the storage is extremely fast, we should see find_first_bit()
not finding any bits set most of the time. In that case it will return sdebug_max_queue, so flag it as (more) likely. That should also indicate
to someone reading the code that the "goto out" in this case is _not_
an error path and may well be the fast path.

Doug Gilbert



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux