Home Home > GIT Browse > SLE15-SP1-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2014-09-17 08:06:06 -0400
committerJeff Mahoney <jeffm@suse.com>2014-09-17 08:06:06 -0400
commit5fca623fef82770d0a6895d3fb6382ac069cb1a6 (patch)
tree242f003b854d0e0bcb10ede6e59f9a71b6801329
parentdcee3975936b33996dd656617da8e1879ef4dcbd (diff)
blk-merge: fix blk_recount_segments (bnc#888259).
-rw-r--r--patches.fixes/blk-merge-fix-blk_recount_segments84
-rw-r--r--series.conf2
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
########################################################