staging: vt6656: lock changes: RXvMngWorkItem.
authorMalcolm Priestley <tvboxspy@gmail.com>
Thu, 15 May 2014 21:49:14 +0000 (22:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 May 2014 22:02:19 +0000 (15:02 -0700)
Narrow atomic locks in RXvMngWorkItem.

We must lock the DequeueRCB and RXvFreeRCB so that
they are in sync.

vMgrRxManagePacket can nolonger be atomically called.

There is no need for an overall lock.

Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/vt6656/dpc.c

index 4ccaa7e29a1c610c3e7681cf41d5ff6c84bd49f0..156399d93540bb314daa2bdb94a55ee027b54eba 100644 (file)
@@ -1363,34 +1363,43 @@ void RXvMngWorkItem(struct work_struct *work)
        struct vnt_rcb *pRCB = NULL;
        struct vnt_rx_mgmt *pRxPacket;
        int bReAllocSkb = false;
+       unsigned long flags;
 
        if (pDevice->Flags & fMP_DISCONNECTED)
                return;
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
 
-    spin_lock_irq(&pDevice->lock);
     while (pDevice->NumRecvMngList!=0)
     {
+       spin_lock_irqsave(&pDevice->lock, flags);
+
         pRCB = pDevice->FirstRecvMngList;
         pDevice->NumRecvMngList--;
         DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+
+       spin_unlock_irqrestore(&pDevice->lock, flags);
+
         if(!pRCB){
             break;
         }
         pRxPacket = &(pRCB->sMngPacket);
        vMgrRxManagePacket(pDevice, &pDevice->vnt_mgmt, pRxPacket);
         pRCB->Ref--;
-        if(pRCB->Ref == 0) {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
-            RXvFreeRCB(pRCB, bReAllocSkb);
-        } else {
+       if (pRCB->Ref == 0) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",
+                       pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+
+               spin_lock_irqsave(&pDevice->lock, flags);
+
+               RXvFreeRCB(pRCB, bReAllocSkb);
+
+               spin_unlock_irqrestore(&pDevice->lock, flags);
+       } else {
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
         }
     }
 
        pDevice->bIsRxMngWorkItemQueued = false;
-       spin_unlock_irq(&pDevice->lock);
-
 }