All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] io_uring iopoll in scsi layer
@ 2021-02-01  5:16 Kashyap Desai
  2021-02-01  5:16 ` [PATCH v3 1/4] add io_uring with IOPOLL support " Kashyap Desai
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai

[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]

This patch series is to support io_uring iopoll feature
in scsi stack. This patch set requires shared hosttag support.

This patch set is created on top of 5.12/scsi-staging branch.
https://kernel.googlesource.com/pub/scm/linux/kernel/git/mkp/scsi/+/refs/heads/5.12/scsi-staging

v3 ->  
- added reviewed-by tag
- Fix comment provided by Hannes for below patch.
https://patchwork.kernel.org/project/linux-scsi/patch/20201203034100.29716-3-kashyap.desai@broadcom.com/
- Fix Functional issue of poll_queues settings not working in v2.

v2 -> 
- updated feedback from v1.
- added reviewed-by & tested-by tag
- remove flood of prints in scsi_debug driver during iopoll
  reported by Douglas Gilbert.
- added new patch to support to get shost from hctx.
  added new helper function "scsi_init_hctx"

v1 -> 
Fixed warnings in scsi_debug driver.
Reported-by: kernel test robot <lkp@intel.com>

Kashyap Desai (4):
  add io_uring with IOPOLL support in scsi layer
  megaraid_sas: iouring iopoll support
  scsi_debug : iouring iopoll support
  scsi: set shost as hctx driver_data

 drivers/scsi/megaraid/megaraid_sas.h        |   3 +
 drivers/scsi/megaraid/megaraid_sas_base.c   |  87 +++++++++++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  42 ++++++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   2 +
 drivers/scsi/scsi_debug.c                   | 130 ++++++++++++++++++++
 drivers/scsi/scsi_lib.c                     |  29 ++++-
 include/scsi/scsi_cmnd.h                    |   1 +
 include/scsi/scsi_host.h                    |  11 ++
 8 files changed, 291 insertions(+), 14 deletions(-)


base-commit: a927ec3995427e9c47752900ad2df0755d02aba5
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/4] add io_uring with IOPOLL support in scsi layer
  2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
@ 2021-02-01  5:16 ` Kashyap Desai
  2021-02-01  5:16 ` [PATCH v3 2/4] megaraid_sas: iouring iopoll support Kashyap Desai
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai, sumit.saxena, chandrakanth.patil, linux-block

[-- Attachment #1: Type: text/plain, Size: 3424 bytes --]

io_uring with IOPOLL is not currently supported in scsi mid layer.
Outside of that everything else should work and no extra support
in the driver is needed.

Currently io_uring with IOPOLL support is only available in block layer.
This patch is to extend support of mq_poll in scsi layer.

Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: John Garry <john.garry@huawei.com>

Cc: sumit.saxena@broadcom.com
Cc: chandrakanth.patil@broadcom.com
Cc: linux-block@vger.kernel.org
---
 drivers/scsi/scsi_lib.c  | 16 ++++++++++++++++
 include/scsi/scsi_cmnd.h |  1 +
 include/scsi/scsi_host.h | 11 +++++++++++
 3 files changed, 28 insertions(+)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d0ae586565f8..8c29bf0e4cfd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1789,6 +1789,19 @@ static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq,
 			       cmd->sense_buffer);
 }
 
+
+static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
+{
+	struct request_queue *q = hctx->queue;
+	struct scsi_device *sdev = q->queuedata;
+	struct Scsi_Host *shost = sdev->host;
+
+	if (shost->hostt->mq_poll)
+		return shost->hostt->mq_poll(shost, hctx->queue_num);
+
+	return 0;
+}
+
 static int scsi_map_queues(struct blk_mq_tag_set *set)
 {
 	struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set);
@@ -1856,6 +1869,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = {
 	.cleanup_rq	= scsi_cleanup_rq,
 	.busy		= scsi_mq_lld_busy,
 	.map_queues	= scsi_map_queues,
+	.poll		= scsi_mq_poll,
 };
 
 
@@ -1884,6 +1898,7 @@ static const struct blk_mq_ops scsi_mq_ops = {
 	.cleanup_rq	= scsi_cleanup_rq,
 	.busy		= scsi_mq_lld_busy,
 	.map_queues	= scsi_map_queues,
+	.poll		= scsi_mq_poll,
 };
 
 struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev)
@@ -1916,6 +1931,7 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
 	else
 		tag_set->ops = &scsi_mq_ops_no_commit;
 	tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1;
+	tag_set->nr_maps = shost->nr_maps ? : 1;
 	tag_set->queue_depth = shost->can_queue;
 	tag_set->cmd_size = cmd_size;
 	tag_set->numa_node = NUMA_NO_NODE;
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index ace15b5dc956..1d8a0f6ea8c5 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -10,6 +10,7 @@
 #include <linux/timer.h>
 #include <linux/scatterlist.h>
 #include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
 
 struct Scsi_Host;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index e30fd963b97d..3d627bf7b951 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -270,6 +270,16 @@ struct scsi_host_template {
 	 */
 	int (* map_queues)(struct Scsi_Host *shost);
 
+	/*
+	 * SCSI interface of blk_poll - poll for IO completions.
+	 * Possible interface only if scsi LLD expose multiple h/w queues.
+	 *
+	 * Return value: Number of completed entries found.
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* mq_poll)(struct Scsi_Host *shost, unsigned int queue_num);
+
 	/*
 	 * Check if scatterlists need to be padded for DMA draining.
 	 *
@@ -616,6 +626,7 @@ struct Scsi_Host {
 	 * the total queue depth is can_queue.
 	 */
 	unsigned nr_hw_queues;
+	unsigned nr_maps;
 	unsigned active_mode:2;
 	unsigned unchecked_isa_dma:1;
 
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/4] megaraid_sas: iouring iopoll support
  2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
  2021-02-01  5:16 ` [PATCH v3 1/4] add io_uring with IOPOLL support " Kashyap Desai
@ 2021-02-01  5:16 ` Kashyap Desai
  2021-02-01 15:06   ` Hannes Reinecke
  2021-02-01  5:16   ` Kashyap Desai
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai, sumit.saxena, chandrakanth.patil, linux-block

[-- Attachment #1: Type: text/plain, Size: 12754 bytes --]

Add support of iouring iopoll interface. This feature requires shared
hosttag support in kernel and driver.

Driver will work in non-IRQ mode = There will not be any msix vector
associated for poll_queues and h/w can still work in this mode.
MegaRaid h/w is single submission queue and multiple reply queue, but
using shared host tagset support it will enable simulated multiple hw queue.

Driver allocates some extra reply queues and it will be marked as poll_queue.
These poll_queues will not have associated msix vectors. All the IO
completion on this queue will be done from IOPOLL interface.

megaraid_sas driver having 8 poll_queues and using io_uring hiprio=1 settings,
It can reach 3.2M IOPs and there is zero interrupt generated by h/w.

This feature can be enabled using module parameter poll_queues.

Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: sumit.saxena@broadcom.com
Cc: chandrakanth.patil@broadcom.com
Cc: linux-block@vger.kernel.org
---
 drivers/scsi/megaraid/megaraid_sas.h        |  3 +
 drivers/scsi/megaraid/megaraid_sas_base.c   | 87 ++++++++++++++++++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 42 +++++++++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +
 4 files changed, 123 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 0f808d63580e..d8b1797e2768 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2212,6 +2212,7 @@ struct megasas_irq_context {
 	struct irq_poll irqpoll;
 	bool irq_poll_scheduled;
 	bool irq_line_enable;
+	atomic_t   in_used;
 };
 
 struct MR_DRV_SYSTEM_INFO {
@@ -2446,6 +2447,7 @@ struct megasas_instance {
 	bool support_pci_lane_margining;
 	u8  low_latency_index_start;
 	int perf_mode;
+	int iopoll_q_count;
 };
 
 struct MR_LD_VF_MAP {
@@ -2726,5 +2728,6 @@ void megasas_init_debugfs(void);
 void megasas_exit_debugfs(void);
 void megasas_setup_debugfs(struct megasas_instance *instance);
 void megasas_destroy_debugfs(struct megasas_instance *instance);
+int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num);
 
 #endif				/*LSI_MEGARAID_SAS_H */
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 63a4f48bdc75..25673d0ee524 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -114,6 +114,15 @@ unsigned int enable_sdev_max_qd;
 module_param(enable_sdev_max_qd, int, 0444);
 MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0");
 
+int poll_queues;
+module_param(poll_queues, int, 0444);
+MODULE_PARM_DESC(poll_queues, "Number of queues to be use for io_uring poll mode.\n\t\t"
+		"This parameter is effective only if host_tagset_enable=1 &\n\t\t"
+		"It is not applicable for MFI_SERIES. &\n\t\t"
+		"Driver will work in latency mode. &\n\t\t"
+		"High iops queues are not allocated &\n\t\t"
+		);
+
 int host_tagset_enable = 1;
 module_param(host_tagset_enable, int, 0444);
 MODULE_PARM_DESC(host_tagset_enable, "Shared host tagset enable/disable Default: enable(1)");
@@ -207,6 +216,7 @@ static bool support_pci_lane_margining;
 static spinlock_t poll_aen_lock;
 
 extern struct dentry *megasas_debugfs_root;
+extern int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num);
 
 void
 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
@@ -3127,14 +3137,37 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
 static int megasas_map_queues(struct Scsi_Host *shost)
 {
 	struct megasas_instance *instance;
+	int qoff = 0, offset;
+	struct blk_mq_queue_map *map;
 
 	instance = (struct megasas_instance *)shost->hostdata;
 
 	if (shost->nr_hw_queues == 1)
 		return 0;
 
-	return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT],
-			instance->pdev, instance->low_latency_index_start);
+	offset = instance->low_latency_index_start;
+
+	/* Setup Default hctx */
+	map = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
+	map->nr_queues = instance->msix_vectors - offset;
+	map->queue_offset = 0;
+	blk_mq_pci_map_queues(map, instance->pdev, offset);
+	qoff += map->nr_queues;
+	offset += map->nr_queues;
+
+	/* Setup Poll hctx */
+	map = &shost->tag_set.map[HCTX_TYPE_POLL];
+	map->nr_queues = instance->iopoll_q_count;
+	if (map->nr_queues) {
+		/*
+		 * The poll queue(s) doesn't have an IRQ (and hence IRQ
+		 * affinity), so use the regular blk-mq cpu mapping
+		 */
+		map->queue_offset = qoff;
+		blk_mq_map_queues(map);
+	}
+
+	return 0;
 }
 
 static void megasas_aen_polling(struct work_struct *work);
@@ -3446,6 +3479,7 @@ static struct scsi_host_template megasas_template = {
 	.shost_attrs = megaraid_host_attrs,
 	.bios_param = megasas_bios_param,
 	.map_queues = megasas_map_queues,
+	.mq_poll = megasas_blk_mq_poll,
 	.change_queue_depth = scsi_change_queue_depth,
 	.max_segment_size = 0xffffffff,
 };
@@ -5834,13 +5868,16 @@ __megasas_alloc_irq_vectors(struct megasas_instance *instance)
 	irq_flags = PCI_IRQ_MSIX;
 
 	if (instance->smp_affinity_enable)
-		irq_flags |= PCI_IRQ_AFFINITY;
+		irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
 	else
 		descp = NULL;
 
+	/* Do not allocate msix vectors for poll_queues.
+	 * msix_vectors is always within a range of FW supported reply queue.
+	 */
 	i = pci_alloc_irq_vectors_affinity(instance->pdev,
 		instance->low_latency_index_start,
-		instance->msix_vectors, irq_flags, descp);
+		instance->msix_vectors - instance->iopoll_q_count, irq_flags, descp);
 
 	return i;
 }
@@ -5856,10 +5893,30 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance)
 	int i;
 	unsigned int num_msix_req;
 
+	instance->iopoll_q_count = 0;
+	if ((instance->adapter_type != MFI_SERIES) &&
+		poll_queues) {
+
+		instance->perf_mode = MR_LATENCY_PERF_MODE;
+		instance->low_latency_index_start = 1;
+
+		/* reserve for default and non-mananged pre-vector. */
+		if (instance->msix_vectors > (poll_queues + 2))
+			instance->iopoll_q_count = poll_queues;
+		else
+			instance->iopoll_q_count = 0;
+
+		num_msix_req = num_online_cpus() + instance->low_latency_index_start;
+		instance->msix_vectors = min(num_msix_req,
+				instance->msix_vectors);
+
+	}
+
 	i = __megasas_alloc_irq_vectors(instance);
 
-	if ((instance->perf_mode == MR_BALANCED_PERF_MODE) &&
-	    (i != instance->msix_vectors)) {
+	if (((instance->perf_mode == MR_BALANCED_PERF_MODE)
+		|| instance->iopoll_q_count) &&
+	    (i != (instance->msix_vectors - instance->iopoll_q_count))) {
 		if (instance->msix_vectors)
 			pci_free_irq_vectors(instance->pdev);
 		/* Disable Balanced IOPS mode and try realloc vectors */
@@ -5870,12 +5927,15 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance)
 		instance->msix_vectors = min(num_msix_req,
 				instance->msix_vectors);
 
+		instance->iopoll_q_count = 0;
 		i = __megasas_alloc_irq_vectors(instance);
 
 	}
 
 	dev_info(&instance->pdev->dev,
-		"requested/available msix %d/%d\n", instance->msix_vectors, i);
+		"requested/available msix %d/%d poll_queue %d\n",
+			instance->msix_vectors - instance->iopoll_q_count,
+			i, instance->iopoll_q_count);
 
 	if (i > 0)
 		instance->msix_vectors = i;
@@ -6841,12 +6901,18 @@ static int megasas_io_attach(struct megasas_instance *instance)
 		instance->smp_affinity_enable) {
 		host->host_tagset = 1;
 		host->nr_hw_queues = instance->msix_vectors -
-			instance->low_latency_index_start;
+			instance->low_latency_index_start + instance->iopoll_q_count;
+		if (instance->iopoll_q_count)
+			host->nr_maps = 3;
+	} else {
+		instance->iopoll_q_count = 0;
 	}
 
 	dev_info(&instance->pdev->dev,
-		"Max firmware commands: %d shared with nr_hw_queues = %d\n",
-		instance->max_fw_cmds, host->nr_hw_queues);
+		"Max firmware commands: %d shared with default "
+		"hw_queues = %d poll_queues %d\n", instance->max_fw_cmds,
+		host->nr_hw_queues - instance->iopoll_q_count,
+		instance->iopoll_q_count);
 	/*
 	 * Notify the mid-layer about the new controller
 	 */
@@ -8859,6 +8925,7 @@ static int __init megasas_init(void)
 		msix_vectors = 1;
 		rdpq_enable = 0;
 		dual_qdepth_disable = 1;
+		poll_queues = 0;
 	}
 
 	/*
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 38fc9467c625..10b8157044bb 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -685,6 +685,8 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance)
 	fusion = instance->ctrl_context;
 
 	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	count += instance->iopoll_q_count;
+
 	fusion->reply_frames_desc_pool =
 			dma_pool_create("mr_reply", &instance->pdev->dev,
 				fusion->reply_alloc_sz * count, 16, 0);
@@ -779,6 +781,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance)
 	}
 
 	msix_count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	msix_count += instance->iopoll_q_count;
 
 	fusion->reply_frames_desc_pool = dma_pool_create("mr_rdpq",
 							 &instance->pdev->dev,
@@ -1129,7 +1132,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
 			MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0;
 	IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys);
 	IOCInitMessage->SenseBufferAddressHigh = cpu_to_le32(upper_32_bits(fusion->sense_phys_addr));
-	IOCInitMessage->HostMSIxVectors = instance->msix_vectors;
+	IOCInitMessage->HostMSIxVectors = instance->msix_vectors + instance->iopoll_q_count;
 	IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT;
 
 	time = ktime_get_real();
@@ -1823,6 +1826,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
 		 sizeof(union MPI2_SGE_IO_UNION))/16;
 
 	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	count += instance->iopoll_q_count;
+
 	for (i = 0 ; i < count; i++)
 		fusion->last_reply_idx[i] = 0;
 
@@ -1835,6 +1840,9 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
 				MEGASAS_FUSION_IOCTL_CMDS);
 	sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
 
+	for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++)
+		atomic_set(&fusion->busy_mq_poll[i], 0);
+
 	if (megasas_alloc_ioc_init_frame(instance))
 		return 1;
 
@@ -3500,6 +3508,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
 	if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
 		return IRQ_NONE;
 
+	if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1))
+		return 0;
+
 	num_completed = 0;
 
 	while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
@@ -3613,6 +3624,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
 					irq_context->irq_line_enable = true;
 					irq_poll_sched(&irq_context->irqpoll);
 				}
+				atomic_dec(&irq_context->in_used);
 				return num_completed;
 			}
 		}
@@ -3630,9 +3642,35 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
 				instance->reply_post_host_index_addr[0]);
 		megasas_check_and_restore_queue_depth(instance);
 	}
+
+	if (irq_context)
+		atomic_dec(&irq_context->in_used);
+
 	return num_completed;
 }
 
+int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
+{
+
+	struct megasas_instance *instance;
+	int num_entries = 0;
+	struct fusion_context *fusion;
+
+	instance = (struct megasas_instance *)shost->hostdata;
+
+	fusion = instance->ctrl_context;
+
+	queue_num = queue_num + instance->low_latency_index_start;
+
+	if (!atomic_add_unless(&fusion->busy_mq_poll[queue_num], 1, 1))
+		return 0;
+
+	num_entries = complete_cmd_fusion(instance, queue_num, NULL);
+	atomic_dec(&fusion->busy_mq_poll[queue_num]);
+
+	return num_entries;
+}
+
 /**
  * megasas_enable_irq_poll() - enable irqpoll
  * @instance:			Adapter soft state
@@ -4163,6 +4201,8 @@ void  megasas_reset_reply_desc(struct megasas_instance *instance)
 
 	fusion = instance->ctrl_context;
 	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
+	count += instance->iopoll_q_count;
+
 	for (i = 0 ; i < count ; i++) {
 		fusion->last_reply_idx[i] = 0;
 		reply_desc = fusion->reply_frames_desc[i];
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 30de4b01f703..ce84f811e5e1 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -1303,6 +1303,8 @@ struct fusion_context {
 	u8 *sense;
 	dma_addr_t sense_phys_addr;
 
+	atomic_t   busy_mq_poll[MAX_MSIX_QUEUES_FUSION];
+
 	dma_addr_t reply_frames_desc_phys[MAX_MSIX_QUEUES_FUSION];
 	union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc[MAX_MSIX_QUEUES_FUSION];
 	struct rdpq_alloc_detail rdpq_tracker[RDPQ_MAX_CHUNK_COUNT];
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/4] scsi_debug : iouring iopoll support
  2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
@ 2021-02-01  5:16   ` Kashyap Desai
  2021-02-01  5:16 ` [PATCH v3 2/4] megaraid_sas: iouring iopoll support Kashyap Desai
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai, dgilbert, linux-block

[-- Attachment #1: Type: text/plain, Size: 6838 bytes --]

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@broadcom.com>
Acked-by: Douglas Gilbert <dgilbert@interlog.com>
Tested-by: Douglas Gilbert <dgilbert@interlog.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>

Cc: dgilbert@interlog.com
Cc: linux-block@vger.kernel.org
---
 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 d1b0cbe1b5f1..746eec521f79 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)");
@@ -7201,6 +7212,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;
+
+		sqcp = &sqp->qc_arr[qc_idx];
+		scp = sqcp->a_cmnd;
+		if (unlikely(scp == NULL)) {
+			pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n",
+			       queue_num, qc_idx, __func__);
+			goto out;
+		}
+		devip = (struct sdebug_dev_info *)scp->device->hostdata;
+		if (likely(devip))
+			atomic_dec(&devip->num_in_q);
+		else
+			pr_err("devip=NULL from %s\n", __func__);
+		if (unlikely(atomic_read(&retired_max_queue) > 0))
+			retiring = 1;
+
+		sqcp->a_cmnd = NULL;
+		if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) {
+			pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n",
+				sqp, queue_num, qc_idx, __func__);
+			goto out;
+		}
+
+		if (unlikely(retiring)) {	/* user has reduced max_queue */
+			int k, retval;
+
+			retval = atomic_read(&retired_max_queue);
+			if (qc_idx >= retval) {
+				pr_err("index %d too large\n", retval);
+				goto out;
+			}
+			k = find_last_bit(sqp->in_use_bm, retval);
+			if ((k < sdebug_max_queue) || (k == retval))
+				atomic_set(&retired_max_queue, 0);
+			else
+				atomic_set(&retired_max_queue, k + 1);
+		}
+		spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+		scp->scsi_done(scp); /* callback to mid level */
+		num_entries++;
+	} while (1);
+
+out:
+	spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+	return num_entries;
+}
+
+
 static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 				   struct scsi_cmnd *scp)
 {
@@ -7380,6 +7489,8 @@ static struct scsi_host_template sdebug_driver_template = {
 	.ioctl =		scsi_debug_ioctl,
 	.queuecommand =		scsi_debug_queuecommand,
 	.change_queue_depth =	sdebug_change_qdepth,
+	.map_queues =		sdebug_map_queues,
+	.mq_poll =		sdebug_blk_mq_poll,
 	.eh_abort_handler =	scsi_debug_abort,
 	.eh_device_reset_handler = scsi_debug_device_reset,
 	.eh_target_reset_handler = scsi_debug_target_reset,
@@ -7427,6 +7538,25 @@ static int sdebug_driver_probe(struct device *dev)
 	if (sdebug_host_max_queue)
 		hpnt->host_tagset = 1;
 
+	/* poll queues are possible for nr_hw_queues > 1 */
+	if (hpnt->nr_hw_queues == 1 || (poll_queues < 1)) {
+		pr_warn("%s: trim poll_queues to 0. poll_q/nr_hw = (%d/%d)\n",
+			 my_name, poll_queues, hpnt->nr_hw_queues);
+		poll_queues = 0;
+	}
+
+	/*
+	 * Poll queues don't need interrupts, but we need at least one I/O queue
+	 * left over for non-polled I/O.
+	 * If condition not met, trim poll_queues to 1 (just for simplicity).
+	 */
+	if (poll_queues >= submit_queues) {
+		pr_warn("%s: trim poll_queues to 1\n", my_name);
+		poll_queues = 1;
+	}
+	if (poll_queues)
+		hpnt->nr_maps = 3;
+
 	sdbg_host->shost = hpnt;
 	*((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
 	if ((hpnt->this_id >= 0) && (sdebug_num_tgts > hpnt->this_id))
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/4] scsi_debug : iouring iopoll support
@ 2021-02-01  5:16   ` Kashyap Desai
  0 siblings, 0 replies; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai, dgilbert, linux-block

[-- Attachment #1: Type: text/plain, Size: 6838 bytes --]

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@broadcom.com>
Acked-by: Douglas Gilbert <dgilbert@interlog.com>
Tested-by: Douglas Gilbert <dgilbert@interlog.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>

Cc: dgilbert@interlog.com
Cc: linux-block@vger.kernel.org
---
 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 d1b0cbe1b5f1..746eec521f79 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)");
@@ -7201,6 +7212,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;
+
+		sqcp = &sqp->qc_arr[qc_idx];
+		scp = sqcp->a_cmnd;
+		if (unlikely(scp == NULL)) {
+			pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n",
+			       queue_num, qc_idx, __func__);
+			goto out;
+		}
+		devip = (struct sdebug_dev_info *)scp->device->hostdata;
+		if (likely(devip))
+			atomic_dec(&devip->num_in_q);
+		else
+			pr_err("devip=NULL from %s\n", __func__);
+		if (unlikely(atomic_read(&retired_max_queue) > 0))
+			retiring = 1;
+
+		sqcp->a_cmnd = NULL;
+		if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) {
+			pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n",
+				sqp, queue_num, qc_idx, __func__);
+			goto out;
+		}
+
+		if (unlikely(retiring)) {	/* user has reduced max_queue */
+			int k, retval;
+
+			retval = atomic_read(&retired_max_queue);
+			if (qc_idx >= retval) {
+				pr_err("index %d too large\n", retval);
+				goto out;
+			}
+			k = find_last_bit(sqp->in_use_bm, retval);
+			if ((k < sdebug_max_queue) || (k == retval))
+				atomic_set(&retired_max_queue, 0);
+			else
+				atomic_set(&retired_max_queue, k + 1);
+		}
+		spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+		scp->scsi_done(scp); /* callback to mid level */
+		num_entries++;
+	} while (1);
+
+out:
+	spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+	return num_entries;
+}
+
+
 static int scsi_debug_queuecommand(struct Scsi_Host *shost,
 				   struct scsi_cmnd *scp)
 {
@@ -7380,6 +7489,8 @@ static struct scsi_host_template sdebug_driver_template = {
 	.ioctl =		scsi_debug_ioctl,
 	.queuecommand =		scsi_debug_queuecommand,
 	.change_queue_depth =	sdebug_change_qdepth,
+	.map_queues =		sdebug_map_queues,
+	.mq_poll =		sdebug_blk_mq_poll,
 	.eh_abort_handler =	scsi_debug_abort,
 	.eh_device_reset_handler = scsi_debug_device_reset,
 	.eh_target_reset_handler = scsi_debug_target_reset,
@@ -7427,6 +7538,25 @@ static int sdebug_driver_probe(struct device *dev)
 	if (sdebug_host_max_queue)
 		hpnt->host_tagset = 1;
 
+	/* poll queues are possible for nr_hw_queues > 1 */
+	if (hpnt->nr_hw_queues == 1 || (poll_queues < 1)) {
+		pr_warn("%s: trim poll_queues to 0. poll_q/nr_hw = (%d/%d)\n",
+			 my_name, poll_queues, hpnt->nr_hw_queues);
+		poll_queues = 0;
+	}
+
+	/*
+	 * Poll queues don't need interrupts, but we need at least one I/O queue
+	 * left over for non-polled I/O.
+	 * If condition not met, trim poll_queues to 1 (just for simplicity).
+	 */
+	if (poll_queues >= submit_queues) {
+		pr_warn("%s: trim poll_queues to 1\n", my_name);
+		poll_queues = 1;
+	}
+	if (poll_queues)
+		hpnt->nr_maps = 3;
+
 	sdbg_host->shost = hpnt;
 	*((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
 	if ((hpnt->this_id >= 0) && (sdebug_num_tgts > hpnt->this_id))
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/4] scsi: set shost as hctx driver_data
  2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
                   ` (2 preceding siblings ...)
  2021-02-01  5:16   ` Kashyap Desai
@ 2021-02-01  5:16 ` Kashyap Desai
  2021-03-01  7:30   ` Hannes Reinecke
  2021-02-01 20:57 ` [PATCH v3 0/4] io_uring iopoll in scsi layer Douglas Gilbert
  4 siblings, 1 reply; 12+ messages in thread
From: Kashyap Desai @ 2021-02-01  5:16 UTC (permalink / raw)
  To: linux-scsi; +Cc: Kashyap Desai

[-- Attachment #1: Type: text/plain, Size: 2107 bytes --]

hctx->driver_data is not set for SCSI currently.
Separately set hctx->driver_data = shost.

Suggested-by: John Garry <john.garry@huawei.com>
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Reviewed-by: John Garry <john.garry@huawei.com>
---
 drivers/scsi/scsi_lib.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 8c29bf0e4cfd..f661c50f3b88 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1792,9 +1792,7 @@ static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq,
 
 static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
 {
-	struct request_queue *q = hctx->queue;
-	struct scsi_device *sdev = q->queuedata;
-	struct Scsi_Host *shost = sdev->host;
+	struct Scsi_Host *shost = hctx->driver_data;
 
 	if (shost->hostt->mq_poll)
 		return shost->hostt->mq_poll(shost, hctx->queue_num);
@@ -1802,6 +1800,15 @@ static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
 	return 0;
 }
 
+static int scsi_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
+			  unsigned int hctx_idx)
+{
+	struct Scsi_Host *shost = data;
+
+	hctx->driver_data = shost;
+	return 0;
+}
+
 static int scsi_map_queues(struct blk_mq_tag_set *set)
 {
 	struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set);
@@ -1869,15 +1876,14 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = {
 	.cleanup_rq	= scsi_cleanup_rq,
 	.busy		= scsi_mq_lld_busy,
 	.map_queues	= scsi_map_queues,
+	.init_hctx	= scsi_init_hctx,
 	.poll		= scsi_mq_poll,
 };
 
 
 static void scsi_commit_rqs(struct blk_mq_hw_ctx *hctx)
 {
-	struct request_queue *q = hctx->queue;
-	struct scsi_device *sdev = q->queuedata;
-	struct Scsi_Host *shost = sdev->host;
+	struct Scsi_Host *shost = hctx->driver_data;
 
 	shost->hostt->commit_rqs(shost, hctx->queue_num);
 }
@@ -1898,6 +1904,7 @@ static const struct blk_mq_ops scsi_mq_ops = {
 	.cleanup_rq	= scsi_cleanup_rq,
 	.busy		= scsi_mq_lld_busy,
 	.map_queues	= scsi_map_queues,
+	.init_hctx	= scsi_init_hctx,
 	.poll		= scsi_mq_poll,
 };
 
-- 
2.18.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/4] megaraid_sas: iouring iopoll support
  2021-02-01  5:16 ` [PATCH v3 2/4] megaraid_sas: iouring iopoll support Kashyap Desai
@ 2021-02-01 15:06   ` Hannes Reinecke
  2021-02-02 11:30     ` Kashyap Desai
  0 siblings, 1 reply; 12+ messages in thread
From: Hannes Reinecke @ 2021-02-01 15:06 UTC (permalink / raw)
  To: Kashyap Desai, linux-scsi; +Cc: sumit.saxena, chandrakanth.patil, linux-block

On 2/1/21 6:16 AM, Kashyap Desai wrote:
> Add support of iouring iopoll interface. This feature requires shared
> hosttag support in kernel and driver.
> 
> Driver will work in non-IRQ mode = There will not be any msix vector
> associated for poll_queues and h/w can still work in this mode.
> MegaRaid h/w is single submission queue and multiple reply queue, but
> using shared host tagset support it will enable simulated multiple hw queue.
> 
> Driver allocates some extra reply queues and it will be marked as poll_queue.
> These poll_queues will not have associated msix vectors. All the IO
> completion on this queue will be done from IOPOLL interface.
> 
> megaraid_sas driver having 8 poll_queues and using io_uring hiprio=1 settings,
> It can reach 3.2M IOPs and there is zero interrupt generated by h/w.
> 
> This feature can be enabled using module parameter poll_queues.
> 
> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
> Cc: sumit.saxena@broadcom.com
> Cc: chandrakanth.patil@broadcom.com
> Cc: linux-block@vger.kernel.org
> ---
>   drivers/scsi/megaraid/megaraid_sas.h        |  3 +
>   drivers/scsi/megaraid/megaraid_sas_base.c   | 87 ++++++++++++++++++---
>   drivers/scsi/megaraid/megaraid_sas_fusion.c | 42 +++++++++-
>   drivers/scsi/megaraid/megaraid_sas_fusion.h |  2 +
>   4 files changed, 123 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
> index 0f808d63580e..d8b1797e2768 100644
> --- a/drivers/scsi/megaraid/megaraid_sas.h
> +++ b/drivers/scsi/megaraid/megaraid_sas.h
> @@ -2212,6 +2212,7 @@ struct megasas_irq_context {
>   	struct irq_poll irqpoll;
>   	bool irq_poll_scheduled;
>   	bool irq_line_enable;
> +	atomic_t   in_used;
>   };
>   
>   struct MR_DRV_SYSTEM_INFO {
> @@ -2446,6 +2447,7 @@ struct megasas_instance {
>   	bool support_pci_lane_margining;
>   	u8  low_latency_index_start;
>   	int perf_mode;
> +	int iopoll_q_count;
>   };
>   
>   struct MR_LD_VF_MAP {
> @@ -2726,5 +2728,6 @@ void megasas_init_debugfs(void);
>   void megasas_exit_debugfs(void);
>   void megasas_setup_debugfs(struct megasas_instance *instance);
>   void megasas_destroy_debugfs(struct megasas_instance *instance);
> +int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num);
>   
>   #endif				/*LSI_MEGARAID_SAS_H */
> diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
> index 63a4f48bdc75..25673d0ee524 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_base.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
> @@ -114,6 +114,15 @@ unsigned int enable_sdev_max_qd;
>   module_param(enable_sdev_max_qd, int, 0444);
>   MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0");
>   
> +int poll_queues;
> +module_param(poll_queues, int, 0444);
> +MODULE_PARM_DESC(poll_queues, "Number of queues to be use for io_uring poll mode.\n\t\t"
> +		"This parameter is effective only if host_tagset_enable=1 &\n\t\t"
> +		"It is not applicable for MFI_SERIES. &\n\t\t"
> +		"Driver will work in latency mode. &\n\t\t"
> +		"High iops queues are not allocated &\n\t\t"
> +		);
> +
>   int host_tagset_enable = 1;
>   module_param(host_tagset_enable, int, 0444);
>   MODULE_PARM_DESC(host_tagset_enable, "Shared host tagset enable/disable Default: enable(1)");
> @@ -207,6 +216,7 @@ static bool support_pci_lane_margining;
>   static spinlock_t poll_aen_lock;
>   
>   extern struct dentry *megasas_debugfs_root;
> +extern int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num);
>   
>   void
>   megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
> @@ -3127,14 +3137,37 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
>   static int megasas_map_queues(struct Scsi_Host *shost)
>   {
>   	struct megasas_instance *instance;
> +	int qoff = 0, offset;
> +	struct blk_mq_queue_map *map;
>   
>   	instance = (struct megasas_instance *)shost->hostdata;
>   
>   	if (shost->nr_hw_queues == 1)
>   		return 0;
>   
> -	return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT],
> -			instance->pdev, instance->low_latency_index_start);
> +	offset = instance->low_latency_index_start;
> +
> +	/* Setup Default hctx */
> +	map = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
> +	map->nr_queues = instance->msix_vectors - offset;
> +	map->queue_offset = 0;
> +	blk_mq_pci_map_queues(map, instance->pdev, offset);
> +	qoff += map->nr_queues;
> +	offset += map->nr_queues;
> +
> +	/* Setup Poll hctx */
> +	map = &shost->tag_set.map[HCTX_TYPE_POLL];
> +	map->nr_queues = instance->iopoll_q_count;
> +	if (map->nr_queues) {
> +		/*
> +		 * The poll queue(s) doesn't have an IRQ (and hence IRQ
> +		 * affinity), so use the regular blk-mq cpu mapping
> +		 */
> +		map->queue_offset = qoff;
> +		blk_mq_map_queues(map);
> +	}
> +
> +	return 0;
>   }
>   
>   static void megasas_aen_polling(struct work_struct *work);
> @@ -3446,6 +3479,7 @@ static struct scsi_host_template megasas_template = {
>   	.shost_attrs = megaraid_host_attrs,
>   	.bios_param = megasas_bios_param,
>   	.map_queues = megasas_map_queues,
> +	.mq_poll = megasas_blk_mq_poll,
>   	.change_queue_depth = scsi_change_queue_depth,
>   	.max_segment_size = 0xffffffff,
>   };
> @@ -5834,13 +5868,16 @@ __megasas_alloc_irq_vectors(struct megasas_instance *instance)
>   	irq_flags = PCI_IRQ_MSIX;
>   
>   	if (instance->smp_affinity_enable)
> -		irq_flags |= PCI_IRQ_AFFINITY;
> +		irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES;
>   	else
>   		descp = NULL;
>   
> +	/* Do not allocate msix vectors for poll_queues.
> +	 * msix_vectors is always within a range of FW supported reply queue.
> +	 */
>   	i = pci_alloc_irq_vectors_affinity(instance->pdev,
>   		instance->low_latency_index_start,
> -		instance->msix_vectors, irq_flags, descp);
> +		instance->msix_vectors - instance->iopoll_q_count, irq_flags, descp);
>   
>   	return i;
>   }
> @@ -5856,10 +5893,30 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance)
>   	int i;
>   	unsigned int num_msix_req;
>   
> +	instance->iopoll_q_count = 0;
> +	if ((instance->adapter_type != MFI_SERIES) &&
> +		poll_queues) {
> +
> +		instance->perf_mode = MR_LATENCY_PERF_MODE;
> +		instance->low_latency_index_start = 1;
> +
> +		/* reserve for default and non-mananged pre-vector. */
> +		if (instance->msix_vectors > (poll_queues + 2))
> +			instance->iopoll_q_count = poll_queues;
> +		else
> +			instance->iopoll_q_count = 0;
> +
> +		num_msix_req = num_online_cpus() + instance->low_latency_index_start;
> +		instance->msix_vectors = min(num_msix_req,
> +				instance->msix_vectors);
> +
> +	}
> +
>   	i = __megasas_alloc_irq_vectors(instance);
>   
> -	if ((instance->perf_mode == MR_BALANCED_PERF_MODE) &&
> -	    (i != instance->msix_vectors)) {
> +	if (((instance->perf_mode == MR_BALANCED_PERF_MODE)
> +		|| instance->iopoll_q_count) &&
> +	    (i != (instance->msix_vectors - instance->iopoll_q_count))) {
>   		if (instance->msix_vectors)
>   			pci_free_irq_vectors(instance->pdev);
>   		/* Disable Balanced IOPS mode and try realloc vectors */
> @@ -5870,12 +5927,15 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance)
>   		instance->msix_vectors = min(num_msix_req,
>   				instance->msix_vectors);
>   
> +		instance->iopoll_q_count = 0;
>   		i = __megasas_alloc_irq_vectors(instance);
>   
>   	}
>   
>   	dev_info(&instance->pdev->dev,
> -		"requested/available msix %d/%d\n", instance->msix_vectors, i);
> +		"requested/available msix %d/%d poll_queue %d\n",
> +			instance->msix_vectors - instance->iopoll_q_count,
> +			i, instance->iopoll_q_count);
>   
>   	if (i > 0)
>   		instance->msix_vectors = i;
> @@ -6841,12 +6901,18 @@ static int megasas_io_attach(struct megasas_instance *instance)
>   		instance->smp_affinity_enable) {
>   		host->host_tagset = 1;
>   		host->nr_hw_queues = instance->msix_vectors -
> -			instance->low_latency_index_start;
> +			instance->low_latency_index_start + instance->iopoll_q_count;
> +		if (instance->iopoll_q_count)
> +			host->nr_maps = 3;
> +	} else {
> +		instance->iopoll_q_count = 0;
>   	}
>   
>   	dev_info(&instance->pdev->dev,
> -		"Max firmware commands: %d shared with nr_hw_queues = %d\n",
> -		instance->max_fw_cmds, host->nr_hw_queues);
> +		"Max firmware commands: %d shared with default "
> +		"hw_queues = %d poll_queues %d\n", instance->max_fw_cmds,
> +		host->nr_hw_queues - instance->iopoll_q_count,
> +		instance->iopoll_q_count);
>   	/*
>   	 * Notify the mid-layer about the new controller
>   	 */
> @@ -8859,6 +8925,7 @@ static int __init megasas_init(void)
>   		msix_vectors = 1;
>   		rdpq_enable = 0;
>   		dual_qdepth_disable = 1;
> +		poll_queues = 0;
>   	}
>   
>   	/*
> diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> index 38fc9467c625..10b8157044bb 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> @@ -685,6 +685,8 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance)
>   	fusion = instance->ctrl_context;
>   
>   	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
> +	count += instance->iopoll_q_count;
> +
>   	fusion->reply_frames_desc_pool =
>   			dma_pool_create("mr_reply", &instance->pdev->dev,
>   				fusion->reply_alloc_sz * count, 16, 0);
> @@ -779,6 +781,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance)
>   	}
>   
>   	msix_count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
> +	msix_count += instance->iopoll_q_count;
>   
>   	fusion->reply_frames_desc_pool = dma_pool_create("mr_rdpq",
>   							 &instance->pdev->dev,
> @@ -1129,7 +1132,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
>   			MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0;
>   	IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys);
>   	IOCInitMessage->SenseBufferAddressHigh = cpu_to_le32(upper_32_bits(fusion->sense_phys_addr));
> -	IOCInitMessage->HostMSIxVectors = instance->msix_vectors;
> +	IOCInitMessage->HostMSIxVectors = instance->msix_vectors + instance->iopoll_q_count;
>   	IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT;
>   
>   	time = ktime_get_real();
> @@ -1823,6 +1826,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
>   		 sizeof(union MPI2_SGE_IO_UNION))/16;
>   
>   	count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
> +	count += instance->iopoll_q_count;
> +
>   	for (i = 0 ; i < count; i++)
>   		fusion->last_reply_idx[i] = 0;
>   
> @@ -1835,6 +1840,9 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
>   				MEGASAS_FUSION_IOCTL_CMDS);
>   	sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
>   
> +	for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++)
> +		atomic_set(&fusion->busy_mq_poll[i], 0);
> +
>   	if (megasas_alloc_ioc_init_frame(instance))
>   		return 1;
>   
> @@ -3500,6 +3508,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
>   	if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
>   		return IRQ_NONE;
>   
> +	if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1))
> +		return 0;
> +
>   	num_completed = 0;
>   
>   	while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
> @@ -3613,6 +3624,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
>   					irq_context->irq_line_enable = true;
>   					irq_poll_sched(&irq_context->irqpoll);
>   				}
> +				atomic_dec(&irq_context->in_used);
>   				return num_completed;
>   			}
>   		}
> @@ -3630,9 +3642,35 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex,
>   				instance->reply_post_host_index_addr[0]);
>   		megasas_check_and_restore_queue_depth(instance);
>   	}
> +
> +	if (irq_context)
> +		atomic_dec(&irq_context->in_used);
> +
>   	return num_completed;
>   }
>   
> +int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
> +{
> +
> +	struct megasas_instance *instance;
> +	int num_entries = 0;
> +	struct fusion_context *fusion;
> +
> +	instance = (struct megasas_instance *)shost->hostdata;
> +
> +	fusion = instance->ctrl_context;
> +
> +	queue_num = queue_num + instance->low_latency_index_start;
> +
> +	if (!atomic_add_unless(&fusion->busy_mq_poll[queue_num], 1, 1))
> +		return 0;
> +
> +	num_entries = complete_cmd_fusion(instance, queue_num, NULL);
> +	atomic_dec(&fusion->busy_mq_poll[queue_num]);
> +
> +	return num_entries;
> +}
> +
>   /**
>    * megasas_enable_irq_poll() - enable irqpoll
>    * @instance:			Adapter soft state

I really wonder if we need the atomic counter here.
complete_cmd_fusion() will already return the number of completed 
commands, so the only benefit we're getting is to avoid calling 
complete_cmd_fusion() if no commands are pending.
But if no commands are pending we are necessarily off the hot path 
anyway, so calling complete_cmd_fusion() here (and have it return 0) 
should matter much.
Am I wrong?

Otherwise: All thumbs up for this work. Very good job.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare@suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/4] io_uring iopoll in scsi layer
  2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
                   ` (3 preceding siblings ...)
  2021-02-01  5:16 ` [PATCH v3 4/4] scsi: set shost as hctx driver_data Kashyap Desai
@ 2021-02-01 20:57 ` Douglas Gilbert
  2021-02-02 10:32   ` Kashyap Desai
  4 siblings, 1 reply; 12+ messages in thread
From: Douglas Gilbert @ 2021-02-01 20:57 UTC (permalink / raw)
  To: Kashyap Desai, linux-scsi

On 2021-02-01 12:16 a.m., Kashyap Desai wrote:
> This patch series is to support io_uring iopoll feature
> in scsi stack. This patch set requires shared hosttag support.
> 
> This patch set is created on top of 5.12/scsi-staging branch.
> https://kernel.googlesource.com/pub/scm/linux/kernel/git/mkp/scsi/+/refs/heads/5.12/scsi-staging

Hi,
I don't understand how this patchset works. My testing shows
scsi_debug is broken and I will be sending a correcting patch
shortly (similar to the one I sent you on 20210108).

The scsi_debug driver is a simplified LLD that needs to know in
advance whether a request/command issued to it will be using the
.mq_poll callback. Perhaps you have found another way but one
simple way to find that out is this test:
    if (request->cmd_flags & REQ_HIPRI)

In the case of scsi_debug (after my patch) the delay associated with
the command is not wired up to generate an event which leads to
completion. Instead, callbacks through .mq_poll are expected and
they will check if that delay has expired, if not the callback returns
0. When the delay has expired and a .mq_poll is received then completion
occurs.

Doug Gilbert

> v3 ->
> - added reviewed-by tag
> - Fix comment provided by Hannes for below patch.
> https://patchwork.kernel.org/project/linux-scsi/patch/20201203034100.29716-3-kashyap.desai@broadcom.com/
> - Fix Functional issue of poll_queues settings not working in v2.
> 
> v2 ->
> - updated feedback from v1.
> - added reviewed-by & tested-by tag
> - remove flood of prints in scsi_debug driver during iopoll
>    reported by Douglas Gilbert.
> - added new patch to support to get shost from hctx.
>    added new helper function "scsi_init_hctx"
> 
> v1 ->
> Fixed warnings in scsi_debug driver.
> Reported-by: kernel test robot <lkp@intel.com>
> 
> Kashyap Desai (4):
>    add io_uring with IOPOLL support in scsi layer
>    megaraid_sas: iouring iopoll support
>    scsi_debug : iouring iopoll support
>    scsi: set shost as hctx driver_data
> 
>   drivers/scsi/megaraid/megaraid_sas.h        |   3 +
>   drivers/scsi/megaraid/megaraid_sas_base.c   |  87 +++++++++++--
>   drivers/scsi/megaraid/megaraid_sas_fusion.c |  42 ++++++-
>   drivers/scsi/megaraid/megaraid_sas_fusion.h |   2 +
>   drivers/scsi/scsi_debug.c                   | 130 ++++++++++++++++++++
>   drivers/scsi/scsi_lib.c                     |  29 ++++-
>   include/scsi/scsi_cmnd.h                    |   1 +
>   include/scsi/scsi_host.h                    |  11 ++
>   8 files changed, 291 insertions(+), 14 deletions(-)
> 
> 
> base-commit: a927ec3995427e9c47752900ad2df0755d02aba5
> 


^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH v3 0/4] io_uring iopoll in scsi layer
  2021-02-01 20:57 ` [PATCH v3 0/4] io_uring iopoll in scsi layer Douglas Gilbert
@ 2021-02-02 10:32   ` Kashyap Desai
  2021-02-02 18:54     ` Douglas Gilbert
  0 siblings, 1 reply; 12+ messages in thread
From: Kashyap Desai @ 2021-02-02 10:32 UTC (permalink / raw)
  To: dgilbert, linux-scsi

[-- Attachment #1: Type: text/plain, Size: 3067 bytes --]

> Hi,
> I don't understand how this patchset works. My testing shows scsi_debug is
> broken and I will be sending a correcting patch shortly (similar to the
> one I
> sent you on 20210108).

Hi Doug -

scsi_debug patch from this series works on my setup. I was under impression
that you want this patch to be available in tree and on top of current
patchset, you want to have further incremental update.
What do you suggest ? Do you want me to wait for your updated patch OR We
can ask Martin to pick all the patches except scsi_debug ? You can post
scsi_debug changes as another series or separate patch.

I have few more megaraid_sas patches in pipeline, so I am looking for this
series to be available as baseline.

Kashyap

>
> The scsi_debug driver is a simplified LLD that needs to know in advance
> whether a request/command issued to it will be using the .mq_poll
> callback.
> Perhaps you have found another way but one simple way to find that out is
> this test:
>     if (request->cmd_flags & REQ_HIPRI)
>

Agree. I am not very much familiar with scsi_debug code so used current code
change as starting point and from there things can be improved.

> In the case of scsi_debug (after my patch) the delay associated with the
> command is not wired up to generate an event which leads to completion.
> Instead, callbacks through .mq_poll are expected and they will check if
> that
> delay has expired, if not the callback returns 0. When the delay has
> expired
> and a .mq_poll is received then completion occurs.
>
> Doug Gilbert
>
> > v3 ->
> > - added reviewed-by tag
> > - Fix comment provided by Hannes for below patch.
> > https://patchwork.kernel.org/project/linux-scsi/patch/20201203034100.2
> > 9716-3-kashyap.desai@broadcom.com/
> > - Fix Functional issue of poll_queues settings not working in v2.
> >
> > v2 ->
> > - updated feedback from v1.
> > - added reviewed-by & tested-by tag
> > - remove flood of prints in scsi_debug driver during iopoll
> >    reported by Douglas Gilbert.
> > - added new patch to support to get shost from hctx.
> >    added new helper function "scsi_init_hctx"
> >
> > v1 ->
> > Fixed warnings in scsi_debug driver.
> > Reported-by: kernel test robot <lkp@intel.com>
> >
> > Kashyap Desai (4):
> >    add io_uring with IOPOLL support in scsi layer
> >    megaraid_sas: iouring iopoll support
> >    scsi_debug : iouring iopoll support
> >    scsi: set shost as hctx driver_data
> >
> >   drivers/scsi/megaraid/megaraid_sas.h        |   3 +
> >   drivers/scsi/megaraid/megaraid_sas_base.c   |  87 +++++++++++--
> >   drivers/scsi/megaraid/megaraid_sas_fusion.c |  42 ++++++-
> >   drivers/scsi/megaraid/megaraid_sas_fusion.h |   2 +
> >   drivers/scsi/scsi_debug.c                   | 130 ++++++++++++++++++++
> >   drivers/scsi/scsi_lib.c                     |  29 ++++-
> >   include/scsi/scsi_cmnd.h                    |   1 +
> >   include/scsi/scsi_host.h                    |  11 ++
> >   8 files changed, 291 insertions(+), 14 deletions(-)
> >
> >
> > base-commit: a927ec3995427e9c47752900ad2df0755d02aba5
> >

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH v3 2/4] megaraid_sas: iouring iopoll support
  2021-02-01 15:06   ` Hannes Reinecke
@ 2021-02-02 11:30     ` Kashyap Desai
  0 siblings, 0 replies; 12+ messages in thread
From: Kashyap Desai @ 2021-02-02 11:30 UTC (permalink / raw)
  To: Hannes Reinecke, linux-scsi; +Cc: Sumit Saxena, Chandrakanth Patil, linux-block

[-- Attachment #1: Type: text/plain, Size: 2171 bytes --]

> >
> > +int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int
> > +queue_num) {
> > +
> > +	struct megasas_instance *instance;
> > +	int num_entries = 0;
> > +	struct fusion_context *fusion;
> > +
> > +	instance = (struct megasas_instance *)shost->hostdata;
> > +
> > +	fusion = instance->ctrl_context;
> > +
> > +	queue_num = queue_num + instance->low_latency_index_start;
> > +
> > +	if (!atomic_add_unless(&fusion->busy_mq_poll[queue_num], 1, 1))
> > +		return 0;
> > +
> > +	num_entries = complete_cmd_fusion(instance, queue_num, NULL);
> > +	atomic_dec(&fusion->busy_mq_poll[queue_num]);
> > +
> > +	return num_entries;
> > +}
> > +
> >   /**
> >    * megasas_enable_irq_poll() - enable irqpoll
> >    * @instance:			Adapter soft state
>
> I really wonder if we need the atomic counter here.
> complete_cmd_fusion() will already return the number of completed
> commands, so the only benefit we're getting is to avoid calling
> complete_cmd_fusion() if no commands are pending.
> But if no commands are pending we are necessarily off the hot path anyway,
> so calling complete_cmd_fusion() here (and have it return 0) should matter
> much.
> Am I wrong?
Hannes -

I think you are talking about busy_mq_poll atomic counter. This counter
avoid race condition of having complete_cmd_fusion() (for specific
queue_number) called from multiple context.
It is possible that we have hctx0 (which is in polled mode) with multiple
cpu_mask. Without this counter, more than one poll thread can attempt to
poll on hctx0 and we will end up in panic or some other issues. This counter
will make sure poll is executed from only one context and if poll on
specific hctx is active, another poll will simply return as very first poll
will take care the completion.

Kashyap

>
> Otherwise: All thumbs up for this work. Very good job.
>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke                Kernel Storage Architect
> hare@suse.de                              +49 911 74053 688
> SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809
> (AG Nürnberg), Geschäftsführer: Felix Imendörffer

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/4] io_uring iopoll in scsi layer
  2021-02-02 10:32   ` Kashyap Desai
@ 2021-02-02 18:54     ` Douglas Gilbert
  0 siblings, 0 replies; 12+ messages in thread
From: Douglas Gilbert @ 2021-02-02 18:54 UTC (permalink / raw)
  To: Kashyap Desai, linux-scsi

On 2021-02-02 5:32 a.m., Kashyap Desai wrote:
>> Hi,
>> I don't understand how this patchset works. My testing shows scsi_debug is
>> broken and I will be sending a correcting patch shortly (similar to the
>> one I
>> sent you on 20210108).
> 
> Hi Doug -
> 
> scsi_debug patch from this series works on my setup. I was under impression
> that you want this patch to be available in tree and on top of current
> patchset, you want to have further incremental update.
> What do you suggest ? Do you want me to wait for your updated patch OR We
> can ask Martin to pick all the patches except scsi_debug ? You can post
> scsi_debug changes as another series or separate patch.

Kashyap,
I did post a fixing patch titled: "[PATCH] scsi_debug: add new defer_type
for mq_poll" and cc-ed it to you.

At first I also thought your scsi_debug patch worked but on closer
examination it was falling through to the existing
delay_expired-event_generated model. It was only when I checked for
requests with REQ_HIPRI set and in those cases turned off the event
generation, that I saw it was not working.

Another way to tell if iopoll/blk_poll is really working is to turn off
the code that drives blk_poll(). What should happen in that case (due to
the mid layer) is that the command timeout (after 60 seconds?) should
cancel the command. If the command still manages to succeed normally
then iopoll is not really working.

> I have few more megaraid_sas patches in pipeline, so I am looking for this
> series to be available as baseline.

And on my side the most recent "[PATCH v15 00/45] sg: add v4 interface"
patchset [20210225] included "[PATCH v15 44/45] sg: add blk_poll support".
Jens accepted a patch to the fio sg engine to use the "hipri=1" option
to drive that new capability. This is an addition to the fio script
example that you sent using io_uring:

[global]
ioengine=io_uring
hipri=1
direct=1
runtime=3s
rw=randread
norandommap
bs=512

[seqprecon]
filename=/dev/sdb


Doug Gilbert


>> The scsi_debug driver is a simplified LLD that needs to know in advance
>> whether a request/command issued to it will be using the .mq_poll
>> callback.
>> Perhaps you have found another way but one simple way to find that out is
>> this test:
>>      if (request->cmd_flags & REQ_HIPRI)
>>
> 
> Agree. I am not very much familiar with scsi_debug code so used current code
> change as starting point and from there things can be improved.
> 
>> In the case of scsi_debug (after my patch) the delay associated with the
>> command is not wired up to generate an event which leads to completion.
>> Instead, callbacks through .mq_poll are expected and they will check if
>> that
>> delay has expired, if not the callback returns 0. When the delay has
>> expired
>> and a .mq_poll is received then completion occurs.
>>
>> Doug Gilbert
>>
>>> v3 ->
>>> - added reviewed-by tag
>>> - Fix comment provided by Hannes for below patch.
>>> https://patchwork.kernel.org/project/linux-scsi/patch/20201203034100.2
>>> 9716-3-kashyap.desai@broadcom.com/
>>> - Fix Functional issue of poll_queues settings not working in v2.
>>>
>>> v2 ->
>>> - updated feedback from v1.
>>> - added reviewed-by & tested-by tag
>>> - remove flood of prints in scsi_debug driver during iopoll
>>>     reported by Douglas Gilbert.
>>> - added new patch to support to get shost from hctx.
>>>     added new helper function "scsi_init_hctx"
>>>
>>> v1 ->
>>> Fixed warnings in scsi_debug driver.
>>> Reported-by: kernel test robot <lkp@intel.com>
>>>
>>> Kashyap Desai (4):
>>>     add io_uring with IOPOLL support in scsi layer
>>>     megaraid_sas: iouring iopoll support
>>>     scsi_debug : iouring iopoll support
>>>     scsi: set shost as hctx driver_data
>>>
>>>    drivers/scsi/megaraid/megaraid_sas.h        |   3 +
>>>    drivers/scsi/megaraid/megaraid_sas_base.c   |  87 +++++++++++--
>>>    drivers/scsi/megaraid/megaraid_sas_fusion.c |  42 ++++++-
>>>    drivers/scsi/megaraid/megaraid_sas_fusion.h |   2 +
>>>    drivers/scsi/scsi_debug.c                   | 130 ++++++++++++++++++++
>>>    drivers/scsi/scsi_lib.c                     |  29 ++++-
>>>    include/scsi/scsi_cmnd.h                    |   1 +
>>>    include/scsi/scsi_host.h                    |  11 ++
>>>    8 files changed, 291 insertions(+), 14 deletions(-)
>>>
>>>
>>> base-commit: a927ec3995427e9c47752900ad2df0755d02aba5
>>>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 4/4] scsi: set shost as hctx driver_data
  2021-02-01  5:16 ` [PATCH v3 4/4] scsi: set shost as hctx driver_data Kashyap Desai
@ 2021-03-01  7:30   ` Hannes Reinecke
  0 siblings, 0 replies; 12+ messages in thread
From: Hannes Reinecke @ 2021-03-01  7:30 UTC (permalink / raw)
  To: Kashyap Desai, linux-scsi

On 2/1/21 6:16 AM, Kashyap Desai wrote:
> hctx->driver_data is not set for SCSI currently.
> Separately set hctx->driver_data = shost.
> 
> Suggested-by: John Garry <john.garry@huawei.com>
> Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
> Reviewed-by: John Garry <john.garry@huawei.com>
> ---
>   drivers/scsi/scsi_lib.c | 19 +++++++++++++------
>   1 file changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 8c29bf0e4cfd..f661c50f3b88 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -1792,9 +1792,7 @@ static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq,
>   
>   static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
>   {
> -	struct request_queue *q = hctx->queue;
> -	struct scsi_device *sdev = q->queuedata;
> -	struct Scsi_Host *shost = sdev->host;
> +	struct Scsi_Host *shost = hctx->driver_data;
>   
>   	if (shost->hostt->mq_poll)
>   		return shost->hostt->mq_poll(shost, hctx->queue_num);
> @@ -1802,6 +1800,15 @@ static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx)
>   	return 0;
>   }
>   
> +static int scsi_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
> +			  unsigned int hctx_idx)
> +{
> +	struct Scsi_Host *shost = data;
> +
> +	hctx->driver_data = shost;
> +	return 0;
> +}
> +
>   static int scsi_map_queues(struct blk_mq_tag_set *set)
>   {
>   	struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set);
> @@ -1869,15 +1876,14 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = {
>   	.cleanup_rq	= scsi_cleanup_rq,
>   	.busy		= scsi_mq_lld_busy,
>   	.map_queues	= scsi_map_queues,
> +	.init_hctx	= scsi_init_hctx,
>   	.poll		= scsi_mq_poll,
>   };
>   
>   
>   static void scsi_commit_rqs(struct blk_mq_hw_ctx *hctx)
>   {
> -	struct request_queue *q = hctx->queue;
> -	struct scsi_device *sdev = q->queuedata;
> -	struct Scsi_Host *shost = sdev->host;
> +	struct Scsi_Host *shost = hctx->driver_data;
>   
>   	shost->hostt->commit_rqs(shost, hctx->queue_num);
>   }
> @@ -1898,6 +1904,7 @@ static const struct blk_mq_ops scsi_mq_ops = {
>   	.cleanup_rq	= scsi_cleanup_rq,
>   	.busy		= scsi_mq_lld_busy,
>   	.map_queues	= scsi_map_queues,
> +	.init_hctx	= scsi_init_hctx,
>   	.poll		= scsi_mq_poll,
>   };
>   
> 
Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare@suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-03-01  7:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-01  5:16 [PATCH v3 0/4] io_uring iopoll in scsi layer Kashyap Desai
2021-02-01  5:16 ` [PATCH v3 1/4] add io_uring with IOPOLL support " Kashyap Desai
2021-02-01  5:16 ` [PATCH v3 2/4] megaraid_sas: iouring iopoll support Kashyap Desai
2021-02-01 15:06   ` Hannes Reinecke
2021-02-02 11:30     ` Kashyap Desai
2021-02-01  5:16 ` [PATCH v3 3/4] scsi_debug : " Kashyap Desai
2021-02-01  5:16   ` Kashyap Desai
2021-02-01  5:16 ` [PATCH v3 4/4] scsi: set shost as hctx driver_data Kashyap Desai
2021-03-01  7:30   ` Hannes Reinecke
2021-02-01 20:57 ` [PATCH v3 0/4] io_uring iopoll in scsi layer Douglas Gilbert
2021-02-02 10:32   ` Kashyap Desai
2021-02-02 18:54     ` Douglas Gilbert

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.