Message ID | 20170403232228.11208-5-bart.vanassche@sandisk.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> +static void scsi_restart_hctx(struct request_queue *q, > + struct blk_mq_hw_ctx *hctx) > +{ > + struct blk_mq_tags *tags = hctx->tags; > + struct blk_mq_tag_set *set = q->tag_set; > + int i; > + > + rcu_read_lock(); > + list_for_each_entry_rcu(q, &set->tag_list, tag_set_list) > + queue_for_each_hw_ctx(q, hctx, i) > + if (hctx->tags == tags) > + blk_mq_sched_restart_hctx(hctx); > + rcu_read_unlock(); > +} This looks like generic block layer code, why is it in SCSI?
On 04/03/2017 11:42 PM, Christoph Hellwig wrote: >> +static void scsi_restart_hctx(struct request_queue *q, >> + struct blk_mq_hw_ctx *hctx) >> +{ >> + struct blk_mq_tags *tags = hctx->tags; >> + struct blk_mq_tag_set *set = q->tag_set; >> + int i; >> + >> + rcu_read_lock(); >> + list_for_each_entry_rcu(q, &set->tag_list, tag_set_list) >> + queue_for_each_hw_ctx(q, hctx, i) >> + if (hctx->tags == tags) >> + blk_mq_sched_restart_hctx(hctx); >> + rcu_read_unlock(); >> +} > > This looks like generic block layer code, why is it in SCSI? Hello Christoph, That's an excellent question. I assume that you are fine with moving this code to the block layer? Bart.
On Tue, Apr 04, 2017 at 03:56:34PM +0000, Bart Van Assche wrote: > > This looks like generic block layer code, why is it in SCSI? > > Hello Christoph, > > That's an excellent question. I assume that you are fine with moving > this code to the block layer? Yes. In fact I wonder if we need the blk_mq_ops method at all now that you're using RCU locking and don't need the scsi host_lock.
On 04/04/2017 11:20 PM, Christoph Hellwig wrote: > On Tue, Apr 04, 2017 at 03:56:34PM +0000, Bart Van Assche wrote: >>> This looks like generic block layer code, why is it in SCSI? >> >> That's an excellent question. I assume that you are fine with moving >> this code to the block layer? > > Yes. In fact I wonder if we need the blk_mq_ops method at all now > that you're using RCU locking and don't need the scsi host_lock. Hello Christoph, My plan is to remove the new blk_mq_ops method again before I post v3 of this patch series. Bart.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c1519660824b..0e240aebc150 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -555,6 +555,21 @@ void scsi_run_host_queues(struct Scsi_Host *shost) scsi_run_queue(sdev->request_queue); } +static void scsi_restart_hctx(struct request_queue *q, + struct blk_mq_hw_ctx *hctx) +{ + struct blk_mq_tags *tags = hctx->tags; + struct blk_mq_tag_set *set = q->tag_set; + int i; + + rcu_read_lock(); + list_for_each_entry_rcu(q, &set->tag_list, tag_set_list) + queue_for_each_hw_ctx(q, hctx, i) + if (hctx->tags == tags) + blk_mq_sched_restart_hctx(hctx); + rcu_read_unlock(); +} + static void scsi_uninit_cmd(struct scsi_cmnd *cmd) { if (!blk_rq_is_passthrough(cmd->request)) { @@ -2156,6 +2171,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) static const struct blk_mq_ops scsi_mq_ops = { .queue_rq = scsi_queue_rq, + .restart_hctx = scsi_restart_hctx, .complete = scsi_softirq_done, .timeout = scsi_timeout, .init_request = scsi_init_request,
This patch avoids that if multiple SCSI devices are associated with a SCSI host that a queue can get stuck if scsi_queue_rq() returns "busy". Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.com> --- drivers/scsi/scsi_lib.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)