scsi: core: Support setting BLK_MQ_F_BLOCKING
authorBart Van Assche <bvanassche@acm.org>
Mon, 29 May 2023 20:26:37 +0000 (13:26 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 31 May 2023 15:42:46 +0000 (11:42 -0400)
Prepare for adding code in ufshcd_queuecommand() that may sleep. This patch
is similar to a patch posted last year by Mike Christie. See also
https://lore.kernel.org/all/20220308003957.123312-2-michael.christie@oracle.com/

Cc: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20230529202640.11883-3-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hosts.c
drivers/scsi/scsi_lib.c
include/scsi/scsi_host.h

index f0bc8bb..198edf0 100644 (file)
@@ -441,6 +441,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
        shost->cmd_per_lun = sht->cmd_per_lun;
        shost->no_write_same = sht->no_write_same;
        shost->host_tagset = sht->host_tagset;
+       shost->queuecommand_may_block = sht->queuecommand_may_block;
 
        if (shost_eh_deadline == -1 || !sht->eh_host_reset_handler)
                shost->eh_deadline = -1;
index 758a576..c7588c4 100644 (file)
@@ -1982,6 +1982,8 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
        tag_set->flags = BLK_MQ_F_SHOULD_MERGE;
        tag_set->flags |=
                BLK_ALLOC_POLICY_TO_MQ_FLAG(shost->hostt->tag_alloc_policy);
+       if (shost->queuecommand_may_block)
+               tag_set->flags |= BLK_MQ_F_BLOCKING;
        tag_set->driver_data = shost;
        if (shost->host_tagset)
                tag_set->flags |= BLK_MQ_F_TAG_HCTX_SHARED;
@@ -2968,13 +2970,8 @@ scsi_host_block(struct Scsi_Host *shost)
                }
        }
 
-       /*
-        * SCSI never enables blk-mq's BLK_MQ_F_BLOCKING flag so
-        * calling synchronize_rcu() once is enough.
-        */
-       WARN_ON_ONCE(shost->tag_set.flags & BLK_MQ_F_BLOCKING);
-
-       synchronize_rcu();
+       /* Wait for ongoing scsi_queue_rq() calls to finish. */
+       blk_mq_wait_quiesce_done(&shost->tag_set);
 
        return 0;
 }
index 0f29799..70b7475 100644 (file)
@@ -458,6 +458,9 @@ struct scsi_host_template {
        /* True if the host uses host-wide tagspace */
        unsigned host_tagset:1;
 
+       /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */
+       unsigned queuecommand_may_block:1;
+
        /*
         * Countdown for host blocking with no commands outstanding.
         */
@@ -653,6 +656,9 @@ struct Scsi_Host {
        /* True if the host uses host-wide tagspace */
        unsigned host_tagset:1;
 
+       /* The queuecommand callback may block. See also BLK_MQ_F_BLOCKING. */
+       unsigned queuecommand_may_block:1;
+
        /* Host responded with short (<36 bytes) INQUIRY result */
        unsigned short_inquiry:1;