Return-path: Received: from mail-fx0-f218.google.com ([209.85.220.218]:39686 "EHLO mail-fx0-f218.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751754AbZGFUBA convert rfc822-to-8bit (ORCPT ); Mon, 6 Jul 2009 16:01:00 -0400 Received: by fxm18 with SMTP id 18so4400592fxm.37 for ; Mon, 06 Jul 2009 13:01:02 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <4a524b55.wIWqgs5uHs2CpdJy%Larry.Finger@lwfinger.net> References: <4a524b55.wIWqgs5uHs2CpdJy%Larry.Finger@lwfinger.net> Date: Mon, 6 Jul 2009 22:01:01 +0200 Message-ID: <9c30dffe0907061301m5514212blda06267a996f9f4f@mail.gmail.com> Subject: Re: [PATCH] p54: Fix regression in 2.6.31-rcX since commit a1091aa - sleeping function called from invalid context From: Bjarke Istrup Pedersen To: linux-wireless@vger.kernel.org Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-wireless-owner@vger.kernel.org List-ID: 2009/7/6 Larry Finger : > Beginning with commit a1091aae19b1d9c85d91c86915a611387f67a26b entitled > "p54: Use SKB list handling helpers instead of by-hand code.", the following > appears in my logs whenever I try to use my p54usb wireless device: > > BUG: sleeping function called from invalid context at arch/x86/mm/fault.c:1085 > ?in_atomic(): 0, irqs_disabled(): 1, pid: 8538, name: modprobe > ?2 locks held by modprobe/8538: > ?#0: ?(&local->queue_stop_reason_lock){-.-...}, at: [] > ? ? ? ?ieee80211_stop_queues_by_reason+0x28/0x5e [mac80211] > ?#1: ?(&mm->mmap_sem){++++++}, at: [] do_page_fault+0xd2/0x1fe > ?irq event stamp: 25212 > ?hardirqs last ?enabled at (25211): [] _spin_unlock_irqrestore+0x3f/0x47 > ?hardirqs last disabled at (25212): [] _spin_lock_irqsave+0x17/0x4b > ?softirqs last ?enabled at (24064): [] sk_filter+0xba/0xc3 > ?softirqs last disabled at (24062): [] sk_filter+0x16/0xc3 > ?Pid: 8538, comm: modprobe Not tainted 2.6.30-rc6-Linus-00905-g46c3767-dirty #180 > ?Call Trace: > ?[] ? print_irqtrace_events+0xd0/0xd4 > ?[] __might_sleep+0xf4/0xf6 > ?[] do_page_fault+0x11c/0x1fe > ?[] ? _spin_unlock_irqrestore+0x3f/0x47 > ?[] page_fault+0x1f/0x30 > ?[] ? _spin_unlock_irqrestore+0x3f/0x47 > ?[] ? ieee80211_stop_queues_by_reason+0x28/0x5e [mac80211] > ?[] ? __ieee80211_stop_queue+0x36/0x82 [mac80211] > ?[] ? _spin_lock_irqsave+0x3f/0x4b > ?[] ieee80211_stop_queues_by_reason+0x3c/0x5e [mac80211] > ?[] ieee80211_stop_queues+0xb/0xd [mac80211] > ?[] p54_assign_address+0x164/0x1ec [p54common] > ?[] p54_alloc_skb+0xb6/0xd3 [p54common] > ... > > Reverting the hunk that affects p54_assign_address() fixes the problem. When I > tried to determine which change(s) caused the problem, the skb_peek_tail() > seemed to be the problem; however, the system would freeze. I was not able to > recover any log information. > > Signed-off-by: Larry Finger > --- > > diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c > index b618bd1..c5bc55a 100644 > --- a/drivers/net/wireless/p54/p54common.c > +++ b/drivers/net/wireless/p54/p54common.c > @@ -1164,21 +1164,23 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, > ? ? ? ? ? ? ? ?} > ? ? ? ?} > > - ? ? ? skb_queue_walk(&priv->tx_queue, entry) { > + ? ? ? entry = priv->tx_queue.next; > + ? ? ? while (left--) { > ? ? ? ? ? ? ? ?u32 hole_size; > ? ? ? ? ? ? ? ?info = IEEE80211_SKB_CB(entry); > ? ? ? ? ? ? ? ?range = (void *)info->rate_driver_data; > ? ? ? ? ? ? ? ?hole_size = range->start_addr - last_addr; > ? ? ? ? ? ? ? ?if (!target_skb && hole_size >= len) { > - ? ? ? ? ? ? ? ? ? ? ? target_skb = skb_queue_prev(&priv->tx_queue, entry); > + ? ? ? ? ? ? ? ? ? ? ? target_skb = entry->prev; > ? ? ? ? ? ? ? ? ? ? ? ?hole_size -= len; > ? ? ? ? ? ? ? ? ? ? ? ?target_addr = last_addr; > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?largest_hole = max(largest_hole, hole_size); > ? ? ? ? ? ? ? ?last_addr = range->end_addr; > + ? ? ? ? ? ? ? entry = entry->next; > ? ? ? ?} > ? ? ? ?if (!target_skb && priv->rx_end - last_addr >= len) { > - ? ? ? ? ? ? ? target_skb = skb_peek_tail(&priv->tx_queue); > + ? ? ? ? ? ? ? target_skb = priv->tx_queue.prev; > ? ? ? ? ? ? ? ?largest_hole = max(largest_hole, priv->rx_end - last_addr - len); > ? ? ? ? ? ? ? ?if (!skb_queue_empty(&priv->tx_queue)) { > ? ? ? ? ? ? ? ? ? ? ? ?info = IEEE80211_SKB_CB(target_skb); > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at ?http://vger.kernel.org/majordomo-info.html > Please read the FAQ at ?http://www.tux.org/lkml/ > I've been having this problem too. Just completed a bisect to track the commit causing the problem when this mail hit my inbox :-) The oops of it is logged it kerneloops here: http://kerneloops.org/guilty.php?guilty=__ieee80211_stop_queue&version=2.6.31-rc&start=2031616&end=2064383&class=oops Best regards, Bjarke Istrup Pedersen