| From 42cbb41f8607f21114c134a7bbba1c4013519503 Mon Sep 17 00:00:00 2001 |
| From: Ritesh Harjani <riteshh@linux.ibm.com> |
| Date: Wed, 9 Sep 2020 08:44:25 +0530 |
| Subject: [PATCH] block: Set same_page to false in __bio_try_merge_page if ret |
| is false |
| |
| commit 2cd896a5e86fc326bda8614b96c0401dcc145868 upstream. |
| |
| If we hit the UINT_MAX limit of bio->bi_iter.bi_size and so we are anyway |
| not merging this page in this bio, then it make sense to make same_page |
| also as false before returning. |
| |
| Without this patch, we hit below WARNING in iomap. |
| This mostly happens with very large memory system and / or after tweaking |
| vm dirty threshold params to delay writeback of dirty data. |
| |
| WARNING: CPU: 18 PID: 5130 at fs/iomap/buffered-io.c:74 iomap_page_release+0x120/0x150 |
| CPU: 18 PID: 5130 Comm: fio Kdump: loaded Tainted: G W 5.8.0-rc3 #6 |
| Call Trace: |
| __remove_mapping+0x154/0x320 (unreliable) |
| iomap_releasepage+0x80/0x180 |
| try_to_release_page+0x94/0xe0 |
| invalidate_inode_page+0xc8/0x110 |
| invalidate_mapping_pages+0x1dc/0x540 |
| generic_fadvise+0x3c8/0x450 |
| xfs_file_fadvise+0x2c/0xe0 [xfs] |
| vfs_fadvise+0x3c/0x60 |
| ksys_fadvise64_64+0x68/0xe0 |
| sys_fadvise64+0x28/0x40 |
| system_call_exception+0xf8/0x1c0 |
| system_call_common+0xf0/0x278 |
| |
| Fixes: cc90bc68422 ("block: fix "check bi_size overflow before merge"") |
| Reported-by: Shivaprasad G Bhat <sbhat@linux.ibm.com> |
| Suggested-by: Christoph Hellwig <hch@infradead.org> |
| Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com> |
| Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com> |
| Reviewed-by: Ming Lei <ming.lei@redhat.com> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/block/bio.c b/block/bio.c |
| index 7eea97790851..22280cfba22f 100644 |
| --- a/block/bio.c |
| +++ b/block/bio.c |
| @@ -835,8 +835,10 @@ bool __bio_try_merge_page(struct bio *bio, struct page *page, |
| struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; |
| |
| if (page_is_mergeable(bv, page, len, off, same_page)) { |
| - if (bio->bi_iter.bi_size > UINT_MAX - len) |
| + if (bio->bi_iter.bi_size > UINT_MAX - len) { |
| + *same_page = false; |
| return false; |
| + } |
| bv->bv_len += len; |
| bio->bi_iter.bi_size += len; |
| return true; |
| -- |
| 2.27.0 |
| |