r59 - in unstable/rt2500/debian: . patches
benh at alioth.debian.org
benh at alioth.debian.org
Sun Oct 14 20:53:30 UTC 2007
Author: benh
Date: 2007-10-14 20:53:30 +0000 (Sun, 14 Oct 2007)
New Revision: 59
Added:
unstable/rt2500/debian/patches/004_fix_mlme_queue_locking.diff
unstable/rt2500/debian/patches/005_fix_error_rate_vars.diff
Modified:
unstable/rt2500/debian/changelog
unstable/rt2500/debian/patches/series
Log:
Added some bug fix patches.
Modified: unstable/rt2500/debian/changelog
===================================================================
--- unstable/rt2500/debian/changelog 2007-10-14 19:23:30 UTC (rev 58)
+++ unstable/rt2500/debian/changelog 2007-10-14 20:53:30 UTC (rev 59)
@@ -1,8 +1,12 @@
-rt2500 (1:1.1.0-b4+cvs20070924-1) UNRELEASED; urgency=low
+rt2500 (1:1.1.0-b4+cvs20070924-1) unstable; urgency=low
* New CVS snapshot
+ * Fixed some race conditions in processing of queued work, with help
+ from Bryan Batten (004_fix_mlme_queue_locking.diff)
+ * Fixed sharing of error rate variables between interfaces
+ (005_fix_error_rate_vars.diff)
- -- Ben Hutchings <ben at decadent.org.uk> Sun, 30 Sep 2007 03:00:51 +0100
+ -- Ben Hutchings <ben at decadent.org.uk> Sun, 14 Oct 2007 21:52:44 +0100
rt2500 (1:1.1.0-b4-4) unstable; urgency=low
Added: unstable/rt2500/debian/patches/004_fix_mlme_queue_locking.diff
===================================================================
--- unstable/rt2500/debian/patches/004_fix_mlme_queue_locking.diff (rev 0)
+++ unstable/rt2500/debian/patches/004_fix_mlme_queue_locking.diff 2007-10-14 20:53:30 UTC (rev 59)
@@ -0,0 +1,263 @@
+--- rt2500.orig/Module/mlme.c
++++ rt2500/Module/mlme.c
+@@ -42,6 +42,8 @@
+ #include "rt_config.h"
+ #include <stdarg.h>
+
++#include <asm/system.h>
++
+ // e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
+ // this value, then it's quaranteed capable of operating in 36 mbps TX rate in
+ // clean environment.
+@@ -289,7 +291,6 @@
+ do
+ {
+ pAd->Mlme.Running = FALSE;
+- spin_lock_init(&pAd->Mlme.TaskLock);
+
+ // initialize the two tables
+ // MacTableInit(pAd);
+@@ -356,34 +357,27 @@
+ MLME_QUEUE_ELEM *Elem = NULL;
+ unsigned long flags;
+
+- // Only accept MLME and Frame from peer side, no other (control/data) frame should
+- // get into this state machine
++ // Only accept MLME and Frame from peer side, no other (control/data)
++ // frame should get into this state machine
+
+- spin_lock_irqsave(&pAd->Mlme.TaskLock, flags);
++ // We fix the multiple context service drop problem identified by
++ // Ben Hutchings in an SMP- safe way by combining TaskLock and Queue.Lock
++ // per his suggestion.
++ spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
+ if(pAd->Mlme.Running)
+ {
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock, flags);
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+ return;
+ }
+- else
+- {
+- pAd->Mlme.Running = TRUE;
+- }
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock, flags);
+-
+- while (TRUE) {
+- spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
+- if (!MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+- spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+- break;
+- }
+- spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
++ pAd->Mlme.Running = TRUE;
+
+- if (pAd->PortCfg.BssType == BSS_MONITOR)
+- continue;
++ // If there's a bubble, wait for it to collapse before proceeding.
++ while (MlmeGetHead(&pAd->Mlme.Queue, &Elem) &&
++ (smp_read_barrier_depends(), Elem->Occupied)) {
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+
+ //From message type, determine which state machine I should drive
+- switch (Elem->Machine)
++ if (pAd->PortCfg.BssType != BSS_MONITOR) switch (Elem->Machine)
+ {
+ case ASSOC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
+@@ -404,18 +398,19 @@
+ StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
+ break;
+ default:
+- DBGPRINT(RT_DEBUG_TRACE, "ERROR: Illegal machine in MlmeHandler()\n");
++ DBGPRINT(RT_DEBUG_ERROR,
++ "ERROR: Illegal machine in MlmeHandler()\n");
+ break;
+ } // end of switch
+
+ // free MLME element
+- Elem->Occupied = FALSE;
+- Elem->MsgLen = 0;
++ smp_mb();
++ Elem->Occupied = FALSE; // sic - bb
++ spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
++ MlmeDequeue(&pAd->Mlme.Queue);
+ }
+-
+- spin_lock_irqsave(&pAd->Mlme.TaskLock,flags);
+ pAd->Mlme.Running = FALSE;
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock,flags);
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock,flags);
+ }
+
+ /*
+@@ -491,7 +486,6 @@
+ StateMachineDestroy(&pAd->Mlme.SyncMachine);
+ // StateMachineDestroy(&pAd->Mlme.CntlMachine);
+ //NdisFreeSpinLock(&pAd->Mlme.Queue.Lock);
+- //NdisFreeSpinLock(&pAd->Mlme.TaskLock);
+ // NdisFreeSpinLock(&pAd->PortCfg.MacTab.Lock);
+
+ MlmeFreeMemoryHandler(pAd); //Free MLME memory handler
+@@ -2341,18 +2335,32 @@
+ printk(KERN_ERR DRV_NAME "MlmeEnqueue full, msg dropped and may corrupt MLME\n");
+ return FALSE;
+ }
++ // If another context preempts us, it uses the next element - sic. bb
+ Tail = Queue->Tail++;
+ Queue->Tail %= MAX_LEN_OF_MLME_QUEUE;
+ Queue->Num++;
++
++ // We guard against Ben Hutchings' incomplete queue element problem by not
++ // setting the Occupied flag until the memcpy is done. The ocurrence of a
++ // refresh cycle during a copy can stretch the time by up to 100 usec
++ // (well, quite a few usec, anyway); not good when interrupts are disabled.
++ // Note that this can leave a bubble in the queue, but it will have
++ // disappeared by the time this thread gets around to calling MlmeHandler.
++ // All items will be handled in their proper order, but possibly not in the
++ // context in which they were added. - bb
+ spin_unlock_irqrestore(&Queue->Lock, flags);
+ DBGPRINT(RT_DEBUG_INFO, "MlmeEnqueue, num=%d\n",Queue->Num);
+
+- Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+ if (Msg != NULL)
+ memcpy(Queue->Entry[Tail].Msg, Msg, MsgLen);
++
++ //MlmeHandler will stop when it finds this false.
++ smp_wmb();
++ Queue->Entry[Tail].Occupied = TRUE;
++
+ return TRUE;
+ }
+
+@@ -2409,7 +2417,7 @@
+ DBGPRINT(RT_DEBUG_INFO, "MlmeEnqueueForRecv, num=%d\n",Queue->Num);
+
+ // OK, we got all the informations, it is time to put things into queue
+- Queue->Entry[Tail].Occupied = TRUE;
++ // See MlmeEnqueue note for use of Occupied flag.
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+@@ -2419,13 +2427,15 @@
+ Queue->Entry[Tail].Noise = (Noise > BBP_R17_DYNAMIC_UP_BOUND) ? BBP_R17_DYNAMIC_UP_BOUND : ((ULONG) Noise);
+ if (Msg != NULL)
+ memcpy(Queue->Entry[Tail].Msg, Msg, MsgLen);
++ smp_wmb();
++ Queue->Entry[Tail].Occupied = TRUE;
+
+ MlmeHandler(pAd);
+
+ return TRUE;
+ }
+
+-/*! \brief Dequeue a message from the MLME Queue
++/*! \brief Get the first message from the MLME Queue
+ * WARNING: Must be call with Mlme.Queue.Lock held
+ * \param *Queue The MLME Queue
+ * \param *Elem The message dequeued from MLME Queue
+@@ -2433,14 +2443,29 @@
+ * \pre
+ * \post
+ */
+-BOOLEAN MlmeDequeue(
++BOOLEAN MlmeGetHead(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem)
+ {
+ if (Queue->Num == 0)
+ return FALSE;
+- *Elem = &Queue->Entry[Queue->Head++];
+- Queue->Head %= MAX_LEN_OF_MLME_QUEUE;
++ *Elem = &Queue->Entry[Queue->Head];
++ return TRUE;
++}
++
++/*! \brief Remove the first message from the MLME Queue
++ * WARNING: Must be call with Mlme.Queue.Lock held
++ * \param *Queue The MLME Queue
++ * \return TRUE if a message was removed, FALSE if the queue was empty
++ * \pre
++ * \post
++ */
++BOOLEAN MlmeDequeue(
++ IN MLME_QUEUE *Queue)
++{
++ if (Queue->Num == 0)
++ return FALSE;
++ Queue->Head = (Queue->Head + 1) % MAX_LEN_OF_MLME_QUEUE;
+ Queue->Num--;
+ DBGPRINT(RT_DEBUG_INFO, "MlmeDequeue, num=%d\n",Queue->Num);
+
+@@ -2460,25 +2485,24 @@
+ // Continue the reset procedure...
+ }
+
+- spin_lock_irqsave(&pAd->Mlme.TaskLock, flags);
++ spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
+ if(pAd->Mlme.Running)
+ {
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock, flags);
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+ return;
+ }
+ else
+ {
+ pAd->Mlme.Running = TRUE;
+ }
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock, flags);
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+
+ // Remove all Mlme queues elements
+ spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
+- while (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+- // free MLME element
++ while (MlmeGetHead(&pAd->Mlme.Queue, &Elem)) {
++ MlmeDequeue(&pAd->Mlme.Queue);
+ Elem->Occupied = FALSE;
+- Elem->MsgLen = 0;
+- }
++ }
+ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+
+ // Cancel all timer events
+@@ -2507,9 +2531,9 @@
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+
+ // Remove running state
+- spin_lock_irqsave(&pAd->Mlme.TaskLock, flags);
++ spin_lock_irqsave(&pAd->Mlme.Queue.Lock, flags);
+ pAd->Mlme.Running = FALSE;
+- spin_unlock_irqrestore(&pAd->Mlme.TaskLock, flags);
++ spin_unlock_irqrestore(&pAd->Mlme.Queue.Lock, flags);
+ }
+
+ /*! \brief The destructor of MLME Queue
+--- rt2500.orig/Module/rtmp.h
++++ rt2500/Module/rtmp.h
+@@ -773,7 +773,6 @@
+ ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
+
+ BOOLEAN Running;
+- spinlock_t TaskLock;
+ MLME_QUEUE Queue;
+
+ UINT ShiftReg;
+@@ -1573,10 +1572,13 @@
+ IN ULONG MsgLen,
+ IN PVOID Msg);
+
+-BOOLEAN MlmeDequeue(
++BOOLEAN MlmeGetHead(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem);
+
++BOOLEAN MlmeDequeue(
++ IN MLME_QUEUE *Queue);
++
+ VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd);
+
Added: unstable/rt2500/debian/patches/005_fix_error_rate_vars.diff
===================================================================
--- unstable/rt2500/debian/patches/005_fix_error_rate_vars.diff (rev 0)
+++ unstable/rt2500/debian/patches/005_fix_error_rate_vars.diff 2007-10-14 20:53:30 UTC (rev 59)
@@ -0,0 +1,45 @@
+--- rt2500.orig/Module/mlme.c
++++ rt2500/Module/mlme.c
+@@ -901,7 +901,6 @@
+ {
+ ULONG TxFailCnt, TxOkCnt, TxRetryCnt, TxCnt;
+ ULONG RxFailCnt, RxOkCnt, RxCnt, Cnt0, OldFcsCount;
+- static ULONG TxPER = 0, TxPRR = 0, RxPER = 0;
+
+ //
+ // monitor TX counters change for the past period
+@@ -914,12 +913,6 @@
+ pAd->Mlme.PrevWlanCounters.TransmittedFragmentCount.vv.LowPart;
+ TxCnt = TxOkCnt + TxFailCnt;
+
+- if (TxCnt > 5) // if too few TX samples, skip TX related statistics
+- {
+- TxPER = (TxFailCnt * 100) / TxCnt;
+- TxPRR = ((TxRetryCnt + TxFailCnt) * 100) / TxCnt;
+- }
+-
+ //
+ // calculate RX PER
+ //
+@@ -943,8 +936,6 @@
+ pAd->Mlme.PrevWlanCounters.FCSErrorCount.vv.LowPart;
+ RxCnt = RxOkCnt + RxFailCnt;
+
+- if (RxCnt > 5)
+- RxPER = (RxFailCnt * 100) / RxCnt;
+ //printk("!! WiFi: Ok: %d, Fail: %d, PER: %d\n", RxOkCnt, RxFailCnt, RxPER);
+ //
+ // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+@@ -966,8 +957,11 @@
+ LinkDown(pAd);
+ }
+ }
+- else
++ else if (TxCnt > 5 && RxCnt > 5)
+ {
++ ULONG TxPRR = ((TxRetryCnt + TxFailCnt) * 100) / TxCnt;
++ ULONG RxPER = (RxFailCnt * 100) / RxCnt;
++
+ // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
+ pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * pAd->PortCfg.LastRssi +
+ TX_WEIGHTING * (100 - TxPRR) +
Modified: unstable/rt2500/debian/patches/series
===================================================================
--- unstable/rt2500/debian/patches/series 2007-10-14 19:23:30 UTC (rev 58)
+++ unstable/rt2500/debian/patches/series 2007-10-14 20:53:30 UTC (rev 59)
@@ -1 +1,3 @@
000_if_name.diff -p0
+004_fix_mlme_queue_locking.diff
+005_fix_error_rate_vars.diff
More information about the Pkg-ralink-commits
mailing list