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