[Devel] [PATCH RHEL7 COMMIT] rh/radix-tree: fix ENOMEM handling in radix_tree_insert

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jun 5 03:40:38 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.9
------>
commit d13b1b3f6a528810c7eb698d6f1c5bfd597a24a5
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Fri Jun 5 14:40:38 2015 +0400

    rh/radix-tree: fix ENOMEM handling in radix_tree_insert
    
    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.
    
    https://jira.sw.ru/browse/PSBM-34065
    
    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 e8cb1af..d5c2fa1 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);



More information about the Devel mailing list