diff for duplicates of <20170131093141.GA15899@node.shutemov.name> diff --git a/a/1.txt b/N1/1.txt index 4329e37..b6acf26 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -5,3 +5,111 @@ On Tue, Jan 31, 2017 at 09:27:41AM +0100, Dmitry Vyukov wrote: > fd694aaa46c7ed811b72eb47d5eb11ce7ab3f7f1: This should help: + +>From fb85b3fe273decb11c558d56257193424b8f071a Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> +Date: Tue, 31 Jan 2017 12:22:26 +0300 +Subject: [PATCH] shmem: fix sleeping from atomic context + +Syzkaller fuzzer managed to trigger this: + +BUG: sleeping function called from invalid context at mm/shmem.c:852 +in_atomic(): 1, irqs_disabled(): 0, pid: 529, name: khugepaged +3 locks held by khugepaged/529: + #0: (shrinker_rwsem){++++..}, at: [<ffffffff818d7ef1>] +shrink_slab.part.59+0x121/0xd30 mm/vmscan.c:451 + #1: (&type->s_umount_key#29){++++..}, at: [<ffffffff81a63630>] +trylock_super+0x20/0x100 fs/super.c:392 + #2: (&(&sbinfo->shrinklist_lock)->rlock){+.+.-.}, at: +[<ffffffff818fd83e>] spin_lock include/linux/spinlock.h:302 [inline] + #2: (&(&sbinfo->shrinklist_lock)->rlock){+.+.-.}, at: +[<ffffffff818fd83e>] shmem_unused_huge_shrink+0x28e/0x1490 +mm/shmem.c:427 +CPU: 2 PID: 529 Comm: khugepaged Not tainted 4.10.0-rc5+ #201 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:15 [inline] + dump_stack+0x2ee/0x3ef lib/dump_stack.c:51 + ___might_sleep+0x47e/0x650 kernel/sched/core.c:7780 + shmem_undo_range+0xb20/0x2710 mm/shmem.c:852 + shmem_truncate_range+0x27/0xa0 mm/shmem.c:939 + shmem_evict_inode+0x35f/0xca0 mm/shmem.c:1030 + evict+0x46e/0x980 fs/inode.c:553 + iput_final fs/inode.c:1515 [inline] + iput+0x589/0xb20 fs/inode.c:1542 + shmem_unused_huge_shrink+0xbad/0x1490 mm/shmem.c:446 + shmem_unused_huge_scan+0x10c/0x170 mm/shmem.c:512 + super_cache_scan+0x376/0x450 fs/super.c:106 + do_shrink_slab mm/vmscan.c:378 [inline] + shrink_slab.part.59+0x543/0xd30 mm/vmscan.c:481 + shrink_slab mm/vmscan.c:2592 [inline] + shrink_node+0x2c7/0x870 mm/vmscan.c:2592 + shrink_zones mm/vmscan.c:2734 [inline] + do_try_to_free_pages+0x369/0xc80 mm/vmscan.c:2776 + try_to_free_pages+0x3c6/0x900 mm/vmscan.c:2982 + __perform_reclaim mm/page_alloc.c:3301 [inline] + __alloc_pages_direct_reclaim mm/page_alloc.c:3322 [inline] + __alloc_pages_slowpath+0xa24/0x1c30 mm/page_alloc.c:3683 + __alloc_pages_nodemask+0x544/0xae0 mm/page_alloc.c:3848 + __alloc_pages include/linux/gfp.h:426 [inline] + __alloc_pages_node include/linux/gfp.h:439 [inline] + khugepaged_alloc_page+0xc2/0x1b0 mm/khugepaged.c:750 + collapse_huge_page+0x182/0x1fe0 mm/khugepaged.c:955 + khugepaged_scan_pmd+0xfdf/0x12a0 mm/khugepaged.c:1208 + khugepaged_scan_mm_slot mm/khugepaged.c:1727 [inline] + khugepaged_do_scan mm/khugepaged.c:1808 [inline] + khugepaged+0xe9b/0x1590 mm/khugepaged.c:1853 + kthread+0x326/0x3f0 kernel/kthread.c:227 + ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430 + +The iput() from atomic context was a bad idea: if after igrab() somebody +else calls iput() and we left with the last inode reference, our iput() +would lead to inode eviction and therefore sleeping. + +This patch should fix the situation. + +Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> +Reported-by: Dmitry Vyukov <dvyukov@google.com> +--- + mm/shmem.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/mm/shmem.c b/mm/shmem.c +index 3c9be716083f..54d1ebfb577d 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -415,6 +415,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + struct shrink_control *sc, unsigned long nr_to_split) + { + LIST_HEAD(list), *pos, *next; ++ LIST_HEAD(to_remove); + struct inode *inode; + struct shmem_inode_info *info; + struct page *page; +@@ -441,9 +442,8 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + /* Check if there's anything to gain */ + if (round_up(inode->i_size, PAGE_SIZE) == + round_up(inode->i_size, HPAGE_PMD_SIZE)) { +- list_del_init(&info->shrinklist); ++ list_move(&info->shrinklist, &to_remove); + removed++; +- iput(inode); + goto next; + } + +@@ -454,6 +454,13 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, + } + spin_unlock(&sbinfo->shrinklist_lock); + ++ list_for_each_safe(pos, next, &to_remove) { ++ info = list_entry(pos, struct shmem_inode_info, shrinklist); ++ inode = &info->vfs_inode; ++ list_del_init(&info->shrinklist); ++ iput(inode); ++ } ++ + list_for_each_safe(pos, next, &list) { + int ret; + +-- + Kirill A. Shutemov diff --git a/a/content_digest b/N1/content_digest index 81d26cc..1028549 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -19,6 +19,114 @@ "> I've got the following report while running syzkaller fuzzer on\n" "> fd694aaa46c7ed811b72eb47d5eb11ce7ab3f7f1:\n" "\n" - This should help: + "This should help:\n" + "\n" + ">From fb85b3fe273decb11c558d56257193424b8f071a Mon Sep 17 00:00:00 2001\n" + "From: \"Kirill A. Shutemov\" <kirill.shutemov@linux.intel.com>\n" + "Date: Tue, 31 Jan 2017 12:22:26 +0300\n" + "Subject: [PATCH] shmem: fix sleeping from atomic context\n" + "\n" + "Syzkaller fuzzer managed to trigger this:\n" + "\n" + "BUG: sleeping function called from invalid context at mm/shmem.c:852\n" + "in_atomic(): 1, irqs_disabled(): 0, pid: 529, name: khugepaged\n" + "3 locks held by khugepaged/529:\n" + " #0: (shrinker_rwsem){++++..}, at: [<ffffffff818d7ef1>]\n" + "shrink_slab.part.59+0x121/0xd30 mm/vmscan.c:451\n" + " #1: (&type->s_umount_key#29){++++..}, at: [<ffffffff81a63630>]\n" + "trylock_super+0x20/0x100 fs/super.c:392\n" + " #2: (&(&sbinfo->shrinklist_lock)->rlock){+.+.-.}, at:\n" + "[<ffffffff818fd83e>] spin_lock include/linux/spinlock.h:302 [inline]\n" + " #2: (&(&sbinfo->shrinklist_lock)->rlock){+.+.-.}, at:\n" + "[<ffffffff818fd83e>] shmem_unused_huge_shrink+0x28e/0x1490\n" + "mm/shmem.c:427\n" + "CPU: 2 PID: 529 Comm: khugepaged Not tainted 4.10.0-rc5+ #201\n" + "Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011\n" + "Call Trace:\n" + " __dump_stack lib/dump_stack.c:15 [inline]\n" + " dump_stack+0x2ee/0x3ef lib/dump_stack.c:51\n" + " ___might_sleep+0x47e/0x650 kernel/sched/core.c:7780\n" + " shmem_undo_range+0xb20/0x2710 mm/shmem.c:852\n" + " shmem_truncate_range+0x27/0xa0 mm/shmem.c:939\n" + " shmem_evict_inode+0x35f/0xca0 mm/shmem.c:1030\n" + " evict+0x46e/0x980 fs/inode.c:553\n" + " iput_final fs/inode.c:1515 [inline]\n" + " iput+0x589/0xb20 fs/inode.c:1542\n" + " shmem_unused_huge_shrink+0xbad/0x1490 mm/shmem.c:446\n" + " shmem_unused_huge_scan+0x10c/0x170 mm/shmem.c:512\n" + " super_cache_scan+0x376/0x450 fs/super.c:106\n" + " do_shrink_slab mm/vmscan.c:378 [inline]\n" + " shrink_slab.part.59+0x543/0xd30 mm/vmscan.c:481\n" + " shrink_slab mm/vmscan.c:2592 [inline]\n" + " shrink_node+0x2c7/0x870 mm/vmscan.c:2592\n" + " shrink_zones mm/vmscan.c:2734 [inline]\n" + " do_try_to_free_pages+0x369/0xc80 mm/vmscan.c:2776\n" + " try_to_free_pages+0x3c6/0x900 mm/vmscan.c:2982\n" + " __perform_reclaim mm/page_alloc.c:3301 [inline]\n" + " __alloc_pages_direct_reclaim mm/page_alloc.c:3322 [inline]\n" + " __alloc_pages_slowpath+0xa24/0x1c30 mm/page_alloc.c:3683\n" + " __alloc_pages_nodemask+0x544/0xae0 mm/page_alloc.c:3848\n" + " __alloc_pages include/linux/gfp.h:426 [inline]\n" + " __alloc_pages_node include/linux/gfp.h:439 [inline]\n" + " khugepaged_alloc_page+0xc2/0x1b0 mm/khugepaged.c:750\n" + " collapse_huge_page+0x182/0x1fe0 mm/khugepaged.c:955\n" + " khugepaged_scan_pmd+0xfdf/0x12a0 mm/khugepaged.c:1208\n" + " khugepaged_scan_mm_slot mm/khugepaged.c:1727 [inline]\n" + " khugepaged_do_scan mm/khugepaged.c:1808 [inline]\n" + " khugepaged+0xe9b/0x1590 mm/khugepaged.c:1853\n" + " kthread+0x326/0x3f0 kernel/kthread.c:227\n" + " ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430\n" + "\n" + "The iput() from atomic context was a bad idea: if after igrab() somebody\n" + "else calls iput() and we left with the last inode reference, our iput()\n" + "would lead to inode eviction and therefore sleeping.\n" + "\n" + "This patch should fix the situation.\n" + "\n" + "Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>\n" + "Reported-by: Dmitry Vyukov <dvyukov@google.com>\n" + "---\n" + " mm/shmem.c | 11 +++++++++--\n" + " 1 file changed, 9 insertions(+), 2 deletions(-)\n" + "\n" + "diff --git a/mm/shmem.c b/mm/shmem.c\n" + "index 3c9be716083f..54d1ebfb577d 100644\n" + "--- a/mm/shmem.c\n" + "+++ b/mm/shmem.c\n" + "@@ -415,6 +415,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,\n" + " \t\tstruct shrink_control *sc, unsigned long nr_to_split)\n" + " {\n" + " \tLIST_HEAD(list), *pos, *next;\n" + "+\tLIST_HEAD(to_remove);\n" + " \tstruct inode *inode;\n" + " \tstruct shmem_inode_info *info;\n" + " \tstruct page *page;\n" + "@@ -441,9 +442,8 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,\n" + " \t\t/* Check if there's anything to gain */\n" + " \t\tif (round_up(inode->i_size, PAGE_SIZE) ==\n" + " \t\t\t\tround_up(inode->i_size, HPAGE_PMD_SIZE)) {\n" + "-\t\t\tlist_del_init(&info->shrinklist);\n" + "+\t\t\tlist_move(&info->shrinklist, &to_remove);\n" + " \t\t\tremoved++;\n" + "-\t\t\tiput(inode);\n" + " \t\t\tgoto next;\n" + " \t\t}\n" + " \n" + "@@ -454,6 +454,13 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo,\n" + " \t}\n" + " \tspin_unlock(&sbinfo->shrinklist_lock);\n" + " \n" + "+\tlist_for_each_safe(pos, next, &to_remove) {\n" + "+\t\tinfo = list_entry(pos, struct shmem_inode_info, shrinklist);\n" + "+\t\tinode = &info->vfs_inode;\n" + "+\t\tlist_del_init(&info->shrinklist);\n" + "+\t\tiput(inode);\n" + "+\t}\n" + "+\n" + " \tlist_for_each_safe(pos, next, &list) {\n" + " \t\tint ret;\n" + " \n" + "-- \n" + Kirill A. Shutemov -4473d98187833854552cdef4c6bdeff37a2de0c34ae1c8519eae3398032e0ecf +c3de203b31a1d608b3af116791265f7eaf2500bd32a4b6f800b4be917e6d0a21
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.