Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3851

kernel-2.6.18-194.11.1.el5.src.rpm

From: John W. Linville <linville@redhat.com>
Date: Thu, 30 Oct 2008 14:26:00 -0400
Subject: [wireless] iwlwifi: avoid sleep in softirq context
Message-id: 20081030182559.GA7282@redhat.com
O-Subject: [RHEL5.3 PATCH] iwlwifi: avoid sleep in softirq context
Bugzilla: 467831
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>

[<ffffffff8009544b>]msleep+0x21/0x2c
[<ffffffff8826006f>]:iwlcore:iwl_scan_cancel_timeout+0x37/0x82
[<ffffffff88279080>]:iwlagn:iwl4965_mac_update_tkip_key+0x46/0x105
[<ffffffff88214ff6>]:mac80211:ieee80211_tkip_decrypt_data+0x18c/0x20e
[<ffffffff8820caf4>]:mac80211:iee80211_crypt_tkip_decrypt+0xa5/0x161
[<ffffffff88217a9f>]:mac80211:iee80211_rx_h_decrypt+0x150/0x16e
[<ffffffff88216c8e>]:mac80211:__iee80211_rx_handle_packet+0x641/0x6ba
[<ffffffff88216453>]:mac80211:iee80211_invoke_rx_handlers+0x28/0x222
[<ffffffff88218130>]:mac80211:__iee80211_rx+0x46c/0x5a5
[<ffffffff882087c3>]:mac80211:__iee80211_tasklet_hanlder+0x61/0x10b
[<ffffffff8009218f>]tasklet_action+0x89/0xfd
[<ffffffff8001214f>]__do_softirq+0x89/0x133
[<ffffffff8005e2fc>]call_sofirq+0x1c/0x28
[<ffffffff8006cada>]do_sofirq+0x2c/0x85

Instead of calling iwl_scan_cancel_timeout, call iwl_scan_cancel and
simply return if it fails.  This merely causes us to decrypt a few
extra packets in software.

BZ467831

Tested by original bug reporter with success in avoiding the oops.

 drivers/net/wireless/iwlwifi/iwl-agn.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c8a16b2..4178018 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3264,7 +3264,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
 		return;
 	}
 
-	iwl_scan_cancel_timeout(priv, 100);
+	if (iwl_scan_cancel(priv)) {
+		/* cancel scan failed, just live w/ bad key and rely
+		   briefly on SW decrpyption */
+		return;
+	}
 
 	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
 	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);