[COMMIT] [NetKvm] From: Yan Vugenfirer <yvugenfi@xxxxxxxxxx>

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 1ca53f5b0576dcb0b5281bb673fcdf11f5c3a29e Mon Sep 17 00:00:00 2001
From: Vadim Rozenfeld <vrozenfe@xxxxxxxxxx>
Date: Mon, 16 May 2011 21:00:20 +0300
Subject: [COMMIT] [NetKvm] From: Yan Vugenfirer <yvugenfi@xxxxxxxxxx>

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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM Development]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Walks]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux