add follow-up fix for NVME driver
fixes a BUG_ON triggered by Samsung SM960 Pro NVME devices
This commit is contained in:
parent
1e9f438872
commit
c1fc04f4d1
96
0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch
Normal file
96
0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
From 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Lei <ming.lei@redhat.com>
|
||||||
|
Date: Fri, 14 Apr 2017 13:58:29 -0600
|
||||||
|
Subject: [PATCH] block: fix bio_will_gap() for first bvec with offset
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Commit 729204ef49ec("block: relax check on sg gap") allows us to merge
|
||||||
|
bios, if both are physically contiguous. This change can merge a huge
|
||||||
|
number of small bios, through mkfs for example, mkfs.ntfs running time
|
||||||
|
can be decreased to ~1/10.
|
||||||
|
|
||||||
|
But if one rq starts with a non-aligned buffer (the 1st bvec's bv_offset
|
||||||
|
is non-zero) and if we allow the merge, it is quite difficult to respect
|
||||||
|
sg gap limit, especially the max segment size, or we risk having an
|
||||||
|
unaligned virtual boundary. This patch tries to avoid the issue by
|
||||||
|
disallowing a merge, if the req starts with an unaligned buffer.
|
||||||
|
|
||||||
|
Also add comments to explain why the merged segment can't end in
|
||||||
|
unaligned virt boundary.
|
||||||
|
|
||||||
|
Fixes: 729204ef49ec ("block: relax check on sg gap")
|
||||||
|
Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
|
||||||
|
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
|
||||||
|
Signed-off-by: Ming Lei <ming.lei@redhat.com>
|
||||||
|
|
||||||
|
Rewrote parts of the commit message and comments.
|
||||||
|
|
||||||
|
Signed-off-by: Jens Axboe <axboe@fb.com>
|
||||||
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
||||||
|
---
|
||||||
|
include/linux/blkdev.h | 32 ++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 28 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
|
||||||
|
index 7548f332121a..01a696b0a4d3 100644
|
||||||
|
--- a/include/linux/blkdev.h
|
||||||
|
+++ b/include/linux/blkdev.h
|
||||||
|
@@ -1672,12 +1672,36 @@ static inline bool bios_segs_mergeable(struct request_queue *q,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
||||||
|
- struct bio *next)
|
||||||
|
+static inline bool bio_will_gap(struct request_queue *q,
|
||||||
|
+ struct request *prev_rq,
|
||||||
|
+ struct bio *prev,
|
||||||
|
+ struct bio *next)
|
||||||
|
{
|
||||||
|
if (bio_has_data(prev) && queue_virt_boundary(q)) {
|
||||||
|
struct bio_vec pb, nb;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * don't merge if the 1st bio starts with non-zero
|
||||||
|
+ * offset, otherwise it is quite difficult to respect
|
||||||
|
+ * sg gap limit. We work hard to merge a huge number of small
|
||||||
|
+ * single bios in case of mkfs.
|
||||||
|
+ */
|
||||||
|
+ if (prev_rq)
|
||||||
|
+ bio_get_first_bvec(prev_rq->bio, &pb);
|
||||||
|
+ else
|
||||||
|
+ bio_get_first_bvec(prev, &pb);
|
||||||
|
+ if (pb.bv_offset)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We don't need to worry about the situation that the
|
||||||
|
+ * merged segment ends in unaligned virt boundary:
|
||||||
|
+ *
|
||||||
|
+ * - if 'pb' ends aligned, the merged segment ends aligned
|
||||||
|
+ * - if 'pb' ends unaligned, the next bio must include
|
||||||
|
+ * one single bvec of 'nb', otherwise the 'nb' can't
|
||||||
|
+ * merge with 'pb'
|
||||||
|
+ */
|
||||||
|
bio_get_last_bvec(prev, &pb);
|
||||||
|
bio_get_first_bvec(next, &nb);
|
||||||
|
|
||||||
|
@@ -1690,12 +1714,12 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
||||||
|
|
||||||
|
static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
|
||||||
|
{
|
||||||
|
- return bio_will_gap(req->q, req->biotail, bio);
|
||||||
|
+ return bio_will_gap(req->q, req, req->biotail, bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool req_gap_front_merge(struct request *req, struct bio *bio)
|
||||||
|
{
|
||||||
|
- return bio_will_gap(req->q, bio, req->bio);
|
||||||
|
+ return bio_will_gap(req->q, NULL, bio, req->bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
int kblockd_schedule_work(struct work_struct *work);
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
1
Makefile
1
Makefile
@ -250,6 +250,7 @@ ${KERNEL_SRC}/README: ${KERNEL_SRC_SUBMODULE} | submodules
|
|||||||
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
|
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-1000365-fs-exec.c-account-for-argv-envp-pointers.patch
|
||||||
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
|
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-10810-drm-virtio-don-t-leak-bo-on-drm_gem_object_init-fail.patch
|
||||||
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
|
cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7482-rxrpc-Fix-several-cases-where-a-padded-len-isn-t-che.patch
|
||||||
|
cd ${KERNEL_SRC}; patch -p1 < ../0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch
|
||||||
sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
|
sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user