summaryrefslogtreecommitdiff |
diff options
author | Jeff Mahoney <jeffm@suse.com> | 2014-09-17 08:06:06 -0400 |
---|---|---|
committer | Jeff Mahoney <jeffm@suse.com> | 2014-09-17 08:06:06 -0400 |
commit | 5fca623fef82770d0a6895d3fb6382ac069cb1a6 (patch) | |
tree | 242f003b854d0e0bcb10ede6e59f9a71b6801329 | |
parent | dcee3975936b33996dd656617da8e1879ef4dcbd (diff) |
blk-merge: fix blk_recount_segments (bnc#888259).
-rw-r--r-- | patches.fixes/blk-merge-fix-blk_recount_segments | 84 | ||||
-rw-r--r-- | series.conf | 2 |
2 files changed, 86 insertions, 0 deletions
diff --git a/patches.fixes/blk-merge-fix-blk_recount_segments b/patches.fixes/blk-merge-fix-blk_recount_segments new file mode 100644 index 0000000000..a4e3a958c7 --- /dev/null +++ b/patches.fixes/blk-merge-fix-blk_recount_segments @@ -0,0 +1,84 @@ +From 0738854939e6ec9b9111a8cfc0ca1dfa3cff6b2e Mon Sep 17 00:00:00 2001 +From: Ming Lei <ming.lei@canonical.com> +Date: Tue, 2 Sep 2014 23:02:59 +0800 +Subject: blk-merge: fix blk_recount_segments +Git-commit: 0738854939e6ec9b9111a8cfc0ca1dfa3cff6b2e +Patch-mainline: v3.17-rc5 +References: bnc#888259 + +QUEUE_FLAG_NO_SG_MERGE is set at default for blk-mq devices, +so bio->bi_phys_segment computed may be bigger than +queue_max_segments(q) for blk-mq devices, then drivers will +fail to handle the case, for example, BUG_ON() in +virtio_queue_rq() can be triggerd for virtio-blk: + + https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1359146 + +This patch fixes the issue by ignoring the QUEUE_FLAG_NO_SG_MERGE +flag if the computed bio->bi_phys_segment is bigger than +queue_max_segments(q), and the regression is caused by commit +05f1dd53152173(block: add queue flag for disabling SG merging). + +Reported-by: Kick In <pierre-andre.morey@canonical.com> +Tested-by: Chris J Arges <chris.j.arges@canonical.com> +Signed-off-by: Ming Lei <ming.lei@canonical.com> +Signed-off-by: Jens Axboe <axboe@fb.com> +Acked-by: Jeff Mahoney <jeffm@suse.com> +--- + block/blk-merge.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/block/blk-merge.c b/block/blk-merge.c +index 5453583..7788179 100644 +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -10,10 +10,11 @@ + #include "blk.h" + + static unsigned int __blk_recalc_rq_segments(struct request_queue *q, +- struct bio *bio) ++ struct bio *bio, ++ bool no_sg_merge) + { + struct bio_vec bv, bvprv = { NULL }; +- int cluster, high, highprv = 1, no_sg_merge; ++ int cluster, high, highprv = 1; + unsigned int seg_size, nr_phys_segs; + struct bio *fbio, *bbio; + struct bvec_iter iter; +@@ -35,7 +36,6 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, + cluster = blk_queue_cluster(q); + seg_size = 0; + nr_phys_segs = 0; +- no_sg_merge = test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); + high = 0; + for_each_bio(bio) { + bio_for_each_segment(bv, bio, iter) { +@@ -88,18 +88,23 @@ new_segment: + + void blk_recalc_rq_segments(struct request *rq) + { +- rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio); ++ bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, ++ &rq->q->queue_flags); ++ ++ rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio, ++ no_sg_merge); + } + + void blk_recount_segments(struct request_queue *q, struct bio *bio) + { +- if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags)) ++ if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && ++ bio->bi_vcnt < queue_max_segments(q)) + bio->bi_phys_segments = bio->bi_vcnt; + else { + struct bio *nxt = bio->bi_next; + + bio->bi_next = NULL; +- bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio); ++ bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); + bio->bi_next = nxt; + } + + diff --git a/series.conf b/series.conf index 8b5204b407..2cf5e95ab7 100644 --- a/series.conf +++ b/series.conf @@ -361,6 +361,8 @@ patches.fixes/scsi-ibmvscsi-module_alias.patch patches.suse/sd_init.mark_majors_busy.patch + patches.fixes/blk-merge-fix-blk_recount_segments + ######################################################## # DRM/Video ######################################################## |