~ahs3/kvm-guest-drivers-windows/upstream-github

« back to all changes in this revision

Viewing changes to NetKVM/Common/ParaNdis-Common.c

  • Committer: Yan Vugenfirer
  • Date: 2011-03-08 15:35:50 UTC
  • Revision ID: git-v1:ce0e25177076cd642170232aba71b011ed1a2883
[NetKVM] Fixing race condition in handling RX interrupts that caused to halt network traffic during netperf tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1741
1741
        {
1742
1742
                b = !pContext->NetSendQueue->vq_ops->restart(pContext->NetSendQueue);
1743
1743
        }
 
1744
        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x20, SyncContext->Parameter, !b, 0);
1744
1745
        return b;
1745
1746
}
1746
1747
/**********************************************************
1753
1754
        ULONG stillRequiresProcessing = 0;
1754
1755
        ULONG interruptSources;
1755
1756
        DEBUG_ENTRY(5);
1756
 
        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)1, 0, 0, 0);
1757
1757
        if (pContext->bEnableInterruptHandlingDPC)      
1758
1758
        {
1759
1759
                InterlockedIncrement(&pContext->counterDPCInside);
1761
1761
                {
1762
1762
                        InterlockedExchange(&pContext->bDPCInactive, 0);
1763
1763
                        interruptSources = InterlockedExchange(&pContext->InterruptStatus, 0);
 
1764
                        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)1, interruptSources, 0, 0);
1764
1765
                        if ((interruptSources & isControl) && pContext->bLinkDetectSupported)
1765
1766
                        {
1766
1767
                                ParaNdis_ReportLinkStatus(pContext);
1771
1772
                        }
1772
1773
                        if (interruptSources & isReceive)
1773
1774
                        {
1774
 
                                int nRestartResult = 2, nLoop = 0;
1775
 
                                while (nRestartResult)
 
1775
                                int nRestartResult = 0, nLoop = 0;
 
1776
                                do
1776
1777
                                {
1777
1778
                                        UINT n;
1778
1779
                                        LONG rxActive = InterlockedIncrement(&pContext->dpcReceiveActive);
1783
1784
                                                NdisAcquireSpinLock(&pContext->ReceiveLock);
1784
1785
                                                nRestartResult = ParaNdis_SynchronizeWithInterrupt(
1785
1786
                                                        pContext, pContext->ulRxMessage, RestartQueueSynchronously, isReceive); 
 
1787
                                                ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)3, nRestartResult, 0, 0);
1786
1788
                                                NdisReleaseSpinLock(&pContext->ReceiveLock);
1787
1789
                                                DPrintf(nRestartResult ? 2 : 6, ("[%s] queue restarted%s", __FUNCTION__, nRestartResult ? "(Rerun)" : "(Done)"));
1788
1790
                                                ++nLoop;
1789
1791
                                                if (nLoop > MAX_RX_LOOPS)
1790
1792
                                                {
1791
1793
                                                        DPrintf(0, ("[%s] Breaking Rx loop on %d-th operation", __FUNCTION__, nLoop));
 
1794
                                                        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)4, nRestartResult, 0, 0);
1792
1795
                                                        break;
1793
1796
                                                }
1794
1797
                                        }
1795
1798
                                        else
1796
1799
                                        {
1797
1800
                                                InterlockedDecrement(&pContext->dpcReceiveActive);
1798
 
                                                nRestartResult = 0;
 
1801
                                                if (!nRestartResult)
 
1802
                                                {
 
1803
                                                        NdisAcquireSpinLock(&pContext->ReceiveLock);
 
1804
                                                        nRestartResult = ParaNdis_SynchronizeWithInterrupt(
 
1805
                                                                pContext, pContext->ulRxMessage, RestartQueueSynchronously, isReceive); 
 
1806
                                                        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)5, nRestartResult, 0, 0);
 
1807
                                                        NdisReleaseSpinLock(&pContext->ReceiveLock);
 
1808
                                                }
1799
1809
                                                DPrintf(1, ("[%s] Skip Rx processing no.%d", __FUNCTION__, rxActive));
 
1810
                                                break;
1800
1811
                                        }
1801
 
                                }
 
1812
                                } while (nRestartResult);
 
1813
 
1802
1814
                                if (nRestartResult) stillRequiresProcessing |= isReceive;
1803
1815
                        }
1804
1816
 
1878
1890
                // todo - collect more and put out optionally
1879
1891
                PrintStatistics(pContext);
1880
1892
        }
 
1893
        
 
1894
        if (pContext->Statistics.ifHCInOctets == pContext->Counters.prevIn)
 
1895
        {
 
1896
                pContext->Counters.nRxInactivity++;
 
1897
                if (pContext->Counters.nRxInactivity >= 10)
 
1898
                {
 
1899
//#define CRASH_ON_NO_RX
 
1900
#if defined(CRASH_ON_NO_RX) 
 
1901
                        ONPAUSECOMPLETEPROC proc = (ONPAUSECOMPLETEPROC)(PVOID)1;
 
1902
                        proc(pContext);
 
1903
#endif
 
1904
                }
 
1905
        }
 
1906
        else
 
1907
        {
 
1908
                pContext->Counters.nRxInactivity = 0;
 
1909
                pContext->Counters.prevIn = pContext->Statistics.ifHCInOctets;
 
1910
        }
1881
1911
        return bReportHang;
1882
1912
}
1883
1913
 
2033
2063
                pContext->NetSendQueue->vq_ops->enable_interrupt(pContext->NetSendQueue, b);
2034
2064
        if (interruptSource & isReceive)
2035
2065
                pContext->NetReceiveQueue->vq_ops->enable_interrupt(pContext->NetReceiveQueue, b);
 
2066
        ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x10, interruptSource, b, 0);
2036
2067
}
2037
2068
 
2038
2069
/**********************************************************