From: Somasundaram Krishnasamy Date: Fri, 4 Aug 2017 02:05:22 +0000 (-0700) Subject: fs/fuse: fuse mount can cause panic with no memory numa node X-Git-Tag: v4.1.12-110.0.20170822_0730~42 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=384f1d8dd5f2cac85f8210945ff8489b8aa9cac3;p=users%2Fjedix%2Flinux-maple.git fs/fuse: fuse mount can cause panic with no memory numa node Orabug: 26591421 Host panics with the below stack trace:- [ 2509.835362] BUG: unable to handle kernel paging request at 0000000000001e08 [ 2509.843155] IP: [] __alloc_pages_nodemask+0xb7/0xa10 [ 2509.850466] PGD 7f5bbf5067 PUD 7f5c492067 PMD 0 .. .. [ 2510.108923] Call Trace: [ 2510.111658] [] ? native_sched_clock+0x35/0xa0 [ 2510.118360] [] ? sched_clock+0x9/0x10 [ 2510.124291] [] ? sched_clock_cpu+0x85/0xc0 [ 2510.130692] [] ? try_to_wake_up+0x47/0x370 [ 2510.137108] [] ? deactivate_slab+0x383/0x400 [ 2510.143712] [] new_slab+0xa7/0x460 [ 2510.149350] [] __slab_alloc+0x317/0x477 [ 2510.155473] [] ? fuse_conn_init+0x236/0x420 [fuse] [ 2510.162664] [] ? extract_entropy+0x14c/0x330 [ 2510.169260] [] ? get_random_bytes+0x40/0xa0 [ 2510.175769] [] kmem_cache_alloc_node_trace+0x95/0x2b0 [ 2510.183248] [] fuse_conn_init+0x236/0x420 [fuse] [ 2510.190241] [] fuse_fill_super+0x3a0/0x700 [fuse] [ 2510.197330] [] ? __kmalloc+0x266/0x2c0 [ 2510.203355] [] ? register_shrinker+0x3c/0xa0 [ 2510.209961] [] ? sget+0x3b8/0x3f0 [ 2510.215500] [] ? get_anon_bdev+0x120/0x120 [ 2510.221911] [] ? fuse_conn_init+0x420/0x420 [fuse] [ 2510.229096] [] mount_nodev+0x4d/0xb0 [ 2510.234927] [] fuse_mount+0x18/0x20 [fuse] [ 2510.241337] [] mount_fs+0x39/0x180 [ 2510.246975] [] vfs_kern_mount+0x6b/0x110 [ 2510.253191] [] do_mount+0x251/0xcf0 [ 2510.258922] [] SyS_mount+0xa2/0x110 [ 2510.264653] [] ? syscall_trace_leave+0xc6/0x150 [ 2510.271551] [] system_call_fastpath+0x12/0x71 This commit reverts the changes done in 937287c2e4ab ("fs/fuse: Fix for correct number of numa nodes") and fixes the original problem by calling kmalloc_node/kmem_cache_alloc_node, only on the online numa nodes. For the offline nodes, kmalloc or kmem_cache_alloc will be used for allocation. This problem happens only with slub allocator because it does not do fallback allocation if node is offline, unlike slab. And for that reason, the same behavior is emulated here. Signed-off-by: Somasundaram Krishnasamy Reviewed-by: Ashish Samant Reviewed-by: Babu Moger --- diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d41bed1ed2203..9ae98d4719750 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -71,15 +71,20 @@ static struct fuse_req *__fuse_request_alloc(struct fuse_conn *fc, { struct fuse_req *req; struct fuse_node *fn; + int nid; fn = fuse_get_node(fc); if (fc->affinity == FUSE_CPU) - req = kmem_cache_alloc_node(fuse_req_cachep, GFP_KERNEL, - cpu_to_node(fn->node_id)); + nid = cpu_to_node(fn->node_id); else - req = kmem_cache_alloc_node(fuse_req_cachep, GFP_KERNEL, - fn->node_id); + nid = fn->node_id; + + if (node_online(nid)) + req = kmem_cache_alloc_node(fuse_req_cachep, GFP_KERNEL, nid); + else + req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); + if (req) { struct page **pages; struct fuse_page_desc *page_descs; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1d814cdade168..b6b9234e55a2e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -618,10 +618,10 @@ int fuse_conn_init(struct fuse_conn *fc, int affinity) if (affinity == FUSE_CPU) { fc->affinity = FUSE_CPU; - fc->nr_nodes = num_present_cpus(); + fc->nr_nodes = num_possible_cpus(); } else if (affinity == FUSE_NUMA) { fc->affinity = FUSE_NUMA; - fc->nr_nodes = nr_online_nodes; + fc->nr_nodes = nr_node_ids; } else { fc->affinity = FUSE_NONE; fc->nr_nodes = 1; @@ -648,7 +648,10 @@ int fuse_conn_init(struct fuse_conn *fc, int affinity) } else { sz = sizeof(struct fuse_node); for (i = 0; i < fc->nr_nodes; i++) { - fn = kmalloc_node(sz, GFP_KERNEL, i); + if (node_online(i)) + fn = kmalloc_node(sz, GFP_KERNEL, i); + else + fn = kmalloc(sz, GFP_KERNEL); if (!fn) goto out; memset(fn, 0, sz);