rpms/kernel/F-10 iwl3945-add-debugging-for-wrong-command-queue.patch, NONE, 1.1 iwl3945-fix-rfkill-sw-and-hw-mishmash.patch, NONE, 1.1 iwl3945-release-resources-before-shutting-down.patch, NONE, 1.1 linux-2.6-iwlwifi_-fix-TX-queue-race.patch, NONE, 1.1 kernel.spec, 1.1399, 1.1400

Chuck Ebbert cebbert at fedoraproject.org
Tue Aug 18 15:51:44 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv15363

Modified Files:
	kernel.spec 
Added Files:
	iwl3945-add-debugging-for-wrong-command-queue.patch 
	iwl3945-fix-rfkill-sw-and-hw-mishmash.patch 
	iwl3945-release-resources-before-shutting-down.patch 
	linux-2.6-iwlwifi_-fix-TX-queue-race.patch 
Log Message:
Intel wireless fixes from Fedora 11:
   iwl3945-release-resources-before-shutting-down.patch
   iwl3945-add-debugging-for-wrong-command-queue.patch
   iwl3945-fix-rfkill-sw-and-hw-mishmash.patch
   linux-2.6-iwlwifi_-fix-TX-queue-race.patch

iwl3945-add-debugging-for-wrong-command-queue.patch:
 iwl3945-base.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- NEW FILE iwl3945-add-debugging-for-wrong-command-queue.patch ---
commit 638d0eb9197d1e285451f6594184fcfc9c2a5d44
Author: Chatre, Reinette <reinette.chatre at intel.com>
Date:   Mon Jan 19 15:30:24 2009 -0800

    iwl3945: add debugging for wrong command queue

    We encountered a problem related to this BUG and need to obtain more
    debugging information. See bug report at
    http://marc.info/?l=linux-wireless&m=123147215829854&w=2

    Signed-off-by: Reinette Chatre <reinette.chatre at intel.com>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>
---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 8cb0fa2..5011a79 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3349,7 +3349,14 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
 	int cmd_index;
 	struct iwl3945_cmd *cmd;
 
-	BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
+	if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
+		 "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
+		  txq_id, sequence,
+		  priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
+		  priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
+		/* Not in F11: iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32); */
+		return;
+	}
 
 	cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
 	cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-- 
1.6.2.5

_______________________________________________
Fedora-kernel-list mailing list
Fedora-kernel-list at redhat.com
https://www.redhat.com/mailman/listinfo/fedora-kernel-list


iwl3945-fix-rfkill-sw-and-hw-mishmash.patch:
 iwl3945-base.c |   18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

--- NEW FILE iwl3945-fix-rfkill-sw-and-hw-mishmash.patch ---
Disable SW switch regardless of HW switch state (we can only enable
radio when both SW and HW rfkill switches are off). Report to rfkill
subsystem SW switch state before HW switch state to move rfkill subsystem
to SOFT_BLOCK rather than HARD_BLOCK, otherwise in some conditions we
would not be able to turn radio back on.
---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5011a79..6065921 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8216,7 +8216,8 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
 	case RFKILL_STATE_UNBLOCKED:
 		if (iwl3945_is_rfkill_hw(priv)) {
 			err = -EBUSY;
-			goto out_unlock;
+			/* pass error to rfkill core to make it state HARD
+			 * BLOCKED and disable software kill switch */
 		}
 		iwl3945_radio_kill_sw(priv, 0);
 		break;
@@ -8227,9 +8228,8 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
 		IWL_WARNING("we received unexpected RFKILL state %d\n", state);
 		break;
 	}
-out_unlock:
-	mutex_unlock(&priv->mutex);
 
+	mutex_unlock(&priv->mutex);
 	return err;
 }
 
@@ -8291,15 +8291,12 @@ void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
 	if (!priv->rfkill)
 		return;
 
-	if (iwl3945_is_rfkill_hw(priv)) {
+	if (iwl3945_is_rfkill_sw(priv))
+		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+	else if (iwl3945_is_rfkill_hw(priv))
 		rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
-		return;
-	}
-
-	if (!iwl3945_is_rfkill_sw(priv))
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
 	else
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
 }
 #endif
 
-- 
1.6.2.5

_______________________________________________
Fedora-kernel-list mailing list
Fedora-kernel-list at redhat.com
https://www.redhat.com/mailman/listinfo/fedora-kernel-list


iwl3945-release-resources-before-shutting-down.patch:
 iwl3945-base.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- NEW FILE iwl3945-release-resources-before-shutting-down.patch ---
commit d552bfb65241a35d48e44ddb0d27e0454f579ab4
Author: Kolekar, Abhijeet <abhijeet.kolekar at intel.com>
Date:   Fri Dec 19 10:37:41 2008 +0800

    iwl3945: release resources before shutting down

    Release resource before shutting down and notify upper stack.

    Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar at intel.com>
    Signed-off-by: Zhu Yi <yi.zhu at intel.com>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>
---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 22e7e99..8cb0fa2 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8096,7 +8096,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 
 	set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	iwl3945_down(priv);
+	if (priv->mac80211_registered) {
+		ieee80211_unregister_hw(priv->hw);
+		priv->mac80211_registered = 0;
+	} else {
+		iwl3945_down(priv);
+	}
 
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
@@ -8121,9 +8126,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	iwl3945_unset_hw_setting(priv);
 	iwl3945_clear_stations_table(priv);
 
-	if (priv->mac80211_registered)
-		ieee80211_unregister_hw(priv->hw);
-
 	/*netif_stop_queue(dev); */
 	flush_workqueue(priv->workqueue);
 
-- 
1.6.2.5

_______________________________________________
Fedora-kernel-list mailing list
Fedora-kernel-list at redhat.com
https://www.redhat.com/mailman/listinfo/fedora-kernel-list


linux-2.6-iwlwifi_-fix-TX-queue-race.patch:
 iwl-tx.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

--- NEW FILE linux-2.6-iwlwifi_-fix-TX-queue-race.patch ---
Backport of the following upstream commit...

commit 3995bd9332a51b626237d6671cfeb7235e6c1305
Author: Johannes Berg <johannes at sipsolutions.net>
Date:   Fri Jul 24 11:13:14 2009 -0700

    iwlwifi: fix TX queue race
    
    I had a problem on 4965 hardware (well, probably other hardware too,
    but others don't survive my stress testing right now, unfortunately)
    where the driver was sending invalid commands to the device, but no
    such thing could be seen from the driver's point of view. I could
    reproduce this fairly easily by sending multiple TCP streams with
    iperf on different TIDs, though sometimes a single iperf stream was
    sufficient. It even happened with a single core, but I have forced
    preemption turned on.
    
    The culprit was a queue overrun, where we advanced the queue's write
    pointer over the read pointer. After careful analysis I've come to
    the conclusion that the cause is a race condition between iwlwifi
    and mac80211.
    
    mac80211, of course, checks whether the queue is stopped, before
    transmitting a frame. This effectively looks like this:
    
            lock(queues)
            if (stopped(queue)) {
                    unlock(queues)
                    return busy;
    	}
            unlock(queues)
            ...             <-- this place will be important
    			    there is some more code here
            drv_tx(frame)
    
    The driver, on the other hand, can stop and start queues, which does
    
            lock(queues)
            mark_running/stopped(queue)
            unlock(queues)
    
    	[if marked running: wake up tasklet to send pending frames]
    
    Now, however, once the driver starts the queue, mac80211 can see that
    and end up at the marked place above, at which point for some reason the
    driver seems to stop the queue again (I don't understand that) and then
    we end up transmitting while the queue is actually full.
    
    Now, this shouldn't actually matter much, but for some reason I've seen
    it happen multiple times in a row and the queue actually overflows, at
    which point the queue bites itself in the tail and things go completely
    wrong.
    
    This patch fixes this by just dropping the packet should this have
    happened, and making the lock in iwlwifi cover everything so iwlwifi
    can't race against itself (dropping the lock there might make it more
    likely, but it did seem to happen without that too).
    
    Since we can't hold the lock across drv_tx() above, I see no way to fix
    this in mac80211, but I also don't understand why I haven't seen this
    before -- maybe I just never stress tested it this badly.
    
    With this patch, the device has survived many minutes of simultanously
    sending two iperf streams on different TIDs with combined throughput
    of about 60 Mbps.
    
    Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
    Signed-off-by: Reinette Chatre <reinette.chatre at intel.com>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>

diff -up linux-2.6.29.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c.orig linux-2.6.29.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c
--- linux-2.6.29.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c.orig	2009-03-23 19:12:14.000000000 -0400
+++ linux-2.6.29.noarch/drivers/net/wireless/iwlwifi/iwl-tx.c	2009-08-12 11:56:04.000000000 -0400
@@ -876,8 +876,6 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 		goto drop_unlock;
 	}
 
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	hdr_len = ieee80211_hdrlen(fc);
 
 	/* Find (or create) index into station table for destination station */
@@ -885,7 +883,7 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 	if (sta_id == IWL_INVALID_STATION) {
 		IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
-		goto drop;
+		goto drop_unlock;
 	}
 
 	IWL_DEBUG_TX("station Id %d\n", sta_id);
@@ -904,14 +902,17 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 		/* aggregation is on for this <sta,tid> */
 		if (info->flags & IEEE80211_TX_CTL_AMPDU)
 			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
-		priv->stations[sta_id].tid[tid].tfds_in_queue++;
 	}
 
 	txq = &priv->txq[txq_id];
 	q = &txq->q;
 	txq->swq_id = swq_id;
 
-	spin_lock_irqsave(&priv->lock, flags);
+	if (unlikely(iwl_queue_space(q) < q->high_mark))
+		goto drop_unlock;
+
+	if (ieee80211_is_data_qos(fc))
+		priv->stations[sta_id].tid[tid].tfds_in_queue++;
 
 	/* Set up first empty TFD within this queue's circular TFD buffer */
 	tfd = &txq->tfds[q->write_ptr];
@@ -1043,7 +1044,6 @@ int iwl_tx_skb(struct iwl_priv *priv, st
 
 drop_unlock:
 	spin_unlock_irqrestore(&priv->lock, flags);
-drop:
 	return -1;
 }
 EXPORT_SYMBOL(iwl_tx_skb);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-10/kernel.spec,v
retrieving revision 1.1399
retrieving revision 1.1400
diff -u -p -r1.1399 -r1.1400
--- kernel.spec	17 Aug 2009 13:57:27 -0000	1.1399
+++ kernel.spec	18 Aug 2009 15:51:44 -0000	1.1400
@@ -664,6 +664,10 @@ Patch684: linux-2.6-iwlagn-fix-hw-rfkill
 Patch685: linux-2.6-iwl3945-use-cancel_delayed_work_sync-to-cancel-rfkill_poll.patch
 Patch686: linux-2.6-mac80211-fix-beacon-loss-detection-after-scan.patch
 Patch687: mac80211-don-t-drop-nullfunc-frames-during-software.patch
+Patch690: iwl3945-release-resources-before-shutting-down.patch
+Patch691: iwl3945-add-debugging-for-wrong-command-queue.patch
+Patch692: iwl3945-fix-rfkill-sw-and-hw-mishmash.patch
+Patch693: linux-2.6-iwlwifi_-fix-TX-queue-race.patch
 
 Patch1000: linux-2.6-neigh_-fix-state-transition-INCOMPLETE-_FAILED-via-Netlink-request.patch
 
@@ -1333,6 +1337,13 @@ ApplyPatch linux-2.6-mac80211-fix-beacon
 
 ApplyPatch mac80211-don-t-drop-nullfunc-frames-during-software.patch
 
+ApplyPatch iwl3945-release-resources-before-shutting-down.patch
+ApplyPatch iwl3945-add-debugging-for-wrong-command-queue.patch
+ApplyPatch iwl3945-fix-rfkill-sw-and-hw-mishmash.patch
+
+# iwlwifi: fix TX queue race
+ApplyPatch linux-2.6-iwlwifi_-fix-TX-queue-race.patch
+
 # neigh: fix state transition INCOMPLETE->FAILED via Netlink request
 ApplyPatch linux-2.6-neigh_-fix-state-transition-INCOMPLETE-_FAILED-via-Netlink-request.patch
 
@@ -2004,6 +2015,13 @@ fi
 %kernel_variant_files -k vmlinux %{with_kdump} kdump
 
 %changelog
+* Tue Aug 18 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.29.6-99
+- Intel wireless fixes from Fedora 11:
+   iwl3945-release-resources-before-shutting-down.patch
+   iwl3945-add-debugging-for-wrong-command-queue.patch
+   iwl3945-fix-rfkill-sw-and-hw-mishmash.patch
+   linux-2.6-iwlwifi_-fix-TX-queue-race.patch
+
 * Mon Aug 17 2009 Jarod Wilson <jarod at redhat.com> 2.6.29.6-99
 - Fix flub in prior lirc patch update that resulted in no lirc
   drivers getting built




More information about the fedora-extras-commits mailing list