diff mbox series

[V2,3/6] scsi: add flag of .use_managed_irq to 'struct Scsi_Host'

Message ID 20210702150555.2401722-4-ming.lei@redhat.com (mailing list archive)
State Changes Requested
Headers show
Series blk-mq: fix blk_mq_alloc_request_hctx | expand

Commit Message

Ming Lei July 2, 2021, 3:05 p.m. UTC
blk-mq needs this information of using managed irq for improving
deactivating hctx, so add such flag to 'struct Scsi_Host', then
drivers can pass such flag to blk-mq via scsi_mq_setup_tags().

The rule is that driver has to tell blk-mq if managed irq is used.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/scsi/scsi_lib.c  | 12 +++++++-----
 include/scsi/scsi_host.h |  3 +++
 2 files changed, 10 insertions(+), 5 deletions(-)

Comments

John Garry July 5, 2021, 9:25 a.m. UTC | #1
On 02/07/2021 16:05, Ming Lei wrote:
> blk-mq needs this information of using managed irq for improving
> deactivating hctx, so add such flag to 'struct Scsi_Host', then
> drivers can pass such flag to blk-mq via scsi_mq_setup_tags().
> 
> The rule is that driver has to tell blk-mq if managed irq is used.
> 
> Signed-off-by: Ming Lei<ming.lei@redhat.com>

As was said before, can we have something like this instead of relying 
on the LLDs to do the setting:

--------->8------------

diff --git a/block/blk-mq-pci.c b/block/blk-mq-pci.c
index b595a94c4d16..2037a5b69fe1 100644
--- a/block/blk-mq-pci.c
+++ b/block/blk-mq-pci.c
@@ -37,7 +37,7 @@ int blk_mq_pci_map_queues(struct blk_mq_queue_map 
*qmap, struct pci_dev *pdev,
  		for_each_cpu(cpu, mask)
  			qmap->mq_map[cpu] = qmap->queue_offset + queue;
  	}
-
+	qmap->drain_hwq = 1;
  	return 0;

  fallback:
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 46fe5b45a8b8..7b610e680e08 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3408,7 +3408,8 @@ static int blk_mq_update_queue_map(struct 
blk_mq_tag_set *set)
  		set->map[HCTX_TYPE_DEFAULT].nr_queues = set->nr_hw_queues;

  	if (set->ops->map_queues && !is_kdump_kernel()) {
-		int i;
+		struct blk_mq_queue_map *qmap = &set->map[HCTX_TYPE_DEFAULT];
+		int i, ret;

  		/*
  		 * transport .map_queues is usually done in the following
@@ -3427,7 +3428,12 @@ static int blk_mq_update_queue_map(struct 
blk_mq_tag_set *set)
  		for (i = 0; i < set->nr_maps; i++)
  			blk_mq_clear_mq_map(&set->map[i]);

-		return set->ops->map_queues(set);
+		ret = set->ops->map_queues(set);
+		if (ret)
+			return ret;
+		if (qmap->drain_hwq)
+			set->flags |= BLK_MQ_F_MANAGED_IRQ;
+		return 0;
  	} else {
  		BUG_ON(set->nr_maps > 1);
  		return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 65ed99b3f2f0..2b2e71ff43e0 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -193,6 +193,7 @@ struct blk_mq_queue_map {
  	unsigned int *mq_map;
  	unsigned int nr_queues;
  	unsigned int queue_offset;
+	bool drain_hwq;
  };
Ming Lei July 5, 2021, 9:55 a.m. UTC | #2
On Mon, Jul 05, 2021 at 10:25:38AM +0100, John Garry wrote:
> On 02/07/2021 16:05, Ming Lei wrote:
> > blk-mq needs this information of using managed irq for improving
> > deactivating hctx, so add such flag to 'struct Scsi_Host', then
> > drivers can pass such flag to blk-mq via scsi_mq_setup_tags().
> > 
> > The rule is that driver has to tell blk-mq if managed irq is used.
> > 
> > Signed-off-by: Ming Lei<ming.lei@redhat.com>
> 
> As was said before, can we have something like this instead of relying on
> the LLDs to do the setting:
> 
> --------->8------------
> 
> diff --git a/block/blk-mq-pci.c b/block/blk-mq-pci.c
> index b595a94c4d16..2037a5b69fe1 100644
> --- a/block/blk-mq-pci.c
> +++ b/block/blk-mq-pci.c
> @@ -37,7 +37,7 @@ int blk_mq_pci_map_queues(struct blk_mq_queue_map *qmap,
> struct pci_dev *pdev,
>  		for_each_cpu(cpu, mask)
>  			qmap->mq_map[cpu] = qmap->queue_offset + queue;
>  	}
> -
> +	qmap->drain_hwq = 1;

The thing is that blk_mq_pci_map_queues() is allowed to be called for
non-managed irqs. Also some managed irq consumers don't use blk_mq_pci_map_queues().

So this way just provides hint about managed irq uses, but we really
need to get this flag set if driver uses managed irq.


Thanks,
Ming
Christoph Hellwig July 6, 2021, 5:37 a.m. UTC | #3
On Mon, Jul 05, 2021 at 05:55:49PM +0800, Ming Lei wrote:
> The thing is that blk_mq_pci_map_queues() is allowed to be called for
> non-managed irqs. Also some managed irq consumers don't use blk_mq_pci_map_queues().
> 
> So this way just provides hint about managed irq uses, but we really
> need to get this flag set if driver uses managed irq.

blk_mq_pci_map_queues is absolutely intended to only be used by
managed irqs.  I wonder if we can enforce that somehow?
Ming Lei July 6, 2021, 7:41 a.m. UTC | #4
On Tue, Jul 06, 2021 at 07:37:19AM +0200, Christoph Hellwig wrote:
> On Mon, Jul 05, 2021 at 05:55:49PM +0800, Ming Lei wrote:
> > The thing is that blk_mq_pci_map_queues() is allowed to be called for
> > non-managed irqs. Also some managed irq consumers don't use blk_mq_pci_map_queues().
> > 
> > So this way just provides hint about managed irq uses, but we really
> > need to get this flag set if driver uses managed irq.
> 
> blk_mq_pci_map_queues is absolutely intended to only be used by
> managed irqs.  I wonder if we can enforce that somehow?

It may break some scsi drivers.

And blk_mq_pci_map_queues() just calls pci_irq_get_affinity() to
retrieve the irq's affinity, and the irq can be one non-managed irq,
which affinity is set via either irq_set_affinity_hint() from kernel
or /proc/irq/.


Thanks,
Ming
Hannes Reinecke July 6, 2021, 10:32 a.m. UTC | #5
On 7/6/21 9:41 AM, Ming Lei wrote:
> On Tue, Jul 06, 2021 at 07:37:19AM +0200, Christoph Hellwig wrote:
>> On Mon, Jul 05, 2021 at 05:55:49PM +0800, Ming Lei wrote:
>>> The thing is that blk_mq_pci_map_queues() is allowed to be called for
>>> non-managed irqs. Also some managed irq consumers don't use blk_mq_pci_map_queues().
>>>
>>> So this way just provides hint about managed irq uses, but we really
>>> need to get this flag set if driver uses managed irq.
>>
>> blk_mq_pci_map_queues is absolutely intended to only be used by
>> managed irqs.  I wonder if we can enforce that somehow?
> 
> It may break some scsi drivers.
> 
> And blk_mq_pci_map_queues() just calls pci_irq_get_affinity() to
> retrieve the irq's affinity, and the irq can be one non-managed irq,
> which affinity is set via either irq_set_affinity_hint() from kernel
> or /proc/irq/.
> 
But that's static, right? IE blk_mq_pci_map_queues() will be called once 
during module init; so what happens if the user changes the mapping 
later on? How will that be transferred to the driver?

Cheers,

Hannes
Ming Lei July 7, 2021, 10:53 a.m. UTC | #6
On Tue, Jul 06, 2021 at 12:32:27PM +0200, Hannes Reinecke wrote:
> On 7/6/21 9:41 AM, Ming Lei wrote:
> > On Tue, Jul 06, 2021 at 07:37:19AM +0200, Christoph Hellwig wrote:
> > > On Mon, Jul 05, 2021 at 05:55:49PM +0800, Ming Lei wrote:
> > > > The thing is that blk_mq_pci_map_queues() is allowed to be called for
> > > > non-managed irqs. Also some managed irq consumers don't use blk_mq_pci_map_queues().
> > > > 
> > > > So this way just provides hint about managed irq uses, but we really
> > > > need to get this flag set if driver uses managed irq.
> > > 
> > > blk_mq_pci_map_queues is absolutely intended to only be used by
> > > managed irqs.  I wonder if we can enforce that somehow?
> > 
> > It may break some scsi drivers.
> > 
> > And blk_mq_pci_map_queues() just calls pci_irq_get_affinity() to
> > retrieve the irq's affinity, and the irq can be one non-managed irq,
> > which affinity is set via either irq_set_affinity_hint() from kernel
> > or /proc/irq/.
> > 
> But that's static, right? IE blk_mq_pci_map_queues() will be called once
> during module init; so what happens if the user changes the mapping later
> on? How will that be transferred to the driver?

Yeah, that may not work well enough, but still works since non-managed
irq supports migration.

And there are several SCSI drivers which provide module parameter to
enable/disable managed irq, meantime blk_mq_pci_map_queues() is always
called for mapping queues.


Thanks,
Ming
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 532304d42f00..743df8e824b9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1915,6 +1915,8 @@  int scsi_mq_setup_tags(struct Scsi_Host *shost)
 {
 	unsigned int cmd_size, sgl_size;
 	struct blk_mq_tag_set *tag_set = &shost->tag_set;
+	unsigned long flags = BLK_MQ_F_SHOULD_MERGE |
+		BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy);
 
 	sgl_size = max_t(unsigned int, sizeof(struct scatterlist),
 				scsi_mq_inline_sgl_size(shost));
@@ -1933,12 +1935,12 @@  int scsi_mq_setup_tags(struct Scsi_Host *shost)
 	tag_set->queue_depth = shost->can_queue;
 	tag_set->cmd_size = cmd_size;
 	tag_set->numa_node = NUMA_NO_NODE;
-	tag_set->flags = BLK_MQ_F_SHOULD_MERGE;
-	tag_set->flags |=
-		BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy);
-	tag_set->driver_data = shost;
 	if (shost->host_tagset)
-		tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED;
+		flags |= BLK_MQ_F_TAG_HCTX_SHARED;
+	if (shost->use_managed_irq)
+		flags |= BLK_MQ_F_MANAGED_IRQ;
+	tag_set->flags = flags;
+	tag_set->driver_data = shost;
 
 	return blk_mq_alloc_tag_set(tag_set);
 }
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index d0bf88d77f02..3ac589ae9592 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -657,6 +657,9 @@  struct Scsi_Host {
 	/* True if the host uses host-wide tagspace */
 	unsigned host_tagset:1;
 
+	/* True if the host uses managed irq */
+	unsigned use_managed_irq:1;
+
 	/* Host responded with short (<36 bytes) INQUIRY result */
 	unsigned short_inquiry:1;