>From 1ca53f5b0576dcb0b5281bb673fcdf11f5c3a29e Mon Sep 17 00:00:00 2001
From: Vadim Rozenfeld <[email protected]>
Date: Mon, 16 May 2011 21:00:20 +0300
Subject: [COMMIT] [NetKvm] From: Yan Vugenfirer <[email protected]>
Fixing race condition in handling RX interrupts that
caused to halt network traffic during netperf tests.
---
NetKVM/Common/ParaNdis-Common.c | 41
++++++++++++++++++++++++++++++++++----
NetKVM/Common/kdebugprint.h | 8 +------
NetKVM/Common/ndis56common.h | 2 +
3 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/NetKVM/Common/ParaNdis-Common.c
b/NetKVM/Common/ParaNdis-Common.c
index a775c84..1a51474 100644
--- a/NetKVM/Common/ParaNdis-Common.c
+++ b/NetKVM/Common/ParaNdis-Common.c
@@ -1741,6 +1741,7 @@ static BOOLEAN
RestartQueueSynchronously(tSynchronizedContext *SyncContext)
{
b =
!pContext->NetSendQueue->vq_ops->restart(pContext->NetSendQueue);
}
+ ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x20,
SyncContext->Parameter, !b, 0);
return b;
}
/**********************************************************
@@ -1753,7 +1754,6 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER
*pContext)
ULONG stillRequiresProcessing = 0;
ULONG interruptSources;
DEBUG_ENTRY(5);
- ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)1, 0, 0, 0);
if (pContext->bEnableInterruptHandlingDPC)
{
InterlockedIncrement(&pContext->counterDPCInside);
@@ -1761,6 +1761,7 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER
*pContext)
{
InterlockedExchange(&pContext->bDPCInactive, 0);
interruptSources =
InterlockedExchange(&pContext->InterruptStatus,
0);
+ ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)1,
interruptSources,
0, 0);
if ((interruptSources & isControl) &&
pContext->bLinkDetectSupported)
{
ParaNdis_ReportLinkStatus(pContext);
@@ -1771,8 +1772,8 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER
*pContext)
}
if (interruptSources & isReceive)
{
- int nRestartResult = 2, nLoop = 0;
- while (nRestartResult)
+ int nRestartResult = 0, nLoop = 0;
+ do
{
UINT n;
LONG rxActive =
InterlockedIncrement(&pContext->dpcReceiveActive);
@@ -1783,22 +1784,33 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER
*pContext)
NdisAcquireSpinLock(&pContext->ReceiveLock);
nRestartResult =
ParaNdis_SynchronizeWithInterrupt(
pContext,
pContext->ulRxMessage, RestartQueueSynchronously,
isReceive);
+ ParaNdis_DebugHistory(pContext,
hopDPC, (PVOID)3, nRestartResult,
0, 0);
NdisReleaseSpinLock(&pContext->ReceiveLock);
DPrintf(nRestartResult ? 2 : 6,
("[%s] queue restarted%s",
__FUNCTION__, nRestartResult ? "(Rerun)" : "(Done)"));
++nLoop;
if (nLoop > MAX_RX_LOOPS)
{
DPrintf(0, ("[%s]
Breaking Rx loop on %d-th operation",
__FUNCTION__, nLoop));
+
ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)4,
nRestartResult, 0, 0);
break;
}
}
else
{
InterlockedDecrement(&pContext->dpcReceiveActive);
- nRestartResult = 0;
+ if (!nRestartResult)
+ {
+
NdisAcquireSpinLock(&pContext->ReceiveLock);
+ nRestartResult =
ParaNdis_SynchronizeWithInterrupt(
+ pContext,
pContext->ulRxMessage, RestartQueueSynchronously,
isReceive);
+
ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)5,
nRestartResult, 0, 0);
+
NdisReleaseSpinLock(&pContext->ReceiveLock);
+ }
DPrintf(1, ("[%s] Skip Rx
processing no.%d", __FUNCTION__,
rxActive));
+ break;
}
- }
+ } while (nRestartResult);
+
if (nRestartResult) stillRequiresProcessing |=
isReceive;
}
@@ -1878,6 +1890,24 @@ static BOOLEAN CheckRunningDpc(PARANDIS_ADAPTER
*pContext)
// todo - collect more and put out optionally
PrintStatistics(pContext);
}
+
+ if (pContext->Statistics.ifHCInOctets == pContext->Counters.prevIn)
+ {
+ pContext->Counters.nRxInactivity++;
+ if (pContext->Counters.nRxInactivity >= 10)
+ {
+//#define CRASH_ON_NO_RX
+#if defined(CRASH_ON_NO_RX)
+ ONPAUSECOMPLETEPROC proc =
(ONPAUSECOMPLETEPROC)(PVOID)1;
+ proc(pContext);
+#endif
+ }
+ }
+ else
+ {
+ pContext->Counters.nRxInactivity = 0;
+ pContext->Counters.prevIn = pContext->Statistics.ifHCInOctets;
+ }
return bReportHang;
}
@@ -2033,6 +2063,7 @@ VOID
ParaNdis_VirtIOEnableIrqSynchronized(PARANDIS_ADAPTER *pContext, ULONG
inte
pContext->NetSendQueue->vq_ops->enable_interrupt(pContext->NetSendQueue,
b);
if (interruptSource & isReceive)
pContext->NetReceiveQueue->vq_ops->enable_interrupt(pContext->NetReceiveQueue,
b);
+ ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x10, interruptSource,
b, 0);
}
/**********************************************************
diff --git a/NetKVM/Common/kdebugprint.h b/NetKVM/Common/kdebugprint.h
index c693664..cd89480 100644
--- a/NetKVM/Common/kdebugprint.h
+++ b/NetKVM/Common/kdebugprint.h
@@ -39,13 +39,7 @@ void _LogOutString(int level, const char *s);
#define WPP_INIT_TRACING(a,b)
#define WPP_CLEANUP(a)
-#define DPrintf(Level, Fmt) \
-{ \
- if (bDebugPrint && (Level) <= nDebugLevel) \
- { \
- pDebugPrint Fmt; \
- } \
-}
+#define DPrintf(Level, Fmt) { if ((Level) > nDebugLevel || !
bDebugPrint ) {} else { pDebugPrint Fmt; } }
#define DPrintfBypass(Level, Fmt) DPrintf(Level, Fmt)
diff --git a/NetKVM/Common/ndis56common.h b/NetKVM/Common/ndis56common.h
index 3f53758..f80c287 100644
--- a/NetKVM/Common/ndis56common.h
+++ b/NetKVM/Common/ndis56common.h
@@ -229,6 +229,8 @@ typedef struct _tagOurCounters
{
UINT nReusedRxBuffers;
UINT nPrintDiagnostic;
+ ULONG64 prevIn;
+ UINT nRxInactivity;
}tOurCounters;
typedef struct _tagMaxPacketSize
--
1.7.0.2.msysgit.0
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html