summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalcolm Priestley <tvboxspy@gmail.com>2014-05-15 22:49:14 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-15 15:02:19 -0700
commite03ce8393e41ddff574c95ac72378ed1f02cef54 (patch)
tree1862e93ff82bd39a99840e1291bb8c61cf78907e
parentd1d4120f7fab69b32d40780b766109d377d743a7 (diff)
downloadlinux-stable-e03ce8393e41ddff574c95ac72378ed1f02cef54.tar.gz
linux-stable-e03ce8393e41ddff574c95ac72378ed1f02cef54.tar.bz2
linux-stable-e03ce8393e41ddff574c95ac72378ed1f02cef54.zip
staging: vt6656: lock changes: RXvMngWorkItem.
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>
-rw-r--r--drivers/staging/vt6656/dpc.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 4ccaa7e29a1c..156399d93540 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -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);
-
}