From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pablo Neira Subject: Re: GFP_ATOMIC vs GFP_KERNEL in netfilter module Date: Fri, 03 Dec 2004 00:33:59 +0100 Message-ID: <41AFA667.4030004@eurodev.net> References: <92A26C52-44B7-11D9-A62F-000A957B2B6C@inf.ufrgs.br> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: netfilter-devel@lists.netfilter.org Return-path: To: Roberto Jung Drebes In-Reply-To: <92A26C52-44B7-11D9-A62F-000A957B2B6C@inf.ufrgs.br> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: netfilter-devel-bounces@lists.netfilter.org Errors-To: netfilter-devel-bounces@lists.netfilter.org List-Id: netfilter-devel.vger.kernel.org You are in interrupt context, so GFP_KERNEL is illegal since it can sleep. -- Pablo Roberto Jung Drebes wrote: > Hello there, > > I am testing a simple netfilter module which delays every 5th IP > packet received. I am having problems allocating the timer structure. > Here is the netfilter hook I register: > > static unsigned int > comfirm_rx_hook(unsigned int hook, > struct sk_buff **pskb, > const struct net_device *in, > const struct net_device *out, > int (*okfn) (struct sk_buff *)) > { > static int counter; > struct timer_list *tl; > struct cf_delay_parms *dp; > > if ((*pskb)->nfmark != CF_MAGIC) { > counter++; > > if (!(counter % 5)) { > dp = kmalloc(sizeof(struct cf_delay_parms), GFP_KERNEL); > tl = kmalloc(sizeof(struct timer_list), GFP_KERNEL); > dp->timer = tl; > (*pskb)->nfmark = CF_MAGIC; > dp->skb = *pskb; > tl->data = (unsigned long) dp; > tl->function = (void *) cf_delay_rx; > tl->expires = jiffies + 100; > init_timer(tl); > add_timer(tl); > printk("packet delayed\n"); > return NF_STOLEN; > } else > return NF_ACCEPT; > } else > return NF_ACCEPT; > } > > void cf_delay_rx(struct cf_delay_parms *parms) > { > ip_rcv(parms->skb, parms->skb->dev, NULL); > kfree(parms->timer); > kfree(parms); > } > > If I use GFP_KERNEL with the kmallocs, I get errors like > > Debug: sleeping function called from invalid context at mm/slab.c:2000 > in_atomic():1[expected: 0], irqs_disabled():0 > [<0211b765>] __might_sleep+0x82/0x8c > [<02146dbc>] kmem_cache_alloc+0x1d/0x4c > [<2204b047>] comfirm_rx_hook+0x47/0xd8 [mymodule] > [<022a68eb>] nf_iterate+0x40/0x89 > [<022b5d63>] ip_rcv_finish+0x0/0x1d9 > [<022a6bac>] nf_hook_slow+0x47/0xb1 > [<022b5d63>] ip_rcv_finish+0x0/0x1d9 > [<022b5be7>] ip_rcv+0x36d/0x3a1 > [<022b5d63>] ip_rcv_finish+0x0/0x1d9 > [<0229eef3>] netif_receive_skb+0x1b0/0x1dd > [<0229ef8c>] process_backlog+0x6c/0xd9 > [<0229f056>] net_rx_action+0x5d/0xcd > [<02122fa1>] __do_softirq+0x35/0x73 > [<02108a7b>] do_softirq+0x46/0x4d > ======================= > [<02107e67>] do_IRQ+0x2f7/0x303 > [<021fc4c1>] acpi_processor_idle+0xd3/0x1c5 > [<0210408c>] cpu_idle+0x1f/0x34 > [<0239b6ae>] start_kernel+0x221/0x224 > > If I use GFP_ATOMIC, I don't get the error, but I think timers are not > being called after the delay. I have a similar code for transmition, > which works OK with GFP_KERNEL (delays messages) but with GFP_ATOMIC > it does also not delay. > > I test delay with ping, and I am running kernel 2.6.8-1.521 from > Fedora Core 2. > > What am I doing wrong? > > TIA, > > ps: Please CC me any reply from the linux-kernel mailing list. >