From d4814ebee3d1b29404d904246ceb144fcc1e5b34 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Fri, 20 Dec 2019 10:21:41 +0800 Subject: [PATCH] EX-752 kernel: backport two patches for E2EDI From 40423bfb35bb6057bcefe93b738b5a9411e037a2 Mon Sep 17 00:00:00 2001 From: Jianchao Wang Date: Tue, 12 Feb 2019 09:56:25 +0800 blk-mq: insert rq with DONTPREP to hctx dispatch list when requeue When requeue, if RQF_DONTPREP, rq has contained some driver specific data, so insert it to hctx dispatch list to avoid any merge. Take scsi as example, here is the trace event log (no io scheduler, because RQF_STARTED would prevent merging), kworker/0:1H-339 [000] ...1 2037.209289: block_rq_insert: 8,0 R 4096 () 32768 + 8 [kworker/0:1H] scsi_inert_test-1987 [000] .... 2037.220465: block_bio_queue: 8,0 R 32776 + 8 [scsi_inert_test] scsi_inert_test-1987 [000] ...2 2037.220466: block_bio_backmerge: 8,0 R 32776 + 8 [scsi_inert_test] kworker/0:1H-339 [000] .... 2047.220913: block_rq_issue: 8,0 R 8192 () 32768 + 16 [kworker/0:1H] scsi_inert_test-1996 [000] ..s1 2047.221007: block_rq_complete: 8,0 R () 32768 + 8 [0] scsi_inert_test-1996 [000] .Ns1 2047.221045: block_rq_requeue: 8,0 R () 32776 + 8 [0] kworker/0:1H-339 [000] ...1 2047.221054: block_rq_insert: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] kworker/0:1H-339 [000] ...1 2047.221056: block_rq_issue: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] scsi_inert_test-1986 [000] ..s1 2047.221119: block_rq_complete: 8,0 R () 32776 + 8 [0] (32768 + 8) was requeued by scsi_queue_insert and had RQF_DONTPREP. Then it was merged with (32776 + 8) and issued. Due to RQF_DONTPREP, the sdb only contained the part of (32768 + 8), then only that part was completed. The lucky thing was that scsi_io_completion detected it and requeued the remaining part. So we didn't get corrupted data. However, the requeue of (32776 + 8) is not expected. Suggested-by: Jens Axboe Signed-off-by: Jianchao Wang Signed-off-by: Jens Axboe [gedwards@ddn.com: s/RQF_DONTPREP/REQ_DONTPREP/] From e0c0d06892051e17ee58e041259f339d0c194804 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 26 Sep 2014 19:20:06 -0400 block: Don't merge requests if integrity flags differ We'd occasionally merge requests with conflicting integrity flags. Introduce a merge helper which checks that the requests have compatible integrity payloads. Signed-off-by: Martin K. Petersen Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Signed-off-by: Jens Axboe [gedwards@ddn.com: only compare INTEGRITY bi_flags since we don't have bip_flags yet] Change-Id: Iece6117afa7b16c86e682e8f44b702ac79ea3609 Signed-off-by: Wang Shilong Reviewed-by: Li Dongyang Reviewed-on: https://review.whamcloud.com/41833 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- ...t-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch | 66 +++++++++ ...t-merge-requests-if-integrity-flags-rhel7.patch | 165 +++++++++++++++++++++ lustre/kernel_patches/series/3.10-rhel7.7.series | 2 + 3 files changed, 233 insertions(+) create mode 100644 lustre/kernel_patches/patches/blk-mq-insert-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch create mode 100644 lustre/kernel_patches/patches/block-Don-t-merge-requests-if-integrity-flags-rhel7.patch diff --git a/lustre/kernel_patches/patches/blk-mq-insert-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch b/lustre/kernel_patches/patches/blk-mq-insert-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch new file mode 100644 index 0000000..346ca7e --- /dev/null +++ b/lustre/kernel_patches/patches/blk-mq-insert-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch @@ -0,0 +1,66 @@ +From 40423bfb35bb6057bcefe93b738b5a9411e037a2 Mon Sep 17 00:00:00 2001 +From: Jianchao Wang +Date: Tue, 12 Feb 2019 09:56:25 +0800 +blk-mq: insert rq with DONTPREP to hctx dispatch list + when requeue + +When requeue, if RQF_DONTPREP, rq has contained some driver +specific data, so insert it to hctx dispatch list to avoid any +merge. Take scsi as example, here is the trace event log (no +io scheduler, because RQF_STARTED would prevent merging), + + kworker/0:1H-339 [000] ...1 2037.209289: block_rq_insert: 8,0 R 4096 () 32768 + 8 [kworker/0:1H] +scsi_inert_test-1987 [000] .... 2037.220465: block_bio_queue: 8,0 R 32776 + 8 [scsi_inert_test] +scsi_inert_test-1987 [000] ...2 2037.220466: block_bio_backmerge: 8,0 R 32776 + 8 [scsi_inert_test] + kworker/0:1H-339 [000] .... 2047.220913: block_rq_issue: 8,0 R 8192 () 32768 + 16 [kworker/0:1H] +scsi_inert_test-1996 [000] ..s1 2047.221007: block_rq_complete: 8,0 R () 32768 + 8 [0] +scsi_inert_test-1996 [000] .Ns1 2047.221045: block_rq_requeue: 8,0 R () 32776 + 8 [0] + kworker/0:1H-339 [000] ...1 2047.221054: block_rq_insert: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] + kworker/0:1H-339 [000] ...1 2047.221056: block_rq_issue: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] +scsi_inert_test-1986 [000] ..s1 2047.221119: block_rq_complete: 8,0 R () 32776 + 8 [0] + +(32768 + 8) was requeued by scsi_queue_insert and had RQF_DONTPREP. +Then it was merged with (32776 + 8) and issued. Due to RQF_DONTPREP, +the sdb only contained the part of (32768 + 8), then only that part +was completed. The lucky thing was that scsi_io_completion detected +it and requeued the remaining part. So we didn't get corrupted data. +However, the requeue of (32776 + 8) is not expected. + +Suggested-by: Jens Axboe +Signed-off-by: Jianchao Wang +Signed-off-by: Jens Axboe +[gedwards@ddn.com: s/RQF_DONTPREP/REQ_DONTPREP/] +--- + block/blk-mq.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index fb66815acc5a..5a8060591c9d 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -717,12 +717,20 @@ static void blk_mq_requeue_work(struct work_struct *work) + spin_unlock_irqrestore(&q->requeue_lock, flags); + + list_for_each_entry_safe(rq, next, &rq_list, queuelist) { +- if (!(rq->cmd_flags & REQ_SOFTBARRIER)) ++ if (!(rq->cmd_flags & (REQ_SOFTBARRIER | REQ_DONTPREP))) + continue; + + rq->cmd_flags &= ~REQ_SOFTBARRIER; + list_del_init(&rq->queuelist); +- blk_mq_sched_insert_request(rq, true, false, false); ++ /* ++ * If REQ_DONTPREP, rq has contained some driver specific ++ * data, so insert it to hctx dispatch list to avoid any ++ * merge. ++ */ ++ if (rq->cmd_flags & REQ_DONTPREP) ++ blk_mq_request_bypass_insert(rq, false); ++ else ++ blk_mq_sched_insert_request(rq, true, false, false); + } + + while (!list_empty(&rq_list)) { +-- +2.23.0 + diff --git a/lustre/kernel_patches/patches/block-Don-t-merge-requests-if-integrity-flags-rhel7.patch b/lustre/kernel_patches/patches/block-Don-t-merge-requests-if-integrity-flags-rhel7.patch new file mode 100644 index 0000000..b2bc59e --- /dev/null +++ b/lustre/kernel_patches/patches/block-Don-t-merge-requests-if-integrity-flags-rhel7.patch @@ -0,0 +1,165 @@ +From e0c0d06892051e17ee58e041259f339d0c194804 Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Fri, 26 Sep 2014 19:20:06 -0400 +block: Don't merge requests if integrity flags differ + +We'd occasionally merge requests with conflicting integrity flags. +Introduce a merge helper which checks that the requests have compatible +integrity payloads. + +Signed-off-by: Martin K. Petersen +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Signed-off-by: Jens Axboe +[gedwards@ddn.com: only compare INTEGRITY bi_flags since we don't have bip_flags yet] +--- + block/blk-integrity.c | 38 ++++++++++++++++++++++++++++---------- + block/blk-merge.c | 6 +++--- + include/linux/blkdev.h | 20 ++++++++++---------- + 3 files changed, 41 insertions(+), 23 deletions(-) + +diff --git a/block/blk-integrity.c b/block/blk-integrity.c +index 8f8cb6f84c5d..2046662547cb 100644 +--- a/block/blk-integrity.c ++++ b/block/blk-integrity.c +@@ -182,37 +182,55 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2) + } + EXPORT_SYMBOL(blk_integrity_compare); + +-int blk_integrity_merge_rq(struct request_queue *q, struct request *req, +- struct request *next) ++#define BIP_FLAGS_MASK ((1 << BIO_FS_INTEGRITY) | (1 << BIO_MAPPED_INTEGRITY)) ++bool blk_integrity_merge_rq(struct request_queue *q, struct request *req, ++ struct request *next) + { +- if (blk_integrity_rq(req) != blk_integrity_rq(next)) +- return -1; ++ if (blk_integrity_rq(req) == 0 && blk_integrity_rq(next) == 0) ++ return true; ++ ++ if (blk_integrity_rq(req) == 0 || blk_integrity_rq(next) == 0) ++ return false; ++ ++ if ((req->bio->bi_flags & BIP_FLAGS_MASK) != ++ (next->bio->bi_flags & BIP_FLAGS_MASK)) ++ return false; + + if (req->nr_integrity_segments + next->nr_integrity_segments > + q->limits.max_integrity_segments) +- return -1; ++ return false; + +- return 0; ++ return true; + } + EXPORT_SYMBOL(blk_integrity_merge_rq); + +-int blk_integrity_merge_bio(struct request_queue *q, struct request *req, +- struct bio *bio) ++bool blk_integrity_merge_bio(struct request_queue *q, struct request *req, ++ struct bio *bio) + { + int nr_integrity_segs; + struct bio *next = bio->bi_next; + ++ if (blk_integrity_rq(req) == 0 && !bio_integrity(bio)) ++ return true; ++ ++ if (blk_integrity_rq(req) == 0 || !bio_integrity(bio)) ++ return false; ++ ++ if ((req->bio->bi_flags & BIP_FLAGS_MASK) != ++ (bio->bi_flags & BIP_FLAGS_MASK)) ++ return false; ++ + bio->bi_next = NULL; + nr_integrity_segs = blk_rq_count_integrity_sg(q, bio); + bio->bi_next = next; + + if (req->nr_integrity_segments + nr_integrity_segs > + q->limits.max_integrity_segments) +- return -1; ++ return false; + + req->nr_integrity_segments += nr_integrity_segs; + +- return 0; ++ return true; + } + EXPORT_SYMBOL(blk_integrity_merge_bio); + +diff --git a/block/blk-merge.c b/block/blk-merge.c +index d6a7e3aa89f2..d91794a99fa6 100644 +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -274,7 +274,7 @@ static inline int ll_new_hw_segment(struct request_queue *q, + if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) + goto no_merge; + +- if (bio_integrity(bio) && blk_integrity_merge_bio(q, req, bio)) ++ if (blk_integrity_merge_bio(q, req, bio) == false) + goto no_merge; + + /* +@@ -372,7 +372,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, + if (total_phys_segments > queue_max_segments(q)) + return 0; + +- if (blk_integrity_rq(req) && blk_integrity_merge_rq(q, req, next)) ++ if (blk_integrity_merge_rq(q, req, next) == false) + return 0; + + /* Merge is OK... */ +@@ -566,7 +566,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) + return false; + + /* only merge integrity protected bio into ditto rq */ +- if (bio_integrity(bio) != blk_integrity_rq(rq)) ++ if (blk_integrity_merge_bio(rq->q, rq, bio) == false) + return false; + + /* must be using the same buffer */ +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 00f1af3dab99..8bef3eb8d49a 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -1743,10 +1743,10 @@ extern int blk_integrity_compare(struct gendisk *, struct gendisk *); + extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, + struct scatterlist *); + extern int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); +-extern int blk_integrity_merge_rq(struct request_queue *, struct request *, +- struct request *); +-extern int blk_integrity_merge_bio(struct request_queue *, struct request *, +- struct bio *); ++extern bool blk_integrity_merge_rq(struct request_queue *, struct request *, ++ struct request *); ++extern bool blk_integrity_merge_bio(struct request_queue *, struct request *, ++ struct bio *); + + static inline + struct blk_integrity *bdev_get_integrity(struct block_device *bdev) +@@ -1829,15 +1829,15 @@ static inline unsigned short queue_max_integrity_segments(struct request_queue * + { + return 0; + } +-static inline int blk_integrity_merge_rq(struct request_queue *rq, +- struct request *r1, +- struct request *r2) ++static inline bool blk_integrity_merge_rq(struct request_queue *rq, ++ struct request *r1, ++ struct request *r2) + { + return 0; + } +-static inline int blk_integrity_merge_bio(struct request_queue *rq, +- struct request *r, +- struct bio *b) ++static inline bool blk_integrity_merge_bio(struct request_queue *rq, ++ struct request *r, ++ struct bio *b) + { + return 0; + } +-- +2.23.0 + diff --git a/lustre/kernel_patches/series/3.10-rhel7.7.series b/lustre/kernel_patches/series/3.10-rhel7.7.series index 32c1343..5fb9308 100644 --- a/lustre/kernel_patches/series/3.10-rhel7.7.series +++ b/lustre/kernel_patches/series/3.10-rhel7.7.series @@ -6,3 +6,5 @@ fix-sd-dif-complete-rhel7.patch block-integrity-allow-optional-integrity-functions-rhel7.patch block-pass-bio-into-integrity_processing_fn-rhel7.patch block-Ensure-we-only-enable-integrity-metadata-for-reads-and-writes-rhel7.patch +blk-mq-insert-rq-with-DONTPREP-to-hctx-dispatch-rhel7.patch +block-Don-t-merge-requests-if-integrity-flags-rhel7.patch -- 1.8.3.1