[Devel] [PATCH rh7] radix-tree: fix ENOMEM handling in radix_tree_insert

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jun 5 03:41:43 PDT 2015


JFYI: i've filed a bug for it: https://jira.sw.ru/browse/PSBM-34065

Once we rebase to the latest RHEL7 kernel, need to recheck if they still have not ported that hunk.

If not, to file a bug to RedHat about it.

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 06/03/2015 07:14 PM, Vladimir Davydov wrote:
> 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);
> 



More information about the Devel mailing list