| From f765f07819765c388be1d528caaecd580413c32a Mon Sep 17 00:00:00 2001 |
| From: Qian Cai <cai@lca.pw> |
| Date: Sat, 21 Mar 2020 18:22:17 -0700 |
| Subject: [PATCH] page-flags: fix a crash at SetPageError(THP_SWAP) |
| |
| commit d72520ad004a8ce18a6ba6cde317f0081b27365a upstream. |
| |
| Commit bd4c82c22c36 ("mm, THP, swap: delay splitting THP after swapped |
| out") supported writing THP to a swap device but forgot to upgrade an |
| older commit df8c94d13c7e ("page-flags: define behavior of FS/IO-related |
| flags on compound pages") which could trigger a crash during THP |
| swapping out with DEBUG_VM_PGFLAGS=y, |
| |
| kernel BUG at include/linux/page-flags.h:317! |
| |
| page dumped because: VM_BUG_ON_PAGE(1 && PageCompound(page)) |
| page:fffff3b2ec3a8000 refcount:512 mapcount:0 mapping:000000009eb0338c index:0x7f6e58200 head:fffff3b2ec3a8000 order:9 compound_mapcount:0 compound_pincount:0 |
| anon flags: 0x45fffe0000d8454(uptodate|lru|workingset|owner_priv_1|writeback|head|reclaim|swapbacked) |
| |
| end_swap_bio_write() |
| SetPageError(page) |
| VM_BUG_ON_PAGE(1 && PageCompound(page)) |
| |
| <IRQ> |
| bio_endio+0x297/0x560 |
| dec_pending+0x218/0x430 [dm_mod] |
| clone_endio+0xe4/0x2c0 [dm_mod] |
| bio_endio+0x297/0x560 |
| blk_update_request+0x201/0x920 |
| scsi_end_request+0x6b/0x4b0 |
| scsi_io_completion+0x509/0x7e0 |
| scsi_finish_command+0x1ed/0x2a0 |
| scsi_softirq_done+0x1c9/0x1d0 |
| __blk_mqnterrupt+0xf/0x20 |
| </IRQ> |
| |
| Fix by checking PF_NO_TAIL in those places instead. |
| |
| Fixes: bd4c82c22c36 ("mm, THP, swap: delay splitting THP after swapped out") |
| Signed-off-by: Qian Cai <cai@lca.pw> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Reviewed-by: David Hildenbrand <david@redhat.com> |
| Acked-by: "Huang, Ying" <ying.huang@intel.com> |
| Acked-by: Rafael Aquini <aquini@redhat.com> |
| Cc: <stable@vger.kernel.org> |
| Link: http://lkml.kernel.org/r/20200310235846.1319-1-cai@lca.pw |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h |
| index fd6549160f2c..38d458882319 100644 |
| --- a/include/linux/page-flags.h |
| +++ b/include/linux/page-flags.h |
| @@ -309,7 +309,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; } |
| |
| __PAGEFLAG(Locked, locked, PF_NO_TAIL) |
| PAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) __CLEARPAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) |
| -PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND) |
| +PAGEFLAG(Error, error, PF_NO_TAIL) TESTCLEARFLAG(Error, error, PF_NO_TAIL) |
| PAGEFLAG(Referenced, referenced, PF_HEAD) |
| TESTCLEARFLAG(Referenced, referenced, PF_HEAD) |
| __SETPAGEFLAG(Referenced, referenced, PF_HEAD) |
| -- |
| 2.7.4 |
| |