Message ID | 1479285671-1298-1-git-send-email-nicolas.dichtel@6wind.com |
---|---|
State | Superseded, archived |
Delegated to: | David Miller |
Headers | show |
Le 16/11/2016 à 09:41, Nicolas Dichtel a écrit : > Andrei reports the following kmemleak error: > unreferenced object 0xffff91badb543950 (size 2096): > comm "kworker/u4:0", pid 6, jiffies 4295152553 (age 28.418s) > hex dump (first 32 bytes): > 00 00 00 00 00 00 00 00 00 cb 5f df ba 91 ff ff .........._..... > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > backtrace: > [<ffffffffb1865bea>] kmemleak_alloc+0x4a/0xa0 > [<ffffffffb1243b38>] kmem_cache_alloc+0x128/0x280 > [<ffffffffb142f5ab>] idr_layer_alloc+0x2b/0x90 > [<ffffffffb142f9cd>] idr_get_empty_slot+0x34d/0x370 > [<ffffffffb142fa4e>] idr_alloc+0x5e/0x110 > [<ffffffffb170ac3d>] __peernet2id_alloc+0x6d/0x90 > [<ffffffffb170bda5>] peernet2id_alloc+0x55/0xb0 > [<ffffffffb1731216>] rtnl_fill_ifinfo+0xaa6/0x10a0 > [<ffffffffb1733073>] rtmsg_ifinfo_build_skb+0x73/0xd0 > [<ffffffffb17125d5>] rollback_registered_many+0x295/0x390 > [<ffffffffb1712765>] unregister_netdevice_many+0x25/0x80 > [<ffffffffb17138a5>] default_device_exit_batch+0x145/0x170 > [<ffffffffb170ae52>] ops_exit_list.isra.4+0x52/0x60 > [<ffffffffb170c17f>] cleanup_net+0x1bf/0x2a0 > [<ffffffffb10b616f>] process_one_work+0x1ff/0x660 > [<ffffffffb10b661e>] worker_thread+0x4e/0x480 > > There is no reason to try to allocate an nsid for a netns which is dying. > > Reported-by: Andrei Vagin <avagin@gmail.com> > Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> 'Fixes' tag is missing :/ Fixes: 0c7aecd4bde4 ("netns: add rtnl cmd to add and get peer netns ids")
Hi Nicolas, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Nicolas-Dichtel/net-nsid-cannot-be-allocated-for-a-dead-netns/20161116-164739 config: i386-randconfig-x006-201646 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/list.h:4, from include/linux/timer.h:4, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: net/core/net_namespace.c: In function 'alloc_netid': >> net/core/net_namespace.c:162:49: error: incompatible type for argument 1 of 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^ include/linux/compiler.h:149:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> net/core/net_namespace.c:162:2: note: in expansion of macro 'if' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:58, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/ktime.h:24, from include/linux/timer.h:5, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'atomic_t {aka struct <anonymous>}' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/list.h:4, from include/linux/timer.h:4, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: >> net/core/net_namespace.c:162:49: error: incompatible type for argument 1 of 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^ include/linux/compiler.h:149:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> net/core/net_namespace.c:162:2: note: in expansion of macro 'if' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:58, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/ktime.h:24, from include/linux/timer.h:5, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'atomic_t {aka struct <anonymous>}' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/list.h:4, from include/linux/timer.h:4, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: >> net/core/net_namespace.c:162:49: error: incompatible type for argument 1 of 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^ include/linux/compiler.h:160:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ >> net/core/net_namespace.c:162:2: note: in expansion of macro 'if' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:58, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/ktime.h:24, from include/linux/timer.h:5, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'atomic_t {aka struct <anonymous>}' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ vim +/atomic_read +162 net/core/net_namespace.c 1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 > 3 #include <linux/workqueue.h> 4 #include <linux/rtnetlink.h> 5 #include <linux/cache.h> 6 #include <linux/slab.h> 7 #include <linux/list.h> 8 #include <linux/delay.h> 9 #include <linux/sched.h> 10 #include <linux/idr.h> 11 #include <linux/rculist.h> 12 #include <linux/nsproxy.h> 13 #include <linux/fs.h> 14 #include <linux/proc_ns.h> 15 #include <linux/file.h> 16 #include <linux/export.h> 17 #include <linux/user_namespace.h> 18 #include <linux/net_namespace.h> 19 #include <net/sock.h> 20 #include <net/netlink.h> 21 #include <net/net_namespace.h> 22 #include <net/netns/generic.h> 23 24 /* 25 * Our network namespace constructor/destructor lists 26 */ 27 28 static LIST_HEAD(pernet_list); 29 static struct list_head *first_device = &pernet_list; 30 DEFINE_MUTEX(net_mutex); 31 32 LIST_HEAD(net_namespace_list); 33 EXPORT_SYMBOL_GPL(net_namespace_list); 34 35 struct net init_net = { 36 .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), 37 }; 38 EXPORT_SYMBOL(init_net); 39 40 static bool init_net_initialized; 41 42 #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ 43 44 static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; 45 46 static struct net_generic *net_alloc_generic(void) 47 { 48 struct net_generic *ng; 49 size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); 50 51 ng = kzalloc(generic_size, GFP_KERNEL); 52 if (ng) 53 ng->len = max_gen_ptrs; 54 55 return ng; 56 } 57 58 static int net_assign_generic(struct net *net, int id, void *data) 59 { 60 struct net_generic *ng, *old_ng; 61 62 BUG_ON(!mutex_is_locked(&net_mutex)); 63 BUG_ON(id == 0); 64 65 old_ng = rcu_dereference_protected(net->gen, 66 lockdep_is_held(&net_mutex)); 67 ng = old_ng; 68 if (old_ng->len >= id) 69 goto assign; 70 71 ng = net_alloc_generic(); 72 if (ng == NULL) 73 return -ENOMEM; 74 75 /* 76 * Some synchronisation notes: 77 * 78 * The net_generic explores the net->gen array inside rcu 79 * read section. Besides once set the net->gen->ptr[x] 80 * pointer never changes (see rules in netns/generic.h). 81 * 82 * That said, we simply duplicate this array and schedule 83 * the old copy for kfree after a grace period. 84 */ 85 86 memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); 87 88 rcu_assign_pointer(net->gen, ng); 89 kfree_rcu(old_ng, rcu); 90 assign: 91 ng->ptr[id - 1] = data; 92 return 0; 93 } 94 95 static int ops_init(const struct pernet_operations *ops, struct net *net) 96 { 97 int err = -ENOMEM; 98 void *data = NULL; 99 100 if (ops->id && ops->size) { 101 data = kzalloc(ops->size, GFP_KERNEL); 102 if (!data) 103 goto out; 104 105 err = net_assign_generic(net, *ops->id, data); 106 if (err) 107 goto cleanup; 108 } 109 err = 0; 110 if (ops->init) 111 err = ops->init(net); 112 if (!err) 113 return 0; 114 115 cleanup: 116 kfree(data); 117 118 out: 119 return err; 120 } 121 122 static void ops_free(const struct pernet_operations *ops, struct net *net) 123 { 124 if (ops->id && ops->size) { 125 int id = *ops->id; 126 kfree(net_generic(net, id)); 127 } 128 } 129 130 static void ops_exit_list(const struct pernet_operations *ops, 131 struct list_head *net_exit_list) 132 { 133 struct net *net; 134 if (ops->exit) { 135 list_for_each_entry(net, net_exit_list, exit_list) 136 ops->exit(net); 137 } 138 if (ops->exit_batch) 139 ops->exit_batch(net_exit_list); 140 } 141 142 static void ops_free_list(const struct pernet_operations *ops, 143 struct list_head *net_exit_list) 144 { 145 struct net *net; 146 if (ops->size && ops->id) { 147 list_for_each_entry(net, net_exit_list, exit_list) 148 ops_free(ops, net); 149 } 150 } 151 152 /* should be called with nsid_lock held */ 153 static int alloc_netid(struct net *net, struct net *peer, int reqid) 154 { 155 int min = 0, max = 0; 156 157 if (reqid >= 0) { 158 min = reqid; 159 max = reqid + 1; 160 } 161 > 162 if (!atomic_read(&net->count) || !&atomic_read(peer->count)) 163 return -EINVAL; 164 165 return idr_alloc(&net->netns_ids, peer, min, max, GFP_ATOMIC); --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Le 16/11/2016 à 10:10, kbuild test robot a écrit : > Hi Nicolas, > > [auto build test ERROR on net/master] And I finally send the wrong version of the patch :(
Hi Nicolas, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Nicolas-Dichtel/net-nsid-cannot-be-allocated-for-a-dead-netns/20161116-164739 config: sparc-defconfig (attached as .config) compiler: sparc-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc All error/warnings (new ones prefixed by >>): In file included from include/uapi/linux/stddef.h:1:0, from include/linux/stddef.h:4, from include/uapi/linux/posix_types.h:4, from include/uapi/linux/types.h:13, from include/linux/types.h:5, from include/linux/list.h:4, from include/linux/timer.h:4, from include/linux/workqueue.h:8, from net/core/net_namespace.c:3: net/core/net_namespace.c: In function 'alloc_netid': >> arch/sparc/include/asm/atomic_32.h:32:48: error: invalid type argument of '->' (have 'atomic_t {aka struct <anonymous>}') #define atomic_read(v) ACCESS_ONCE((v)->counter) ^ include/linux/compiler.h:545:25: note: in definition of macro '__ACCESS_ONCE' __maybe_unused typeof(x) __var = (__force typeof(x)) 0; \ ^ >> arch/sparc/include/asm/atomic_32.h:32:33: note: in expansion of macro 'ACCESS_ONCE' #define atomic_read(v) ACCESS_ONCE((v)->counter) ^~~~~~~~~~~ net/core/net_namespace.c:162:37: note: in expansion of macro 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~~~~~~~~~~ >> arch/sparc/include/asm/atomic_32.h:32:48: error: invalid type argument of '->' (have 'atomic_t {aka struct <anonymous>}') #define atomic_read(v) ACCESS_ONCE((v)->counter) ^ include/linux/compiler.h:545:52: note: in definition of macro '__ACCESS_ONCE' __maybe_unused typeof(x) __var = (__force typeof(x)) 0; \ ^ >> arch/sparc/include/asm/atomic_32.h:32:33: note: in expansion of macro 'ACCESS_ONCE' #define atomic_read(v) ACCESS_ONCE((v)->counter) ^~~~~~~~~~~ net/core/net_namespace.c:162:37: note: in expansion of macro 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~~~~~~~~~~ >> arch/sparc/include/asm/atomic_32.h:32:48: error: invalid type argument of '->' (have 'atomic_t {aka struct <anonymous>}') #define atomic_read(v) ACCESS_ONCE((v)->counter) ^ include/linux/compiler.h:546:19: note: in definition of macro '__ACCESS_ONCE' (volatile typeof(x) *)&(x); }) ^ >> arch/sparc/include/asm/atomic_32.h:32:33: note: in expansion of macro 'ACCESS_ONCE' #define atomic_read(v) ACCESS_ONCE((v)->counter) ^~~~~~~~~~~ net/core/net_namespace.c:162:37: note: in expansion of macro 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~~~~~~~~~~ >> arch/sparc/include/asm/atomic_32.h:32:48: error: invalid type argument of '->' (have 'atomic_t {aka struct <anonymous>}') #define atomic_read(v) ACCESS_ONCE((v)->counter) ^ include/linux/compiler.h:546:26: note: in definition of macro '__ACCESS_ONCE' (volatile typeof(x) *)&(x); }) ^ >> arch/sparc/include/asm/atomic_32.h:32:33: note: in expansion of macro 'ACCESS_ONCE' #define atomic_read(v) ACCESS_ONCE((v)->counter) ^~~~~~~~~~~ net/core/net_namespace.c:162:37: note: in expansion of macro 'atomic_read' if (!atomic_read(&net->count) || !&atomic_read(peer->count)) ^~~~~~~~~~~ vim +32 arch/sparc/include/asm/atomic_32.h d550bbd4 arch/sparc/include/asm/atomic_32.h David Howells 2012-03-28 16 #include <asm/cmpxchg.h> 56d36489 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-13 17 #include <asm/barrier.h> aea1181b arch/sparc/include/asm/atomic_32.h Sam Ravnborg 2011-12-27 18 #include <asm-generic/atomic64.h> aea1181b arch/sparc/include/asm/atomic_32.h Sam Ravnborg 2011-12-27 19 f5e706ad include/asm-sparc/atomic_32.h Sam Ravnborg 2008-07-17 20 #define ATOMIC_INIT(i) { (i) } f5e706ad include/asm-sparc/atomic_32.h Sam Ravnborg 2008-07-17 21 4f3316c2 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-26 22 int atomic_add_return(int, atomic_t *); 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 23 int atomic_fetch_add(int, atomic_t *); 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 24 int atomic_fetch_and(int, atomic_t *); 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 25 int atomic_fetch_or(int, atomic_t *); 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 26 int atomic_fetch_xor(int, atomic_t *); f05a6865 arch/sparc/include/asm/atomic_32.h Sam Ravnborg 2014-05-16 27 int atomic_cmpxchg(atomic_t *, int, int); 1a17fdc4 arch/sparc/include/asm/atomic_32.h Andreas Larsson 2014-11-05 28 int atomic_xchg(atomic_t *, int); f05a6865 arch/sparc/include/asm/atomic_32.h Sam Ravnborg 2014-05-16 29 int __atomic_add_unless(atomic_t *, int, int); f05a6865 arch/sparc/include/asm/atomic_32.h Sam Ravnborg 2014-05-16 30 void atomic_set(atomic_t *, int); f5e706ad include/asm-sparc/atomic_32.h Sam Ravnborg 2008-07-17 31 2291059c arch/sparc/include/asm/atomic_32.h Pranith Kumar 2014-09-23 @32 #define atomic_read(v) ACCESS_ONCE((v)->counter) f5e706ad include/asm-sparc/atomic_32.h Sam Ravnborg 2008-07-17 33 4f3316c2 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-26 34 #define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v))) 4f3316c2 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-26 35 #define atomic_sub(i, v) ((void)atomic_add_return(-(int)(i), (v))) 4f3316c2 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-26 36 #define atomic_inc(v) ((void)atomic_add_return( 1, (v))) 4f3316c2 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2014-03-26 37 #define atomic_dec(v) ((void)atomic_add_return( -1, (v))) f5e706ad include/asm-sparc/atomic_32.h Sam Ravnborg 2008-07-17 38 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 39 #define atomic_and(i, v) ((void)atomic_fetch_and((i), (v))) 3a1adb23 arch/sparc/include/asm/atomic_32.h Peter Zijlstra 2016-04-18 40 #define atomic_or(i, v) ((void)atomic_fetch_or((i), (v))) :::::: The code at line 32 was first introduced by commit :::::: 2291059c852706c6f5ffb400366042b7625066cd locking,arch: Use ACCESS_ONCE() instead of cast to volatile in atomic_read() :::::: TO: Pranith Kumar <bobby.prani@gmail.com> :::::: CC: Ingo Molnar <mingo@kernel.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hello. On 11/16/2016 11:41 AM, Nicolas Dichtel wrote: > Andrei reports the following kmemleak error: > unreferenced object 0xffff91badb543950 (size 2096): > comm "kworker/u4:0", pid 6, jiffies 4295152553 (age 28.418s) > hex dump (first 32 bytes): > 00 00 00 00 00 00 00 00 00 cb 5f df ba 91 ff ff .........._..... > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > backtrace: > [<ffffffffb1865bea>] kmemleak_alloc+0x4a/0xa0 > [<ffffffffb1243b38>] kmem_cache_alloc+0x128/0x280 > [<ffffffffb142f5ab>] idr_layer_alloc+0x2b/0x90 > [<ffffffffb142f9cd>] idr_get_empty_slot+0x34d/0x370 > [<ffffffffb142fa4e>] idr_alloc+0x5e/0x110 > [<ffffffffb170ac3d>] __peernet2id_alloc+0x6d/0x90 > [<ffffffffb170bda5>] peernet2id_alloc+0x55/0xb0 > [<ffffffffb1731216>] rtnl_fill_ifinfo+0xaa6/0x10a0 > [<ffffffffb1733073>] rtmsg_ifinfo_build_skb+0x73/0xd0 > [<ffffffffb17125d5>] rollback_registered_many+0x295/0x390 > [<ffffffffb1712765>] unregister_netdevice_many+0x25/0x80 > [<ffffffffb17138a5>] default_device_exit_batch+0x145/0x170 > [<ffffffffb170ae52>] ops_exit_list.isra.4+0x52/0x60 > [<ffffffffb170c17f>] cleanup_net+0x1bf/0x2a0 > [<ffffffffb10b616f>] process_one_work+0x1ff/0x660 > [<ffffffffb10b661e>] worker_thread+0x4e/0x480 > > There is no reason to try to allocate an nsid for a netns which is dying. > > Reported-by: Andrei Vagin <avagin@gmail.com> > Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> > --- > > Thank you for the report. Can you test this patch? > > Regards, > Nicolas > > net/core/net_namespace.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c > index f61c0e02a413..f1340ed0d8df 100644 > --- a/net/core/net_namespace.c > +++ b/net/core/net_namespace.c > @@ -159,6 +159,9 @@ static int alloc_netid(struct net *net, struct net *peer, int reqid) > max = reqid + 1; > } > > + if (!atomic_read(&net->count) || !&atomic_read(peer->count)) Looks like & is misplaced in the second case? MBR, Sergei
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index f61c0e02a413..f1340ed0d8df 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -159,6 +159,9 @@ static int alloc_netid(struct net *net, struct net *peer, int reqid) max = reqid + 1; } + if (!atomic_read(&net->count) || !&atomic_read(peer->count)) + return -EINVAL; + return idr_alloc(&net->netns_ids, peer, min, max, GFP_ATOMIC); }
Andrei reports the following kmemleak error: unreferenced object 0xffff91badb543950 (size 2096): comm "kworker/u4:0", pid 6, jiffies 4295152553 (age 28.418s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 cb 5f df ba 91 ff ff .........._..... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffffb1865bea>] kmemleak_alloc+0x4a/0xa0 [<ffffffffb1243b38>] kmem_cache_alloc+0x128/0x280 [<ffffffffb142f5ab>] idr_layer_alloc+0x2b/0x90 [<ffffffffb142f9cd>] idr_get_empty_slot+0x34d/0x370 [<ffffffffb142fa4e>] idr_alloc+0x5e/0x110 [<ffffffffb170ac3d>] __peernet2id_alloc+0x6d/0x90 [<ffffffffb170bda5>] peernet2id_alloc+0x55/0xb0 [<ffffffffb1731216>] rtnl_fill_ifinfo+0xaa6/0x10a0 [<ffffffffb1733073>] rtmsg_ifinfo_build_skb+0x73/0xd0 [<ffffffffb17125d5>] rollback_registered_many+0x295/0x390 [<ffffffffb1712765>] unregister_netdevice_many+0x25/0x80 [<ffffffffb17138a5>] default_device_exit_batch+0x145/0x170 [<ffffffffb170ae52>] ops_exit_list.isra.4+0x52/0x60 [<ffffffffb170c17f>] cleanup_net+0x1bf/0x2a0 [<ffffffffb10b616f>] process_one_work+0x1ff/0x660 [<ffffffffb10b661e>] worker_thread+0x4e/0x480 There is no reason to try to allocate an nsid for a netns which is dying. Reported-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> --- Thank you for the report. Can you test this patch? Regards, Nicolas net/core/net_namespace.c | 3 +++ 1 file changed, 3 insertions(+)