public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Debug: sleeping function called from invalid context at mm/slab.c:2126
@ 2005-11-10  2:35 Tony
  0 siblings, 0 replies; 4+ messages in thread
From: Tony @ 2005-11-10  2:35 UTC (permalink / raw)
  To: linux-kernel

I'm writing a net_device driver. I want to send a packet when the timer 
is out. I get the following warning. It seems that I should not call 
alloc_skb. Can anyone tell me how to get rid of this? Thanks in advance.

Nov 10 08:54:33 localhost kernel: Debug: sleeping function called from 
invalid context at mm/slab.c:2126
Nov 10 08:54:33 localhost kernel: in_atomic():1, irqs_disabled():0
Nov 10 08:54:33 localhost kernel:  [<c015c27e>] kmem_cache_alloc+0x3c/0x49
Nov 10 08:54:33 localhost kernel:  [<c0301b02>] alloc_skb+0x14/0xc1
Nov 10 08:54:33 localhost kernel:  [<cc8d3056>] rcp_match+0x0/0x1ef [rd]
Nov 10 08:54:33 localhost kernel:  [<cc8d3077>] rcp_match+0x21/0x1ef [rd]
Nov 10 08:54:33 localhost kernel:  [<c012c9ae>] cascade+0x21/0x3b
Nov 10 08:54:33 localhost kernel:  [<cc8d3056>] rcp_match+0x0/0x1ef [rd]
Nov 10 08:54:33 localhost kernel:  [<c012cf73>] 
run_timer_softirq+0x10b/0x472
Nov 10 08:54:33 localhost kernel:  [<c0103c0e>] common_interrupt+0x1a/0x20
Nov 10 08:54:33 localhost kernel:  [<c01282de>] __do_softirq+0x3e/0x8a
Nov 10 08:54:33 localhost kernel:  [<c0105c29>] do_softirq+0x3e/0x42
Nov 10 08:54:33 localhost kernel:  =======================
Nov 10 08:54:33 localhost kernel:  [<c0105b24>] do_IRQ+0x51/0x82
Nov 10 08:54:33 localhost kernel:  [<c0105b24>] do_IRQ+0x51/0x82
Nov 10 08:54:33 localhost kernel:  [<c0103c0e>] common_interrupt+0x1a/0x20
Nov 10 08:54:33 localhost kernel:  [<c010101a>] default_idle+0x0/0x29
Nov 10 08:54:33 localhost kernel:  [<c0101040>] default_idle+0x26/0x29
Nov 10 08:54:33 localhost kernel:  [<c01010a6>] cpu_idle+0x34/0x4c
Nov 10 08:54:33 localhost kernel:  [<c042472a>] start_kernel+0x15f/0x1b9
Nov 10 08:54:33 localhost kernel:  [<c04242fe>] unknown_bootoption+0x0/0x1cd


the timeout function is as below:

static void rcp_match(unsigned long dummy)
{
     struct sk_buff *skb;
     struct net_device *dev;
     struct rcpchdr *h;
     struct rcpopt *o;
     int res;
     static uint8_t broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

#if DEBUG_LEVEL < 1
     printk(KERN_WARNING "-> rcp_match\n");
#endif

     if (rcp_match_count++ >= RCP_MATCH_RETRY)
         goto stop;

     skb = alloc_skb(512, GFP_KERNEL);
     if (skb == NULL) {
         printk(KERN_WARNING "rcp_match: not enough sk_buff\n");
         goto stop;
     }

     dev = dev_get_by_name("eth0");
     if (dev == NULL) {
         printk(KERN_WARNING "rcp_match: net_device not found (%s)\n", 
"eth0");
         goto stop;
     }

     skb_reserve(skb, dev->hard_header_len);
     h = (struct rcpchdr *)skb_put(skb, sizeof (struct rcpchdr));
     h->h_type = RCPC_TYPE_QUERY;
     h->h_index = RCPC_INDEX_ALL;
     o = (struct rcpopt *)skb_put(skb, sizeof (struct rcpopt));
     memset(o, 8, sizeof(struct rcpopt));

     skb->protocol = htons(ETH_P_RADIO_CONTROL);
     skb->nh.raw = skb->data;
     skb->dev = dev;

     res = dev->hard_header(skb, dev, ETH_P_RADIO_CONTROL, broadcast, 
NULL, skb->len);
     if (res < 0) {
         dev_kfree_skb(skb);
         dev_put(dev);
         return;
     }
     res = dev_queue_xmit(skb);
     dev_put(dev);

     rcp_match_timer.expires = jiffies + RCP_MATCH_TIMEO;
     add_timer(&rcp_match_timer);
     return;

stop:
     del_timer_sync(&rcp_match_timer);
     rcp_match_count = 0;
     return;
}


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Debug: sleeping function called from invalid context at mm/slab.c:2126
@ 2005-11-10  3:07 Parag Warudkar
  2005-11-10  3:42 ` Tony
  0 siblings, 1 reply; 4+ messages in thread
From: Parag Warudkar @ 2005-11-10  3:07 UTC (permalink / raw)
  To: Tony, linux-kernel

> I'm writing a net_device driver. I want to send a packet when the timer 
> is out. I get the following warning. It seems that I should not call 
> alloc_skb. Can anyone tell me how to get rid of this? Thanks in advance.
>

You are calling alloc_skb which in turn calls kmem_cache_alloc in interrupt context where things can't sleep and kmem_cache_alloc can sleep.  The reason for this is that you are passing GFP_KERNEL to alloc_skb. Try passing GFP_ATOMIC instead.

Other alternative is to may be use a precreated pool of skbs - may be this can be done in driver init function or any other safe context. But I don't know how much feasible that is in your situation.

HTH
Parag



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Debug: sleeping function called from invalid context at mm/slab.c:2126
  2005-11-10  3:07 Debug: sleeping function called from invalid context at mm/slab.c:2126 Parag Warudkar
@ 2005-11-10  3:42 ` Tony
  2005-11-10 16:11   ` Parag Warudkar
  0 siblings, 1 reply; 4+ messages in thread
From: Tony @ 2005-11-10  3:42 UTC (permalink / raw)
  To: Parag Warudkar; +Cc: linux-kernel

Parag Warudkar wrote:
>>I'm writing a net_device driver. I want to send a packet when the timer 
>>is out. I get the following warning. It seems that I should not call 
>>alloc_skb. Can anyone tell me how to get rid of this? Thanks in advance.
>>
> 
> 
> You are calling alloc_skb which in turn calls kmem_cache_alloc in interrupt context where things can't sleep and kmem_cache_alloc can sleep.  The reason for this is that you are passing GFP_KERNEL to alloc_skb. Try passing GFP_ATOMIC instead.
> 
> Other alternative is to may be use a precreated pool of skbs - may be this can be done in driver init function or any other safe context. But I don't know how much feasible that is in your situation.
> 
> HTH
> Parag
> 
> 
> 
Thanks a lot. Another question.

My interface is a virtual interface which represent a radio connected to 
the host using ethernet NIC. I designed my own L2 protocol on top of 
802.3, which must be used, since the radio and the host are connected by 
ethernet.

Now, my radio_hard_header will only add my L2 header, and my 
radio_hard_start_xmit will do (simplified):
1) ajust the headroom space
     hh_len = LL_RESERVED_SPACE(bdev);
     if (unlikely(skb_headroom(skb) < hh_len && bdev->hard_header)) {
		struct sk_buff *skb2;

		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
		if (skb2 == NULL) {
             stats->tx_dropped++;
			dev_kfree_skb(skb);
			return 0;
		}
		if (skb->sk)
			skb_set_owner_w(skb2, skb->sk);
		dev_kfree_skb(skb);
		skb = skb2;
	}

2) call eth0->hard_header
3) skb->dev = eth0
    return dev_queue_xmit()

The problem is when system try to retransmit the packet, I add another 
ethernet header mistakenly.

I have two question:
1) I do not modify the skb passed to hard_start_xmit if 
skb_realloc_headroom is executed. only in this case the retransmission 
runs well. Is my understanding right?
2) Should I do this way or add the ethernet header in my 
radio_hard_header? If I choose the later, the problem will be how should 
I handle it when eth_hard_header return a negative number, when ARP is 
needed.

Thx

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Debug: sleeping function called from invalid context at mm/slab.c:2126
  2005-11-10  3:42 ` Tony
@ 2005-11-10 16:11   ` Parag Warudkar
  0 siblings, 0 replies; 4+ messages in thread
From: Parag Warudkar @ 2005-11-10 16:11 UTC (permalink / raw)
  To: Tony; +Cc: linux-kernel


On Nov 9, 2005, at 10:42 PM, Tony wrote:


> Thanks a lot. Another question.
>

I don't know the answer to that. You might find some help on the  
linux network development list - try asking

linux-netdev@vger.kernel.org

Parag

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-11-10 16:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-10  3:07 Debug: sleeping function called from invalid context at mm/slab.c:2126 Parag Warudkar
2005-11-10  3:42 ` Tony
2005-11-10 16:11   ` Parag Warudkar
  -- strict thread matches above, loose matches on Subject: below --
2005-11-10  2:35 Tony

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox