Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1251786 > unrolled thread

[PATCH v2 0/7] block: some misc changes

Started byMing Lei <ming.lei@canonical.com>
First post2015-10-20 17:20 +0200
Last post2015-10-21 23:10 +0200
Articles 10 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/7] block: some misc changes Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
    [PATCH v2 2/7] block: setup bi_phys_segments after splitting Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
    [PATCH v2 5/7] block: check bio_mergeable() early before merging Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
      Re: [PATCH v2 5/7] block: check bio_mergeable() early before merging Jeff Moyer <jmoyer@redhat.com> - 2015-10-20 17:30 +0200
    [PATCH v2 7/7] blk-mq: mark ctx as pending at batch in flush plug path Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
    [PATCH v2 6/7] blk-mq: fix for trace_block_plug() Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
      Re: [PATCH v2 6/7] blk-mq: fix for trace_block_plug() Jeff Moyer <jmoyer@redhat.com> - 2015-10-20 17:30 +0200
    [PATCH v2 1/7] block: fix plug list flushing for nomerge queues Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
    [PATCH v2 4/7] blk-mq: check bio_mergeable() early before merging Ming Lei <ming.lei@canonical.com> - 2015-10-20 17:20 +0200
    Re: [PATCH v2 0/7] block: some misc changes Jens Axboe <axboe@kernel.dk> - 2015-10-21 23:10 +0200

#1251786 — [PATCH v2 0/7] block: some misc changes

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 0/7] block: some misc changes
Message-ID<qlGRI-7xO-17@gated-at.bofh.it>
Hi,

The 1st patch is one fix for automatic flush plug in case of
nomerge queue.

The following four patches are optimizations related with bio splitting.

The 6th patch is one fix for using trace_block_plug().

The 7th patch is to mark ctx as pending at batch in flush plug path.

V2:
        - Jeff found one issue about automatic flush plug in case
		of nomerge queue, and fix it in 1/1
V1:
        - 3/6: don't check bio_mergeable() in blk_mq_attempt_merge()
        - 4/6: check bio_mergeable() for non-mq too
        - 5/6: new patch for fixing using trace_block_plug()

 block/blk-core.c  | 32 +++++++++++++++++++++++++++++---
 block/blk-merge.c | 32 +++++++++++++++++++++++++-------
 block/blk-mq.c    | 31 +++++++++++++++++++++----------
 block/blk.h       |  1 +
 block/elevator.c  |  2 +-
 5 files changed, 77 insertions(+), 21 deletions(-)

Thanks,
Ming

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1251788 — [PATCH v2 2/7] block: setup bi_phys_segments after splitting

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 2/7] block: setup bi_phys_segments after splitting
Message-ID<qlGRI-7xO-29@gated-at.bofh.it>
In reply to#1251786
The number of bio->bi_phys_segments is always obtained
during bio splitting, so it is natural to setup it
just after bio splitting, then we can avoid to compute
nr_segment again during merge.

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/blk-merge.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index c4e9c37..22293fd 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -11,13 +11,16 @@
 
 static struct bio *blk_bio_discard_split(struct request_queue *q,
 					 struct bio *bio,
-					 struct bio_set *bs)
+					 struct bio_set *bs,
+					 unsigned *nsegs)
 {
 	unsigned int max_discard_sectors, granularity;
 	int alignment;
 	sector_t tmp;
 	unsigned split_sectors;
 
+	*nsegs = 1;
+
 	/* Zero-sector (unknown) and one-sector granularities are the same.  */
 	granularity = max(q->limits.discard_granularity >> 9, 1U);
 
@@ -51,8 +54,11 @@ static struct bio *blk_bio_discard_split(struct request_queue *q,
 
 static struct bio *blk_bio_write_same_split(struct request_queue *q,
 					    struct bio *bio,
-					    struct bio_set *bs)
+					    struct bio_set *bs,
+					    unsigned *nsegs)
 {
+	*nsegs = 1;
+
 	if (!q->limits.max_write_same_sectors)
 		return NULL;
 
@@ -64,7 +70,8 @@ static struct bio *blk_bio_write_same_split(struct request_queue *q,
 
 static struct bio *blk_bio_segment_split(struct request_queue *q,
 					 struct bio *bio,
-					 struct bio_set *bs)
+					 struct bio_set *bs,
+					 unsigned *segs)
 {
 	struct bio_vec bv, bvprv, *bvprvp = NULL;
 	struct bvec_iter iter;
@@ -106,22 +113,30 @@ new_segment:
 		sectors += bv.bv_len >> 9;
 	}
 
+	*segs = nsegs;
 	return NULL;
 split:
+	*segs = nsegs;
 	return bio_split(bio, sectors, GFP_NOIO, bs);
 }
 
 void blk_queue_split(struct request_queue *q, struct bio **bio,
 		     struct bio_set *bs)
 {
-	struct bio *split;
+	struct bio *split, *res;
+	unsigned nsegs;
 
 	if ((*bio)->bi_rw & REQ_DISCARD)
-		split = blk_bio_discard_split(q, *bio, bs);
+		split = blk_bio_discard_split(q, *bio, bs, &nsegs);
 	else if ((*bio)->bi_rw & REQ_WRITE_SAME)
-		split = blk_bio_write_same_split(q, *bio, bs);
+		split = blk_bio_write_same_split(q, *bio, bs, &nsegs);
 	else
-		split = blk_bio_segment_split(q, *bio, q->bio_split);
+		split = blk_bio_segment_split(q, *bio, q->bio_split, &nsegs);
+
+	/* physical segments can be figured out during splitting */
+	res = split ? split : *bio;
+	res->bi_phys_segments = nsegs;
+	bio_set_flag(res, BIO_SEG_VALID);
 
 	if (split) {
 		bio_chain(split, *bio);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251793 — [PATCH v2 5/7] block: check bio_mergeable() early before merging

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 5/7] block: check bio_mergeable() early before merging
Message-ID<qlGRI-7xO-31@gated-at.bofh.it>
In reply to#1251786
After bio splitting is introduced, one bio can be splitted
and it is marked as NOMERGE because it is too fat to be merged,
so check bio_mergeable() earlier to avoid to try to merge it
unnecessarily.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/elevator.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/elevator.c b/block/elevator.c
index 84d6394..c3555c9 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -420,7 +420,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
 	 * 	noxmerges: Only simple one-hit cache try
 	 * 	merges:	   All merge tries attempted
 	 */
-	if (blk_queue_nomerges(q))
+	if (blk_queue_nomerges(q) || !bio_mergeable(bio))
 		return ELEVATOR_NO_MERGE;
 
 	/*
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251804 — Re: [PATCH v2 5/7] block: check bio_mergeable() early before merging

FromJeff Moyer <jmoyer@redhat.com>
Date2015-10-20 17:30 +0200
SubjectRe: [PATCH v2 5/7] block: check bio_mergeable() early before merging
Message-ID<qlH1o-7IO-17@gated-at.bofh.it>
In reply to#1251793
Ming Lei <ming.lei@canonical.com> writes:

> After bio splitting is introduced, one bio can be splitted
> and it is marked as NOMERGE because it is too fat to be merged,
> so check bio_mergeable() earlier to avoid to try to merge it
> unnecessarily.
>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>

> ---
>  block/elevator.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/elevator.c b/block/elevator.c
> index 84d6394..c3555c9 100644
> --- a/block/elevator.c
> +++ b/block/elevator.c
> @@ -420,7 +420,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
>  	 * 	noxmerges: Only simple one-hit cache try
>  	 * 	merges:	   All merge tries attempted
>  	 */
> -	if (blk_queue_nomerges(q))
> +	if (blk_queue_nomerges(q) || !bio_mergeable(bio))
>  		return ELEVATOR_NO_MERGE;
>  
>  	/*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251794 — [PATCH v2 7/7] blk-mq: mark ctx as pending at batch in flush plug path

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 7/7] blk-mq: mark ctx as pending at batch in flush plug path
Message-ID<qlGRJ-7xO-41@gated-at.bofh.it>
In reply to#1251786
Most of times, flush plug should be the hottest I/O path,
so mark ctx as pending after all requests in the list are
inserted.

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/blk-mq.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index e00b0d8..2c052c0 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -990,18 +990,25 @@ void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs)
 }
 EXPORT_SYMBOL(blk_mq_delay_queue);
 
-static void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx,
-				    struct request *rq, bool at_head)
+static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx,
+					    struct blk_mq_ctx *ctx,
+					    struct request *rq,
+					    bool at_head)
 {
-	struct blk_mq_ctx *ctx = rq->mq_ctx;
-
 	trace_block_rq_insert(hctx->queue, rq);
 
 	if (at_head)
 		list_add(&rq->queuelist, &ctx->rq_list);
 	else
 		list_add_tail(&rq->queuelist, &ctx->rq_list);
+}
+
+static void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx,
+				    struct request *rq, bool at_head)
+{
+	struct blk_mq_ctx *ctx = rq->mq_ctx;
 
+	__blk_mq_insert_req_list(hctx, ctx, rq, at_head);
 	blk_mq_hctx_mark_pending(hctx, ctx);
 }
 
@@ -1057,8 +1064,9 @@ static void blk_mq_insert_requests(struct request_queue *q,
 		rq = list_first_entry(list, struct request, queuelist);
 		list_del_init(&rq->queuelist);
 		rq->mq_ctx = ctx;
-		__blk_mq_insert_request(hctx, rq, false);
+		__blk_mq_insert_req_list(hctx, ctx, rq, false);
 	}
+	blk_mq_hctx_mark_pending(hctx, ctx);
 	spin_unlock(&ctx->lock);
 
 	blk_mq_run_hw_queue(hctx, from_schedule);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251795 — [PATCH v2 6/7] blk-mq: fix for trace_block_plug()

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 6/7] blk-mq: fix for trace_block_plug()
Message-ID<qlGRJ-7xO-49@gated-at.bofh.it>
In reply to#1251786
The trace point is for tracing plug event of each request
queue instead of each task, so we should check the request
count in the plug list from current queue instead of
current task.

Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/blk-mq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index edbc877..e00b0d8 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1380,7 +1380,7 @@ static void blk_sq_make_request(struct request_queue *q, struct bio *bio)
 	plug = current->plug;
 	if (plug) {
 		blk_mq_bio_to_request(rq, bio);
-		if (list_empty(&plug->mq_list))
+		if (!request_count)
 			trace_block_plug(q);
 		else if (request_count >= BLK_MAX_REQUEST_COUNT) {
 			blk_flush_plug_list(plug, false);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251802 — Re: [PATCH v2 6/7] blk-mq: fix for trace_block_plug()

FromJeff Moyer <jmoyer@redhat.com>
Date2015-10-20 17:30 +0200
SubjectRe: [PATCH v2 6/7] blk-mq: fix for trace_block_plug()
Message-ID<qlH1o-7IO-7@gated-at.bofh.it>
In reply to#1251795
Ming Lei <ming.lei@canonical.com> writes:

> The trace point is for tracing plug event of each request
> queue instead of each task, so we should check the request
> count in the plug list from current queue instead of
> current task.
>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>

> ---
>  block/blk-mq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index edbc877..e00b0d8 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -1380,7 +1380,7 @@ static void blk_sq_make_request(struct request_queue *q, struct bio *bio)
>  	plug = current->plug;
>  	if (plug) {
>  		blk_mq_bio_to_request(rq, bio);
> -		if (list_empty(&plug->mq_list))
> +		if (!request_count)
>  			trace_block_plug(q);
>  		else if (request_count >= BLK_MAX_REQUEST_COUNT) {
>  			blk_flush_plug_list(plug, false);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251796 — [PATCH v2 1/7] block: fix plug list flushing for nomerge queues

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 1/7] block: fix plug list flushing for nomerge queues
Message-ID<qlGRJ-7xO-45@gated-at.bofh.it>
In reply to#1251786
From: Jeff Moyer <jmoyer@redhat.com>

Request queues with merging disabled will not flush the plug list after
BLK_MAX_REQUEST_COUNT requests have been queued, since the code relies
on blk_attempt_plug_merge to compute the request_count.  Fix this by
computing the number of queued requests even for nomerge queues.

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
 block/blk-core.c | 32 +++++++++++++++++++++++++++++---
 block/blk-mq.c   |  9 ++++++---
 block/blk.h      |  1 +
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 0391206..4a45d00 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1594,6 +1594,30 @@ out:
 	return ret;
 }
 
+unsigned int blk_plug_queued_count(struct request_queue *q)
+{
+	struct blk_plug *plug;
+	struct request *rq;
+	struct list_head *plug_list;
+	unsigned int ret = 0;
+
+	plug = current->plug;
+	if (!plug)
+		goto out;
+
+	if (q->mq_ops)
+		plug_list = &plug->mq_list;
+	else
+		plug_list = &plug->list;
+
+	list_for_each_entry(rq, plug_list, queuelist) {
+		if (rq->q == q)
+			ret++;
+	}
+out:
+	return ret;
+}
+
 void init_request_from_bio(struct request *req, struct bio *bio)
 {
 	req->cmd_type = REQ_TYPE_FS;
@@ -1641,9 +1665,11 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
 	 * Check if we can merge with the plugged list before grabbing
 	 * any locks.
 	 */
-	if (!blk_queue_nomerges(q) &&
-	    blk_attempt_plug_merge(q, bio, &request_count, NULL))
-		return;
+	if (!blk_queue_nomerges(q)) {
+		if (blk_attempt_plug_merge(q, bio, &request_count, NULL))
+			return;
+	} else
+		request_count = blk_plug_queued_count(q);
 
 	spin_lock_irq(q->queue_lock);
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 546b3b8..1796b31 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1268,9 +1268,12 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio)
 
 	blk_queue_split(q, &bio, q->bio_split);
 
-	if (!is_flush_fua && !blk_queue_nomerges(q) &&
-	    blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq))
-		return;
+	if (!is_flush_fua && !blk_queue_nomerges(q)) {
+		if (blk_attempt_plug_merge(q, bio, &request_count,
+					   &same_queue_rq))
+			return;
+	} else
+		request_count = blk_plug_queued_count(q);
 
 	rq = blk_mq_map_request(q, bio, &data);
 	if (unlikely(!rq))
diff --git a/block/blk.h b/block/blk.h
index 98614ad..aa27d02 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -86,6 +86,7 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
 bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
 			    unsigned int *request_count,
 			    struct request **same_queue_rq);
+unsigned int blk_plug_queued_count(struct request_queue *q);
 
 void blk_account_io_start(struct request *req, bool new_io);
 void blk_account_io_completion(struct request *req, unsigned int bytes);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1251798 — [PATCH v2 4/7] blk-mq: check bio_mergeable() early before merging

FromMing Lei <ming.lei@canonical.com>
Date2015-10-20 17:20 +0200
Subject[PATCH v2 4/7] blk-mq: check bio_mergeable() early before merging
Message-ID<qlGRJ-7xO-53@gated-at.bofh.it>
In reply to#1251786
It isn't necessary to try to merge the bio which is marked
as NOMERGE.

Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 block/blk-mq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1796b31..edbc877 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1140,7 +1140,7 @@ static inline bool blk_mq_merge_queue_io(struct blk_mq_hw_ctx *hctx,
 					 struct blk_mq_ctx *ctx,
 					 struct request *rq, struct bio *bio)
 {
-	if (!hctx_allow_merges(hctx)) {
+	if (!hctx_allow_merges(hctx) || !bio_mergeable(bio)) {
 		blk_mq_bio_to_request(rq, bio);
 		spin_lock(&ctx->lock);
 insert_rq:
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1253249

FromJens Axboe <axboe@kernel.dk>
Date2015-10-21 23:10 +0200
Message-ID<qm8NY-6qY-5@gated-at.bofh.it>
In reply to#1251786
On 10/20/2015 09:13 AM, Ming Lei wrote:
> Hi,
>
> The 1st patch is one fix for automatic flush plug in case of
> nomerge queue.
>
> The following four patches are optimizations related with bio splitting.
>
> The 6th patch is one fix for using trace_block_plug().
>
> The 7th patch is to mark ctx as pending at batch in flush plug path.

Thanks Ming, this series looks good. Applied.

-- 
Jens Axboe

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web