[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