All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bart Van Assche <bart.vanassche@sandisk.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: Sagi Grimberg <sagig@dev.mellanox.co.il>,
	Doug Ledford <dledford@redhat.com>,
	James Bottomley <jbottomley@odin.com>,
	Sagi Grimberg <sagig@mellanox.com>,
	Sebastian Parschauer <sebastian.riemer@profitbricks.com>,
	Jens Axboe <axboe@fb.com>,
	"linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>
Subject: Re: [PATCH 01/12] scsi_transport_srp: Introduce srp_wait_for_queuecommand()
Date: Wed, 6 May 2015 11:59:28 +0200	[thread overview]
Message-ID: <5549E600.9050208@sandisk.com> (raw)
In-Reply-To: <20150430172516.GA19200@infradead.org>

On 04/30/15 19:25, Christoph Hellwig wrote:
> On Thu, Apr 30, 2015 at 12:58:50PM +0200, Bart Van Assche wrote:
>> The only callers in upstream code of scsi_target_block() and
>> scsi_target_unblock() I am aware of are the FC, iSCSI and SRP transport
>> layers and the drivers that use these transport layers. As far as I can see
>> both functions are always called from thread context and without holding any
>> spinlocks. A possible alternative to what I proposed in my previous e-mail
>> could be to provide a new function that waits for active queuecommand()
>> calls and that has to be called explicitly.
> 
> A separate helper sounds fine for now, although I suspect we'll
> eventually migrate the call to it into scsi_target_block().

(+Jens)

How about the patch below (lightly tested so far) ?

[PATCH] Introduce scsi_wait_for_queuecommand()

Move the functionality for waiting until active queuecommand()
calls have finished from the SRP transport layer into the SCSI
core. Add support for blk-mq in scsi_wait_for_queuecommand().
Introduce a request_fn_active counter in struct blk_mq_hw_ctx
to make it possible to implement this functionality for blk-mq.
---
 block/blk-mq.c                    | 19 ++++++++--------
 drivers/scsi/scsi_lib.c           | 48 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/scsi_transport_srp.c | 24 +-------------------
 include/linux/blk-mq.h            |  1 +
 include/scsi/scsi_device.h        |  1 +
 5 files changed, 60 insertions(+), 33 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index ade8a2d..d0063e4 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -786,12 +786,11 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
 	 * If we have previous entries on our dispatch list, grab them
 	 * and stuff them at the front for more fair dispatch.
 	 */
-	if (!list_empty_careful(&hctx->dispatch)) {
-		spin_lock(&hctx->lock);
-		if (!list_empty(&hctx->dispatch))
-			list_splice_init(&hctx->dispatch, &rq_list);
-		spin_unlock(&hctx->lock);
-	}
+	spin_lock(&hctx->lock);
+	hctx->request_fn_active++;
+	if (!list_empty(&hctx->dispatch))
+		list_splice_init(&hctx->dispatch, &rq_list);
+	spin_unlock(&hctx->lock);
 
 	/*
 	 * Start off with dptr being NULL, so we start the first request
@@ -851,11 +850,11 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
 	 * Any items that need requeuing? Stuff them into hctx->dispatch,
 	 * that is where we will continue on next queue run.
 	 */
-	if (!list_empty(&rq_list)) {
-		spin_lock(&hctx->lock);
+	spin_lock(&hctx->lock);
+	if (!list_empty(&rq_list))
 		list_splice(&rq_list, &hctx->dispatch);
-		spin_unlock(&hctx->lock);
-	}
+	hctx->request_fn_active--;
+	spin_unlock(&hctx->lock);
 }
 
 /*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index b1a2631..1466ef2 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -3073,6 +3073,54 @@ scsi_target_unblock(struct device *dev, enum scsi_device_state new_state)
 EXPORT_SYMBOL_GPL(scsi_target_unblock);
 
 /**
+ * scsi_request_fn_active() - number of ongoing scsi_request_fn() calls.
+ * @shost: SCSI host.
+ */
+static int scsi_request_fn_active(struct Scsi_Host *shost)
+{
+	struct scsi_device *sdev;
+	struct request_queue *q;
+	struct blk_mq_hw_ctx *hctx;
+	unsigned int i;
+	int request_fn_active = 0;
+
+	shost_for_each_device(sdev, shost) {
+		q = sdev->request_queue;
+
+		if (q->mq_ops) {
+			queue_for_each_hw_ctx(q, hctx, i) {
+				spin_lock(&hctx->lock);
+				request_fn_active += q->request_fn_active;
+				spin_unlock(&hctx->lock);
+			}
+		} else {
+			spin_lock_irq(q->queue_lock);
+			request_fn_active += q->request_fn_active;
+			spin_unlock_irq(q->queue_lock);
+		}
+	}
+
+	return request_fn_active;
+}
+
+/**
+ * scsi_wait_for_queuecommand() - wait until queuecommand() calls have finished
+ * @shost: SCSI host.
+ *
+ * Although functions like scsi_target_block() and scsi_target_unblock(shost,
+ * SDEV_TRANSPORT_OFFLINE) prevent new calls to the queuecommand() callback
+ * function these functions do not wait until ongoing queucommand() calls have
+ * finished. Hence this function that waits until any ongoing queucommand()
+ * calls have finished.
+ */
+void scsi_wait_for_queuecommand(struct Scsi_Host *shost)
+{
+	while (scsi_request_fn_active(shost))
+		msleep(20);
+}
+EXPORT_SYMBOL(scsi_wait_for_queuecommand);
+
+/**
  * scsi_kmap_atomic_sg - find and atomically map an sg-elemnt
  * @sgl:	scatter-gather list
  * @sg_count:	number of segments in sg
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index ae45bd9..aaf4581 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -504,27 +504,6 @@ void srp_start_tl_fail_timers(struct srp_rport *rport)
 EXPORT_SYMBOL(srp_start_tl_fail_timers);
 
 /**
- * scsi_request_fn_active() - number of kernel threads inside scsi_request_fn()
- * @shost: SCSI host for which to count the number of scsi_request_fn() callers.
- */
-static int scsi_request_fn_active(struct Scsi_Host *shost)
-{
-	struct scsi_device *sdev;
-	struct request_queue *q;
-	int request_fn_active = 0;
-
-	shost_for_each_device(sdev, shost) {
-		q = sdev->request_queue;
-
-		spin_lock_irq(q->queue_lock);
-		request_fn_active += q->request_fn_active;
-		spin_unlock_irq(q->queue_lock);
-	}
-
-	return request_fn_active;
-}
-
-/**
  * srp_reconnect_rport() - reconnect to an SRP target port
  * @rport: SRP target port.
  *
@@ -559,8 +538,7 @@ int srp_reconnect_rport(struct srp_rport *rport)
 	if (res)
 		goto out;
 	scsi_target_block(&shost->shost_gendev);
-	while (scsi_request_fn_active(shost))
-		msleep(20);
+	scsi_wait_for_queuecommand(shost);
 	res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV;
 	pr_debug("%s (state %d): transport.reconnect() returned %d\n",
 		 dev_name(&shost->shost_gendev), rport->state, res);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 2056a99..732b746 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -22,6 +22,7 @@ struct blk_mq_hw_ctx {
 	struct {
 		spinlock_t		lock;
 		struct list_head	dispatch;
+		int			request_fn_active;
 	} ____cacheline_aligned_in_smp;
 
 	unsigned long		state;		/* BLK_MQ_S_* flags */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index a4c9336..5540d02 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -412,6 +412,7 @@ extern void scsi_scan_target(struct device *parent, unsigned int channel,
 extern void scsi_target_reap(struct scsi_target *);
 extern void scsi_target_block(struct device *);
 extern void scsi_target_unblock(struct device *, enum scsi_device_state);
+extern void scsi_wait_for_queuecommand(struct Scsi_Host *shost);
 extern void scsi_remove_target(struct device *);
 extern void int_to_scsilun(u64, struct scsi_lun *);
 extern u64 scsilun_to_int(struct scsi_lun *);
-- 
2.1.4




  reply	other threads:[~2015-05-06  9:59 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-30  8:56 [PATCH 0/12] IB/srp patches for kernel v4.2 Bart Van Assche
2015-04-30  8:56 ` [PATCH 01/12] scsi_transport_srp: Introduce srp_wait_for_queuecommand() Bart Van Assche
     [not found]   ` <5541EE4A.30803-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30  9:32     ` Sagi Grimberg
2015-04-30  9:37     ` Christoph Hellwig
2015-04-30 10:26       ` Bart Van Assche
2015-04-30 10:32         ` Sagi Grimberg
2015-04-30 10:58           ` Bart Van Assche
     [not found]             ` <55420AEA.10108-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 14:13               ` Sagi Grimberg
2015-04-30 17:25               ` Christoph Hellwig
2015-05-06  9:59                 ` Bart Van Assche [this message]
2015-05-11  7:50                   ` hosts resets in SRP and the rest of the world, was: " Christoph Hellwig
2015-05-11  8:54                     ` Bart Van Assche
2015-05-11  9:31                       ` Christoph Hellwig
2015-05-11  9:58                         ` Bart Van Assche
2015-05-11 11:47                           ` Christoph Hellwig
2015-05-11 10:58                         ` Bart Van Assche
2015-05-11 11:50                           ` Christoph Hellwig
2015-05-12  8:49                             ` Bart Van Assche
2015-05-12 18:02                               ` Christoph Hellwig
2015-04-30  8:57 ` [PATCH 02/12] scsi_transport_srp: Fix a race condition Bart Van Assche
     [not found]   ` <5541EE66.7090608-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30  9:44     ` Sagi Grimberg
     [not found]       ` <5541F96F.8090503-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-04-30 10:20         ` Bart Van Assche
2015-04-30  8:58 ` [PATCH 04/12] IB/srp: Fix connection state tracking Bart Van Assche
2015-04-30  9:51   ` Sagi Grimberg
2015-04-30 11:25     ` Bart Van Assche
     [not found]       ` <5542111E.1080305-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 15:00         ` Sagi Grimberg
     [not found]           ` <5542439D.1000107-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-05-05  9:31             ` Bart Van Assche
     [not found]               ` <55488E06.8040308-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-05-05  9:45                 ` Sagi Grimberg
     [not found]                   ` <5548911F.8060505-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-05-05  9:59                     ` Bart Van Assche
2015-04-30 16:08   ` Doug Ledford
     [not found]     ` <1430410094.102408.71.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-05-05  9:21       ` Bart Van Assche
     [not found]         ` <55488BAE.7070006-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-05-05 14:10           ` Doug Ledford
2015-05-05 14:26             ` Bart Van Assche
2015-05-05 15:10               ` Doug Ledford
2015-05-05 15:27                 ` Bart Van Assche
     [not found]                   ` <5548E155.70007-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-05-05 16:10                     ` Doug Ledford
     [not found]                       ` <1430842201.2407.226.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-05-06  9:29                         ` Bart Van Assche
     [not found]                           ` <5549DEEC.9050501-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-05-07 13:44                             ` Doug Ledford
2015-04-30  8:58 ` [PATCH 05/12] IB/srp: Fix reconnection failure handling Bart Van Assche
2015-04-30  8:59 ` [PATCH 06/12] scsi_transport_srp: Reduce failover time Bart Van Assche
2015-04-30 10:13   ` Sagi Grimberg
2015-04-30 11:02     ` Bart Van Assche
     [not found]       ` <55420BAA.7060507-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 15:14         ` Sagi Grimberg
     [not found]           ` <554246E6.9020503-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2015-05-05  9:38             ` Bart Van Assche
2015-04-30  9:00 ` [PATCH 07/12] IB/srp: Remove superfluous casts Bart Van Assche
2015-04-30 10:13   ` Sagi Grimberg
2015-04-30  9:00 ` [PATCH 08/12] IB/srp: Rearrange module description Bart Van Assche
     [not found]   ` <5541EF39.6040301-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 10:15     ` Sagi Grimberg
2015-04-30  9:01 ` [PATCH 09/12] IB/srp: Remove a superfluous check from srp_free_req_data() Bart Van Assche
     [not found]   ` <5541EF4F.6050200-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 10:18     ` Sagi Grimberg
2015-04-30 10:37       ` Bart Van Assche
2015-04-30  9:01 ` [PATCH 10/12] IB/srp: Remove !ch->target tests from the reconnect code Bart Van Assche
2015-04-30 10:19   ` Sagi Grimberg
     [not found] ` <5541EE21.3050809-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30  8:57   ` [PATCH 03/12] IB/srp: Remove an extraneous scsi_host_put() from an error path Bart Van Assche
2015-04-30  9:44     ` Sagi Grimberg
2015-04-30  9:02   ` [PATCH 11/12] IB/srp: Add 64-bit LUN support Bart Van Assche
2015-04-30  9:02   ` [PATCH 12/12] IB/srp: Make CM timeout dependent on subnet timeout Bart Van Assche
     [not found]     ` <5541EFB3.6030704-XdAiOPVOjttBDgjK7y7TUQ@public.gmane.org>
2015-04-30 10:27       ` Sagi Grimberg
2015-04-30 10:45         ` 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=5549E600.9050208@sandisk.com \
    --to=bart.vanassche@sandisk.com \
    --cc=axboe@fb.com \
    --cc=dledford@redhat.com \
    --cc=hch@infradead.org \
    --cc=jbottomley@odin.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sagig@dev.mellanox.co.il \
    --cc=sagig@mellanox.com \
    --cc=sebastian.riemer@profitbricks.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.