Messages in this thread | | | Subject | Re: [PATCH] net/core/neighbour: tell kmemleak about hash tables | From | Konstantin Khlebnikov <> | Date | Tue, 8 Jan 2019 15:56:21 +0300 |
| |
On 08.01.2019 14:59, Eric Dumazet wrote: > > > On 01/08/2019 01:30 AM, Konstantin Khlebnikov wrote: >> This fixes false-positive kmemleak reports about leaked neighbour entries: >> >> unreferenced object 0xffff8885c6e4d0a8 (size 1024): > > > size 1024 object : should have been allocated by kzalloc(), right ?
Yep, neigh_alloc calls kzalloc.
Size might be bloated by lockdep.
> >> comm "softirq", pid 0, jiffies 4294922664 (age 167640.804s) >> hex dump (first 32 bytes): >> 00 00 00 00 00 00 00 00 20 2c f3 83 ff ff ff ff ........ ,...... >> 08 c0 ef 5f 84 88 ff ff 01 8c 7d 02 01 00 00 00 ..._......}..... >> backtrace: >> [<00000000748509fe>] ip6_finish_output2+0x887/0x1e40 >> [<0000000036d7a0d8>] ip6_output+0x1ba/0x600 >> [<0000000027ea7dba>] ip6_send_skb+0x92/0x2f0 >> [<00000000d6e2111d>] udp_v6_send_skb.isra.24+0x680/0x15e0 >> [<000000000668a8be>] udpv6_sendmsg+0x18c9/0x27a0 >> [<000000004bd5fa90>] sock_sendmsg+0xb3/0xf0 >> [<000000008227b29f>] ___sys_sendmsg+0x745/0x8f0 >> [<000000008698009d>] __sys_sendmsg+0xde/0x170 >> [<00000000889dacf1>] do_syscall_64+0x9b/0x400 >> [<0000000081cdb353>] entry_SYSCALL_64_after_hwframe+0x49/0xbe >> [<000000005767ed39>] 0xffffffffffffffff >> >> Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> >> --- >> net/core/neighbour.c | 13 +++++++++---- >> 1 file changed, 9 insertions(+), 4 deletions(-) >> >> diff --git a/net/core/neighbour.c b/net/core/neighbour.c >> index 763a7b08df67..3e27a779f288 100644 >> --- a/net/core/neighbour.c >> +++ b/net/core/neighbour.c >> @@ -18,6 +18,7 @@ >> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt >> >> #include <linux/slab.h> >> +#include <linux/kmemleak.h> >> #include <linux/types.h> >> #include <linux/kernel.h> >> #include <linux/module.h> >> @@ -443,12 +444,14 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) >> ret = kmalloc(sizeof(*ret), GFP_ATOMIC); >> if (!ret) >> return NULL; >> - if (size <= PAGE_SIZE) >> + if (size <= PAGE_SIZE) { >> buckets = kzalloc(size, GFP_ATOMIC); >> - else >> + } else { >> buckets = (struct neighbour __rcu **) >> __get_free_pages(GFP_ATOMIC | __GFP_ZERO, >> get_order(size)); >> + kmemleak_alloc(buckets, size, 0, GFP_ATOMIC); >> + } >> if (!buckets) { >> kfree(ret); >> return NULL; >> @@ -468,10 +471,12 @@ static void neigh_hash_free_rcu(struct rcu_head *head) >> size_t size = (1 << nht->hash_shift) * sizeof(struct neighbour *); >> struct neighbour __rcu **buckets = nht->hash_buckets; >> >> - if (size <= PAGE_SIZE) >> + if (size <= PAGE_SIZE) { >> kfree(buckets); >> - else >> + } else { >> + kmemleak_free(buckets); >> free_pages((unsigned long)buckets, get_order(size)); >> + } >> kfree(nht); >> } >> >>
| |