From c1fc04f4d1bb76ce1eeb03ca08f59ccbf5a7e315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Wed, 2 Aug 2017 14:48:03 +0200 Subject: [PATCH] add follow-up fix for NVME driver fixes a BUG_ON triggered by Samsung SM960 Pro NVME devices --- ..._will_gap-for-first-bvec-with-offset.patch | 96 +++++++++++++++++++ Makefile | 1 + 2 files changed, 97 insertions(+) create mode 100644 0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch diff --git a/0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch b/0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch new file mode 100644 index 0000000..aed9a58 --- /dev/null +++ b/0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch @@ -0,0 +1,96 @@ +From 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af Mon Sep 17 00:00:00 2001 +From: Ming Lei +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 +Reviewed-by: Johannes Thumshirn +Signed-off-by: Ming Lei + +Rewrote parts of the commit message and comments. + +Signed-off-by: Jens Axboe +Signed-off-by: Fabian Grünbichler +--- + 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 + diff --git a/Makefile b/Makefile index 0e744f5..6da6708 100644 --- a/Makefile +++ b/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-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 < ../0001-block-fix-bio_will_gap-for-first-bvec-with-offset.patch sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/' touch $@