diff mbox series

[2/2] blk-mq: provide a helper to check if a queue is busy

Message ID 20181108154216.23853-3-axboe@kernel.dk (mailing list archive)
State New, archived
Headers show
Series Add queue_is_busy helper | expand

Commit Message

Jens Axboe Nov. 8, 2018, 3:42 p.m. UTC
Returns true if the queue currently has requests pending,
false if not.

DM can use this to replace the atomic_inc/dec they do per device
to see if a device is busy.

Cc: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 block/blk-mq.c         | 22 ++++++++++++++++++++++
 include/linux/blk-mq.h |  2 ++
 2 files changed, 24 insertions(+)

Comments

Mike Snitzer Nov. 8, 2018, 3:49 p.m. UTC | #1
On Thu, Nov 08 2018 at 10:42am -0500,
Jens Axboe <axboe@kernel.dk> wrote:

> Returns true if the queue currently has requests pending,
> false if not.
> 
> DM can use this to replace the atomic_inc/dec they do per device
> to see if a device is busy.
> 
> Cc: Mike Snitzer <snitzer@redhat.com>
> Signed-off-by: Jens Axboe <axboe@kernel.dk>

Reviewed-by: Mike Snitzer <snitzer@redhat.com>
Laurence Oberman Nov. 8, 2018, 3:54 p.m. UTC | #2
On Thu, 2018-11-08 at 08:42 -0700, Jens Axboe wrote:
> +static bool blk_mq_check_busy(struct blk_mq_hw_ctx *hctx, struct
> request *rq,
> +                             void *priv, bool reserved)
> +{
> +       bool *busy = (bool *) priv;
> +
> +       /*
> +        * If we find a request, we know the queue is busy. Return
> false
> +        * to stop the iteration.
> +        */
> +       *busy = true;
> +       return false;
> +}
> +

Hi Jens,

Trying to understand the logic, likely just my lack of knowledge
You return false after setting true because you say we know the queue
is busy.
How do we know we found a request here
I dont see you check the result of 
 bool *busy = (bool *) priv;
Is the assumption here because this was called we already knew we had a
request

Apologies it its just my lack of understanding

+static bool blk_mq_check_busy(struct blk_mq_hw_ctx *hctx, struct
request *rq,
+                             void *priv, bool reserved)
+{
+       bool *busy = (bool *) priv;
+
+       /*
+        * If we find a request, we know the queue is busy. Return
false
+        * to stop the iteration.
+        */
+       *busy = true;
+       return false;
+}
+
Jens Axboe Nov. 8, 2018, 3:58 p.m. UTC | #3
On 11/8/18 8:54 AM, Laurence Oberman wrote:
> On Thu, 2018-11-08 at 08:42 -0700, Jens Axboe wrote:
>> +static bool blk_mq_check_busy(struct blk_mq_hw_ctx *hctx, struct
>> request *rq,
>> +                             void *priv, bool reserved)
>> +{
>> +       bool *busy = (bool *) priv;
>> +
>> +       /*
>> +        * If we find a request, we know the queue is busy. Return
>> false
>> +        * to stop the iteration.
>> +        */
>> +       *busy = true;
>> +       return false;
>> +}
>> +
> 
> Hi Jens,
> 
> Trying to understand the logic, likely just my lack of knowledge
> You return false after setting true because you say we know the queue
> is busy.
> How do we know we found a request here
> I dont see you check the result of 
>  bool *busy = (bool *) priv;
> Is the assumption here because this was called we already knew we had a
> request

Yes, that's absolutely right - if we get into the helper, we know we
already have a request. Hence we know the queue is busy. Actually
thinking about it, for shared tags, we need to check if the request
is for the given queue. Will send a v2...
diff mbox series

Patch

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 4a622c832b31..848adcc51c43 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -790,6 +790,28 @@  struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag)
 }
 EXPORT_SYMBOL(blk_mq_tag_to_rq);
 
+static bool blk_mq_check_busy(struct blk_mq_hw_ctx *hctx, struct request *rq,
+			      void *priv, bool reserved)
+{
+	bool *busy = (bool *) priv;
+
+	/*
+	 * If we find a request, we know the queue is busy. Return false
+	 * to stop the iteration.
+	 */
+	*busy = true;
+	return false;
+}
+
+bool blk_mq_queue_busy(struct request_queue *q)
+{
+	bool busy = false;
+
+	blk_mq_queue_tag_busy_iter(q, blk_mq_check_busy, &busy);
+	return busy;
+}
+EXPORT_SYMBOL_GPL(blk_mq_queue_busy);
+
 static void blk_mq_rq_timed_out(struct request *req, bool reserved)
 {
 	req->rq_flags |= RQF_TIMED_OUT;
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index ff497dfcbbf9..929e8abc5535 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -250,6 +250,8 @@  void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule);
 void blk_mq_free_request(struct request *rq);
 bool blk_mq_can_queue(struct blk_mq_hw_ctx *);
 
+bool blk_mq_queue_busy(struct request_queue *q);
+
 enum {
 	/* return when out of requests */
 	BLK_MQ_REQ_NOWAIT	= (__force blk_mq_req_flags_t)(1 << 0),