From patchwork Tue Feb 12 21:19:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [3.5.y.z, extended, stable] Patch "rtlwifi: Fix scheduling while atomic bug" has been added to staging queue Date: Tue, 12 Feb 2013 11:19:19 -0000 From: Herton Ronaldo Krzesinski X-Patchwork-Id: 219985 Message-Id: <1360703959-19041-1-git-send-email-herton.krzesinski@canonical.com> To: Larry Finger Cc: kernel-team@lists.ubuntu.com, Nathaniel Doherty , Stanislaw Gruszka This is a note to let you know that I have just added a patch titled rtlwifi: Fix scheduling while atomic bug to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.5.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Herton ------ >From 5d98f4488f3101f466ed8746c63fae2154c448c7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 2 Feb 2013 15:55:00 -0600 Subject: [PATCH] rtlwifi: Fix scheduling while atomic bug commit a5ffbe0a1993a27072742ef7db6cf9839956fce9 upstream. Kernel commits 41affd5 and 6539306 changed the locking in rtl_lps_leave() from a spinlock to a mutex by doing the calls indirectly from a work queue to reduce the time that interrupts were disabled. This change was fine for most systems; however a scheduling while atomic bug was reported in https://bugzilla.redhat.com/show_bug.cgi?id=903881. The backtrace indicates that routine rtl_is_special(), which calls rtl_lps_leave() in three places was entered in atomic context. These direct calls are replaced by putting a request on the appropriate work queue. Signed-off-by: Larry Finger Reported-and-tested-by: Nathaniel Doherty Cc: Nathaniel Doherty Cc: Stanislaw Gruszka Signed-off-by: John W. Linville Signed-off-by: Herton Ronaldo Krzesinski --- drivers/net/wireless/rtlwifi/base.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) -- 1.7.9.5 diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index f4c852c..4110a6d 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -980,7 +980,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) is_tx ? "Tx" : "Rx"); if (is_tx) { - rtl_lps_leave(hw); + schedule_work(&rtlpriv-> + works.lps_leave_work); ppsc->last_delaylps_stamp_jiffies = jiffies; } @@ -990,7 +991,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) } } else if (ETH_P_ARP == ether_type) { if (is_tx) { - rtl_lps_leave(hw); + schedule_work(&rtlpriv->works.lps_leave_work); ppsc->last_delaylps_stamp_jiffies = jiffies; } @@ -1000,7 +1001,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { - rtl_lps_leave(hw); + schedule_work(&rtlpriv->works.lps_leave_work); ppsc->last_delaylps_stamp_jiffies = jiffies; }