ipt_hashlimit.c: sleeping function called from invalid context
PATCH 2/2 ipt_hashlimit.c: sleeping function called from invalid context
Name: sleeping function called from invalid context
Status: Tested under Linux 2.6.10
Signed-off-by Samuel Jean <[email protected]>
When we cat our proc entries, we get:
Jan 26 22:07:33 Workstation kernel: Debug: sleeping function called from invalid context at mm/slab.c:2055 Jan 26 22:07:33 Workstation kernel: in_atomic():1, irqs_disabled():0 Jan 26 22:07:33 Workstation kernel: [<c0116f80>] __might_sleep+0xb0/0xe0 Jan 26 22:07:33 Workstation kernel: [<c013f3ec>] kmem_cache_alloc+0x6c/0x70 Jan 26 22:07:33 Workstation kernel: [<e0a84b31>] dl_seq_start+0x61/0x80 [ipt_hashlimit] Jan 26 22:07:33 Workstation kernel: [<c01752bf>] seq_read+0xbf/0x2b0 Jan 26 22:07:33 Workstation kernel: [<c0154618>] vfs_read+0xb8/0x130 Jan 26 22:07:33 Workstation kernel: [<c0154901>] sys_read+0x51/0x80 Jan 26 22:07:33 Workstation kernel: [<c01031bf>] syscall_call+0x7/0xb
This incremental patch to the previous fixes it by disallowing kmalloc to sleep.
ipv4/netfilter/ipt_hashlimit.c 2005-01-26 22:36:14.000000000 -0500 renamed from ipv4/netfilter/ipt_hashlimit.c.orig 2005-01-26 22:35:43.000000000 -0500 +1 -1
@@ -570,7 +570,7 @@ static void *dl_seq_start(struct seq_fil if (*pos >= htable->cfg.size) return NULL; - bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL); + bucket = kmalloc(sizeof(unsigned int), GFP_ATOMIC); if (!bucket) return ERR_PTR(-ENOMEM);
ipv4/netfilter/ipt_hashlimit.c 2005-01-26 22:36:14.000000000 -0500 static void *dl_seq_start(struct seq_fil · line 575
Quoted 11 lines · Samuel Jean
---
net/ipv4/netfilter/ipt_hashlimit.c.orig2005-01-26 22:35:43.000000000 -0500
+++net/ipv4/netfilter/ipt_hashlimit.c2005-01-26 22:36:14.000000000 -0500ipv4/netfilter/ipt_hashlimit.c 2005-01-26 22:36:14.000000000 -0500 renamed from ipv4/netfilter/ipt_hashlimit.c.orig 2005-01-26 22:35:43.000000000 -0500 +1
-1@@ -570,7 +570,7 @@ static void *dl_seq_start(struct seq_fil if (*pos >= htable->cfg.size) return NULL; - bucket = kmalloc(sizeof(unsigned int), GFP_KERNEL); + bucket = kmalloc(sizeof(unsigned int), GFP_ATOMIC); if (!bucket) return ERR_PTR(-ENOMEM);
I've also wondered about it this morning.. Couldn't we just let kmalloc sleeps, and once we got the memory, we lock ?