[Devel] [PATCH rh7] radix-tree: fix ENOMEM handling in radix_tree_insert
Vladimir Davydov
vdavydov at parallels.com
Wed Jun 3 09:14:56 PDT 2015
If __radix_tree_create fails to allocate memory, it will leave *slotp
uninitialized. As a result, radix_tree_insert, which calls it, will at
the very best return EEXIST instead of ENOMEM (at worst it will crash),
leading to a BUG in fussy tcache_attach_page:
kernel BUG at mm/tcache.c:576!
invalid opcode: 0000 [#1] SMP
CPU: 0 PID: 12981 Comm: memeater ve: d466287e-31f8-4ad8-b34e-437c55d5b0ce Not tainted 3.10.0+ #101 ovz.5.1-80-g8ce389905103
task: ffff880091819940 ti: ffff880090892000 task.ti: ffff880090892000
RIP: 0010:[<ffffffff811b628f>] [<ffffffff811b628f>] tcache_attach_page+0x1df/0x1f0
RSP: 0000:ffff8800908935e8 EFLAGS: 00010046
RAX: 00000000ffffffef RBX: ffffea0002064700 RCX: 0000000000000000
RDX: 0000000080000002 RSI: 0000000000000000 RDI: ffff880036681000
RBP: ffff880090893618 R08: 0000000000000000 R09: 0000000000000000
R10: ffff8800908935c8 R11: 31fa294ce2894c00 R12: 00000000ffffffef
R13: ffff8800919bcd50 R14: ffff8800919bcd00 R15: ffff8800919bcd40
FS: 00007ffff7fef720(0000) GS:ffff88010be00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007ffff5ba3000 CR3: 0000000091a11000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
0000000000000096 ffff8800919bcd00 0000000000000006 000000000000005f
ffffea0002064700 ffffea00026a3d40 ffff880090893650 ffffffff811b72dc
ffffea00026a3d40 0000000000000006 ffff880109a90a20 00000000281e0006
Call Trace:
[<ffffffff811b72dc>] tcache_cleancache_put_page+0xbc/0x110
[<ffffffff811b5186>] __cleancache_put_page+0x96/0xc0
[<ffffffff811460e1>] __delete_from_page_cache+0x2d1/0x350
[<ffffffff8117fc11>] ? page_referenced+0x191/0x4d0
[<ffffffff811575c8>] __remove_mapping+0xb8/0x1a0
[<ffffffff811582c8>] shrink_page_list+0x3c8/0xac0
[<ffffffff81157983>] ? isolate_lru_pages.isra.47+0xd3/0x190
[<ffffffff8115906a>] shrink_inactive_list+0x1ea/0x580
[<ffffffff81159bd5>] shrink_lruvec+0x395/0x710
[<ffffffff81156201>] ? shrink_slab+0x291/0x410
[<ffffffff8115a03f>] shrink_zone+0xef/0x2b0
[<ffffffff8115a5a1>] do_try_to_free_pages+0x181/0x510
[<ffffffff8114e43a>] ? get_page_from_freelist+0x52a/0x950
[<ffffffff8115ab46>] try_to_free_mem_cgroup_pages+0xb6/0x140
[<ffffffff811ae3c3>] mem_cgroup_reclaim+0x53/0xe0
[<ffffffff811aee7e>] __mem_cgroup_try_charge+0x4fe/0xc90
[<ffffffff811afe19>] mem_cgroup_charge_common+0x59/0xc0
[<ffffffff811b0f06>] mem_cgroup_newpage_charge+0x26/0x30
[<ffffffff81173dfb>] handle_mm_fault+0xa8b/0xdf0
[<ffffffff815d31fe>] __do_page_fault+0x15e/0x530
[<ffffffff811451e3>] ? unlock_page+0x23/0x30
[<ffffffff8117695b>] ? __munlock_vma_pages_range+0xbb/0x110
[<ffffffff81176af0>] ? mlock_fixup+0x140/0x200
[<ffffffff815d35ea>] do_page_fault+0x1a/0x70
[<ffffffff815cf848>] page_fault+0x28/0x30
The hunk checking the error code returned by __radix_tree_cache seems to
have been lost by RH guys - see commit 0495ee1dd0a04 ("rh7: import RHEL7
kernel-3.10.0-123.1.2.el7"). Resurrect it.
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
lib/radix-tree.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index e8cb1afa236b..d5c2fa1a4102 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -433,6 +433,8 @@ int radix_tree_insert(struct radix_tree_root *root,
BUG_ON(radix_tree_is_indirect_ptr(item));
error = __radix_tree_create(root, index, &node, &slot);
+ if (error)
+ return error;
if (*slot != NULL)
return -EEXIST;
rcu_assign_pointer(*slot, item);
--
2.1.4
More information about the Devel
mailing list