diff --git a/NetKVM/Common/ParaNdis-RX.h b/NetKVM/Common/ParaNdis-RX.h index 07796c339..2e12e9ee7 100644 --- a/NetKVM/Common/ParaNdis-RX.h +++ b/NetKVM/Common/ParaNdis-RX.h @@ -40,6 +40,7 @@ class CParaNdisRX : public CParaNdisTemplatePath, public CNdisAlloca PARANDIS_RECEIVE_QUEUE &UnclassifiedPacketsQueue() { return m_UnclassifiedPacketsQueue; } UINT GetFreeRxBuffers() const { return m_NetNofReceiveBuffers; } + BOOLEAN AllocateMore(); private: /* list of Rx buffers available for data (under VIRTIO management) */ LIST_ENTRY m_NetReceiveBuffers; @@ -58,6 +59,7 @@ class CParaNdisRX : public CParaNdisTemplatePath, public CNdisAlloca private: int PrepareReceiveBuffers(); pRxNetDescriptor CreateRxDescriptorOnInit(); + void RecalculateLimits(); }; #ifdef PARANDIS_SUPPORT_RSS diff --git a/NetKVM/Common/ParaNdis-Util.h b/NetKVM/Common/ParaNdis-Util.h index e0e464799..b4c02914d 100644 --- a/NetKVM/Common/ParaNdis-Util.h +++ b/NetKVM/Common/ParaNdis-Util.h @@ -562,10 +562,9 @@ class CNdisSharedMemory : public CNdisAllocatable : m_DrvHandle(NULL) {} - bool Create(NDIS_HANDLE DrvHandle) + void Initialize(NDIS_HANDLE DrvHandle) { m_DrvHandle = DrvHandle; - return true; } ~CNdisSharedMemory(); @@ -849,3 +848,25 @@ void ParaNdis_CompleteNBLChainWithStatus(NDIS_HANDLE MiniportHandle, PNET_BUFFER ParaNdis_CompleteNBLChain(MiniportHandle, NBL, Flags); } + +static FORCEINLINE void UpdateTimestamp(ULONGLONG& Variable) +{ + LARGE_INTEGER li; + NdisGetCurrentSystemTime(&li); + Variable = li.QuadPart; +} + +class CSystemThread +{ +public: + bool Start(PVOID Context); + void Stop(); + CMutexProtectedAccess& PowerMutex() { return m_PowerMutex; } +private: + CNdisEvent m_Event; + CMutexProtectedAccess m_PowerMutex; + HANDLE m_hThread = NULL; + void ThreadProc(); + PVOID m_Context = NULL; + ULONGLONG m_StartTime = 0; +}; diff --git a/NetKVM/Common/ParaNdis-VirtQueue.h b/NetKVM/Common/ParaNdis-VirtQueue.h index 76a917cba..072aab020 100644 --- a/NetKVM/Common/ParaNdis-VirtQueue.h +++ b/NetKVM/Common/ParaNdis-VirtQueue.h @@ -31,13 +31,7 @@ class CTXHeaders CTXHeaders() {} - bool Create(NDIS_HANDLE DrvHandle, ULONG VirtioHdrSize) - { - m_VirtioHdrSize = VirtioHdrSize; - return m_HeadersBuffer.Create(DrvHandle); - } - - bool Allocate(); + void Initialize(ULONG VirtioHdrSize, const tCompletePhysicalAddress& Buffer); virtio_net_hdr *VirtioHeader() const { return static_cast(m_VirtioHeaderVA); } @@ -67,7 +61,7 @@ class CTXHeaders { return m_IPHeadersPA; } private: - CNdisSharedMemory m_HeadersBuffer; + tCompletePhysicalAddress m_HeadersBuffer; ULONG m_VirtioHdrSize = 0; PVOID m_VlanHeaderVA = nullptr; @@ -99,17 +93,30 @@ class CTXDescriptor : public CNdisAllocatable bool Indirect, bool AnyLayout) { - if (!m_Headers.Create(DrvHandle, VirtioHeaderSize)) - return false; - if (!m_IndirectArea.Create(DrvHandle)) + m_MemoryBuffer.Initialize(DrvHandle); + // allocate 8K buffer + if (!m_MemoryBuffer.Allocate(PAGE_SIZE * 2)) + { return false; + } m_VirtioSGL = VirtioSGL; m_VirtioSGLSize = VirtioSGLSize; m_Indirect = Indirect; m_AnyLayout = AnyLayout; - - return m_Headers.Allocate() && (!m_Indirect || m_IndirectArea.Allocate(PAGE_SIZE)); + // first 4K is for headers area + tCompletePhysicalAddress headers; + headers.Physical = m_MemoryBuffer.GetPA(); + headers.Virtual = m_MemoryBuffer.GetVA(); + headers.size = PAGE_SIZE; + m_Headers.Initialize(VirtioHeaderSize, headers); + + // second 4K is for indirect area + m_IndirectArea.Physical = m_MemoryBuffer.GetPA(); + m_IndirectArea.Physical.QuadPart += PAGE_SIZE; + m_IndirectArea.Virtual = RtlOffsetToPointer(m_MemoryBuffer.GetVA(), PAGE_SIZE); + m_IndirectArea.size = PAGE_SIZE; + return true; } SubmitTxPacketResult Enqueue(CTXVirtQueue *Queue, ULONG TotalDescriptors, ULONG FreeDescriptors); @@ -133,7 +140,8 @@ class CTXDescriptor : public CNdisAllocatable private: CTXHeaders m_Headers; - CNdisSharedMemory m_IndirectArea; + CNdisSharedMemory m_MemoryBuffer; + tCompletePhysicalAddress m_IndirectArea; bool m_Indirect = false; bool m_AnyLayout = false; diff --git a/NetKVM/Common/ParaNdis_Common.cpp b/NetKVM/Common/ParaNdis_Common.cpp index e2028fb59..8e22e87e4 100755 --- a/NetKVM/Common/ParaNdis_Common.cpp +++ b/NetKVM/Common/ParaNdis_Common.cpp @@ -94,6 +94,7 @@ typedef struct _tagConfigurationEntries tConfigurationEntry VlanId; tConfigurationEntry JumboPacket; tConfigurationEntry NumberOfHandledRXPacketsInDPC; + tConfigurationEntry FastInit; #if PARANDIS_SUPPORT_RSS tConfigurationEntry RSSOffloadSupported; tConfigurationEntry NumRSSQueues; @@ -133,6 +134,7 @@ static const tConfigurationEntries defaultConfiguration = { "VlanId", 0, 0, MAX_VLAN_ID}, { "*JumboPacket", 1514, 590, 65500}, { "NumberOfHandledRXPacketsInDPC", MAX_RX_LOOPS, 1, 10000}, + { "FastInit", 1, 0, 1}, #if PARANDIS_SUPPORT_RSS { "*RSS", 1, 0, 1}, { "*NumRssQueues", 16, 1, PARANDIS_RSS_MAX_RECEIVE_QUEUES}, @@ -270,6 +272,7 @@ static bool ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR pNewMACAddre GetConfigurationEntry(cfg, &pConfiguration->VlanId); GetConfigurationEntry(cfg, &pConfiguration->JumboPacket); GetConfigurationEntry(cfg, &pConfiguration->NumberOfHandledRXPacketsInDPC); + GetConfigurationEntry(cfg, &pConfiguration->FastInit); #if PARANDIS_SUPPORT_RSS GetConfigurationEntry(cfg, &pConfiguration->RSSOffloadSupported); GetConfigurationEntry(cfg, &pConfiguration->NumRSSQueues); @@ -287,6 +290,7 @@ static bool ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR pNewMACAddre bDebugPrint = pConfiguration->isLogEnabled.ulValue; virtioDebugLevel = pConfiguration->debugLevel.ulValue; + pContext->bFastInit = pConfiguration->FastInit.ulValue != 0; pContext->physicalMediaType = (NDIS_PHYSICAL_MEDIUM)pConfiguration->PhysicalMediaType.ulValue; pContext->maxFreeTxDescriptors = pConfiguration->TxCapacity.ulValue; pContext->maxRxBufferPerQueue = pConfiguration->RxCapacity.ulValue; @@ -2161,6 +2165,8 @@ NDIS_STATUS ParaNdis_PowerOn(PARANDIS_ADAPTER *pContext) DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, _etagHistoryLogOperation::hopPowerOn, NULL, 1, 0, 0); + CMutexLockedContext sync(pContext->systemThread.PowerMutex()); + pContext->m_StateMachine.NotifyPowerOn(); ParaNdis_ResetVirtIONetDevice(pContext); @@ -2213,6 +2219,8 @@ VOID ParaNdis_PowerOff(PARANDIS_ADAPTER *pContext) DEBUG_ENTRY(0); ParaNdis_DebugHistory(pContext, _etagHistoryLogOperation::hopPowerOff, NULL, 1, 0, 0); + CMutexLockedContext sync(pContext->systemThread.PowerMutex()); + pContext->m_StateMachine.NotifySuspended(); pContext->bConnected = FALSE; diff --git a/NetKVM/Common/ParaNdis_RX.cpp b/NetKVM/Common/ParaNdis_RX.cpp index 841e4dd14..f87fc2a39 100644 --- a/NetKVM/Common/ParaNdis_RX.cpp +++ b/NetKVM/Common/ParaNdis_RX.cpp @@ -6,6 +6,10 @@ #include "ParaNdis_RX.tmh" #endif +//define as 0 to allocate all the required buffer at once +//#define INITIAL_RX_BUFFERS 0 +#define INITIAL_RX_BUFFERS 16 + static FORCEINLINE VOID ParaNdis_ReceiveQueueAddBuffer(PPARANDIS_RECEIVE_QUEUE pQueue, pRxNetDescriptor pBuffer) { NdisInterlockedInsertTailList(&pQueue->BuffersList, @@ -93,11 +97,28 @@ CParaNdisRX::~CParaNdisRX() { } +// called during initialization +// also later during additional allocations under m_Lock +// when we update m_NetMaxReceiveBuffers, we also update +// m_nReusedRxBuffersLimit, set m_nReusedRxBuffersLimit to zero +// and kick the rx queue +void CParaNdisRX::RecalculateLimits() +{ + m_nReusedRxBuffersLimit = m_NetMaxReceiveBuffers / 4 + 1; + m_nReusedRxBuffersCounter = 0; + m_MinRxBufferLimit = m_NetMaxReceiveBuffers * m_Context->MinRxBufferPercent / 100; + DPrintf(0, "[%s] m_NetMaxReceiveBuffers %d, m_MinRxBufferLimit %u\n", __FUNCTION__, m_NetMaxReceiveBuffers, m_MinRxBufferLimit); +} + bool CParaNdisRX::Create(PPARANDIS_ADAPTER Context, UINT DeviceQueueIndex) { m_Context = Context; m_queueIndex = (u16)DeviceQueueIndex; - m_NetMaxReceiveBuffers = Context->maxRxBufferPerQueue; + m_NetMaxReceiveBuffers = Context->bFastInit ? INITIAL_RX_BUFFERS : 0; + if (!m_NetMaxReceiveBuffers || m_NetMaxReceiveBuffers > Context->maxRxBufferPerQueue) + { + m_NetMaxReceiveBuffers = Context->maxRxBufferPerQueue; + } if (!m_VirtQueue.Create(DeviceQueueIndex, &m_Context->IODevice, @@ -109,8 +130,6 @@ bool CParaNdisRX::Create(PPARANDIS_ADAPTER Context, UINT DeviceQueueIndex) PrepareReceiveBuffers(); - m_nReusedRxBuffersLimit = m_NetMaxReceiveBuffers / 4 + 1; - CreatePath(); return true; @@ -140,8 +159,9 @@ int CParaNdisRX::PrepareReceiveBuffers() m_NetNofReceiveBuffers++; } m_NetMaxReceiveBuffers = m_NetNofReceiveBuffers; - m_MinRxBufferLimit = m_NetNofReceiveBuffers * m_Context->MinRxBufferPercent / 100; - DPrintf(0, "[%s] m_NetMaxReceiveBuffers %d, m_MinRxBufferLimit %u\n", __FUNCTION__, m_NetMaxReceiveBuffers, m_MinRxBufferLimit); + + RecalculateLimits(); + if (m_Context->extraStatistics.minFreeRxBuffers == 0 || m_Context->extraStatistics.minFreeRxBuffers > m_NetNofReceiveBuffers) { m_Context->extraStatistics.minFreeRxBuffers = m_NetNofReceiveBuffers; @@ -250,6 +270,46 @@ pRxNetDescriptor CParaNdisRX::CreateRxDescriptorOnInit() return NULL; } +/* must be called on PASSIVE from system thread */ +BOOLEAN CParaNdisRX::AllocateMore() +{ + BOOLEAN result = false; + + // if the queue is not ready, try again later + if (!m_pVirtQueue->IsValid() || !m_Reinsert) + { + DPrintf(1, " Queue is not ready, try later\n"); + return true; + } + + if (m_NetMaxReceiveBuffers >= m_Context->maxRxBufferPerQueue || m_NetMaxReceiveBuffers >= m_pVirtQueue->GetRingSize()) + { + return result; + } + pRxNetDescriptor pBuffersDescriptor = CreateRxDescriptorOnInit(); + + TPassiveSpinLocker autoLock(m_Lock); + + if (pBuffersDescriptor) + { + pBuffersDescriptor->Queue = this; + if (m_pVirtQueue->CanTouchHardware() && AddRxBufferToQueue(pBuffersDescriptor)) + { + InsertTailList(&m_NetReceiveBuffers, &pBuffersDescriptor->listEntry); + m_NetNofReceiveBuffers++; + m_NetMaxReceiveBuffers++; + RecalculateLimits(); + KickRXRing(); + result = true; + } + else + { + ParaNdis_FreeRxBufferDescriptor(m_Context, pBuffersDescriptor); + } + } + return result; +} + /* TODO - make it method in pRXNetDescriptor */ BOOLEAN CParaNdisRX::AddRxBufferToQueue(pRxNetDescriptor pBufferDescriptor) { diff --git a/NetKVM/Common/ParaNdis_TX.cpp b/NetKVM/Common/ParaNdis_TX.cpp index 6d0d9ac24..ed4bbc67e 100644 --- a/NetKVM/Common/ParaNdis_TX.cpp +++ b/NetKVM/Common/ParaNdis_TX.cpp @@ -6,13 +6,6 @@ #include "ParaNdis_TX.tmh" #endif -static FORCEINLINE void UpdateTimestamp(ULONGLONG& Variable) -{ - LARGE_INTEGER li; - NdisGetCurrentSystemTime(&li); - Variable = li.QuadPart; -} - CNBL::CNBL(PNET_BUFFER_LIST NBL, PPARANDIS_ADAPTER Context, CParaNdisTX &ParentTXPath, CAllocationHelper *NBLAllocator, CAllocationHelper *NBAllocator) : m_NBL(NBL) , m_Context(Context) @@ -463,7 +456,7 @@ bool CParaNdisTX::AllocateExtraPages() { return false; } - Page->Create(m_Context->MiniportHandle); + Page->Initialize(m_Context->MiniportHandle); if (Page->Allocate(PAGE_SIZE)) { m_ExtraPages.Push(Page); diff --git a/NetKVM/Common/ParaNdis_Util.cpp b/NetKVM/Common/ParaNdis_Util.cpp index 3b5c334c6..52e6a1c7b 100644 --- a/NetKVM/Common/ParaNdis_Util.cpp +++ b/NetKVM/Common/ParaNdis_Util.cpp @@ -124,3 +124,58 @@ void Parandis_UtilOnly_Trace(LONG level, LPCSTR s1, LPCSTR s2) TraceNoPrefix(level, "[%s] - format concatenation failed for %s", s1, s2); } } + +bool CSystemThread::Start(PVOID Context) +{ + m_Context = Context; + UpdateTimestamp(m_StartTime); + NTSTATUS status = PsCreateSystemThread( + &m_hThread, GENERIC_READ, NULL, NULL, NULL, + [](PVOID Ctx) + { + ((CSystemThread*)Ctx)->ThreadProc(); + }, + this); + if (!NT_SUCCESS(status)) + { + DPrintf(0, "Failed to start, status %X", status); + } + return m_hThread != NULL && NT_SUCCESS(status); +} + +void CSystemThread::Stop() +{ + DPrintf(0, "Waiting for thread termination"); + m_Event.Notify(); + while (m_hThread) + { + NdisMSleep(20000); + } + DPrintf(0, "Terminated"); +} + +void CSystemThread::ThreadProc() +{ + PARANDIS_ADAPTER* context = (PARANDIS_ADAPTER*)m_Context; + context->extraStatistics.lazyAllocTime = -1; + while (!m_Event.Wait(1)) + { + UINT n = 0; + + CMutexLockedContext sync(m_PowerMutex); + + for (UINT i = 0; i < context->nPathBundles; ++i) + { + n += context->pPathBundles[i].rxPath.AllocateMore(); + } + if (n == 0) + { + DPrintf(0, "All the memory allocations done"); + m_Event.Notify(); + ULONGLONG endTimestamp; + UpdateTimestamp(endTimestamp); + context->extraStatistics.lazyAllocTime = (LONG)((endTimestamp - m_StartTime)/10000); + } + } + m_hThread = NULL; +} diff --git a/NetKVM/Common/ParaNdis_VirtQueue.cpp b/NetKVM/Common/ParaNdis_VirtQueue.cpp index ae251e337..e050db934 100644 --- a/NetKVM/Common/ParaNdis_VirtQueue.cpp +++ b/NetKVM/Common/ParaNdis_VirtQueue.cpp @@ -62,11 +62,7 @@ bool CVirtQueue::Create(UINT Index, m_Index = Index; m_IODevice = IODevice; - if (!m_SharedMemory.Create(DrvHandle)) - { - DPrintf(0, "[%s] - shared memory creation failed\n", __FUNCTION__); - return false; - } + m_SharedMemory.Initialize(DrvHandle); NETKVM_ASSERT(m_VirtQueue == nullptr); @@ -391,8 +387,8 @@ SubmitTxPacketResult CTXDescriptor::Enqueue(CTXVirtQueue *Queue, ULONG TotalDesc m_CurrVirtioSGLEntry, 0, this, - m_IndirectArea.GetVA(), - m_IndirectArea.GetPA().QuadPart)) + m_IndirectArea.Virtual, + m_IndirectArea.Physical.QuadPart)) { return SubmitTxPacketResult::SUBMIT_SUCCESS; } @@ -452,33 +448,29 @@ bool CTXDescriptor::SetupHeaders(ULONG ParsedHeadersLength) } } -bool CTXHeaders::Allocate() +void CTXHeaders::Initialize(ULONG VirtioHdrSize, const tCompletePhysicalAddress& Buffer) { - if (m_HeadersBuffer.Allocate(PAGE_SIZE)) - { - auto VA = m_HeadersBuffer.GetVA(); - auto PA = m_HeadersBuffer.GetPA(); - ULONG prioSize = ALIGN_UP(ETH_PRIORITY_HEADER_SIZE, ULONGLONG); + m_VirtioHdrSize = VirtioHdrSize; + m_HeadersBuffer = Buffer; - //Headers buffer layout: - // Priority header - // Virtio header - // Ethernet headers + auto VA = m_HeadersBuffer.Virtual; + auto PA = m_HeadersBuffer.Physical; + ULONG prioSize = ALIGN_UP(ETH_PRIORITY_HEADER_SIZE, ULONGLONG); - m_VlanHeaderVA = VA; - m_VirtioHeaderVA = RtlOffsetToPointer(m_VlanHeaderVA, prioSize); - m_EthHeaderVA = RtlOffsetToPointer(m_VirtioHeaderVA, m_VirtioHdrSize); - m_IPHeadersVA = RtlOffsetToPointer(m_EthHeaderVA, ETH_HEADER_SIZE); + //Headers buffer layout: + // Priority header + // Virtio header + // Ethernet headers - m_VirtioHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_VirtioHeaderVA); - m_VlanHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_VlanHeaderVA); - m_EthHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_EthHeaderVA); - m_IPHeadersPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_IPHeadersVA); + m_VlanHeaderVA = VA; + m_VirtioHeaderVA = RtlOffsetToPointer(m_VlanHeaderVA, prioSize); + m_EthHeaderVA = RtlOffsetToPointer(m_VirtioHeaderVA, m_VirtioHdrSize); + m_IPHeadersVA = RtlOffsetToPointer(m_EthHeaderVA, ETH_HEADER_SIZE); - m_MaxEthHeadersSize = m_HeadersBuffer.GetSize() - prioSize - m_VirtioHdrSize; + m_VirtioHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_VirtioHeaderVA); + m_VlanHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_VlanHeaderVA); + m_EthHeaderPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_EthHeaderVA); + m_IPHeadersPA.QuadPart = PA.QuadPart + RtlPointerToOffset(VA, m_IPHeadersVA); - return true; - } - - return false; + m_MaxEthHeadersSize = m_HeadersBuffer.size - prioSize - m_VirtioHdrSize; } diff --git a/NetKVM/Common/ndis56common.h b/NetKVM/Common/ndis56common.h index 020d9dfd0..f971144d0 100755 --- a/NetKVM/Common/ndis56common.h +++ b/NetKVM/Common/ndis56common.h @@ -501,6 +501,7 @@ struct _PARANDIS_ADAPTER : public CNdisAllocatable<_PARANDIS_ADAPTER, 'DCTX'> BOOLEAN bGuestChecksumSupported = false; BOOLEAN bControlQueueSupported = false; BOOLEAN bUseMergedBuffers = false; + BOOLEAN bFastInit = false; BOOLEAN bSurprizeRemoved = false; BOOLEAN bUsingMSIX = false; BOOLEAN bUseIndirect = false; @@ -562,6 +563,8 @@ struct _PARANDIS_ADAPTER : public CNdisAllocatable<_PARANDIS_ADAPTER, 'DCTX'> ULONG allocatedSharedMemory; LARGE_INTEGER totalRxIndicates; LARGE_INTEGER rxIndicatesWithResourcesFlag; + ULONG fastInitTime; + LONG lazyAllocTime; } extraStatistics = {}; /* initial number of free Tx descriptor(from cfg) - max number of available Tx descriptors */ @@ -604,6 +607,7 @@ struct _PARANDIS_ADAPTER : public CNdisAllocatable<_PARANDIS_ADAPTER, 'DCTX'> BOOLEAN bRSSSupportedByDevice = false; BOOLEAN bRSSSupportedByDevicePersistent = false; BOOLEAN bHashReportedByDevice = false; + CSystemThread systemThread; #if PARANDIS_SUPPORT_RSS BOOLEAN bRSSOffloadSupported = false; diff --git a/NetKVM/Common/netkvm.mof b/NetKVM/Common/netkvm.mof index 3e80a7f83..ff2211e6e 100644 --- a/NetKVM/Common/netkvm.mof +++ b/NetKVM/Common/netkvm.mof @@ -44,6 +44,8 @@ class NetKvm_Config : MSNdis [WmiDataId(5), read] boolean RscEnabledv6; [WmiDataId(6), read] boolean Standby; [WmiDataId(7), read] uint32 MemoryKB; + [WmiDataId(8), read] sint32 InitTimeMs; + [WmiDataId(9), read] sint32 LazyAllocTimeMs; }; [WMI, diff --git a/NetKVM/netkvm-base.txt b/NetKVM/netkvm-base.txt index efbbb0df2..440a929d0 100644 --- a/NetKVM/netkvm-base.txt +++ b/NetKVM/netkvm-base.txt @@ -124,6 +124,12 @@ HKR, Ndi\Params\RxCapacity\enum, "1024", 0, %String_1024% HKR, Ndi\Params\RxCapacity\enum, "2048", 0, %String_2048% HKR, Ndi\Params\RxCapacity\enum, "4096", 0, %String_4096% +HKR, Ndi\Params\FastInit, ParamDesc, 0, %FastInit% +HKR, Ndi\Params\FastInit, Default, 0, "1" +HKR, Ndi\Params\FastInit, type, 0, "enum" +HKR, Ndi\Params\FastInit\enum, "1", 0, %Enable% +HKR, Ndi\Params\FastInit\enum, "0", 0, %Disable% + HKR, Ndi\params\NetworkAddress, ParamDesc, 0, %NetworkAddress% HKR, Ndi\params\NetworkAddress, type, 0, "edit" HKR, Ndi\params\NetworkAddress, Optional, 0, "1" @@ -262,6 +268,7 @@ Priority = "Init.Do802.1PQ" JumboPacket = "Jumbo Packet" TxCapacity = "Init.MaxTxBuffers" RxCapacity = "Init.MaxRxBuffers" +FastInit = "Fast Initialization" Offload.TxChecksum = "Offload.Tx.Checksum" Offload.TxLSO = "Offload.Tx.LSO" Offload.RxCS = "Offload.Rx.Checksum" diff --git a/NetKVM/wlh/ParaNdis6_Driver.cpp b/NetKVM/wlh/ParaNdis6_Driver.cpp index 13b132535..96561d66b 100755 --- a/NetKVM/wlh/ParaNdis6_Driver.cpp +++ b/NetKVM/wlh/ParaNdis6_Driver.cpp @@ -168,6 +168,8 @@ static NDIS_STATUS ParaNdis6_Initialize( NDIS_MINIPORT_ADAPTER_ATTRIBUTES miniportAttributes = {}; NDIS_STATUS status = NDIS_STATUS_SUCCESS; PARANDIS_ADAPTER *pContext; + ULONGLONG startTimestamp; + UpdateTimestamp(startTimestamp); UNREFERENCED_PARAMETER(miniportDriverContext); DEBUG_ENTRY(0); @@ -328,6 +330,10 @@ static NDIS_STATUS ParaNdis6_Initialize( pContext->m_StateMachine.NotifyInitialized(pContext); ParaNdis_DebugRegisterMiniport(pContext, TRUE); ParaNdis_ProtocolRegisterAdapter(pContext); + pContext->systemThread.Start(pContext); + ULONGLONG initDoneTimestamp; + UpdateTimestamp(initDoneTimestamp); + pContext->extraStatistics.fastInitTime = (ULONG)((initDoneTimestamp - startTimestamp) / 10000); } else { @@ -353,6 +359,7 @@ static VOID ParaNdis6_Halt(NDIS_HANDLE miniportAdapterContext, NDIS_HALT_ACTION { PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; DEBUG_ENTRY(0); + pContext->systemThread.Stop(); ParaNdis_DebugHistory(pContext, _etagHistoryLogOperation::hopHalt, NULL, 1, haltAction, 0); ParaNdis_ProtocolUnregisterAdapter(pContext); ParaNdis_DebugHistory(pContext, _etagHistoryLogOperation::hopHalt, NULL, 0, 0, 0); diff --git a/NetKVM/wlh/ParaNdis6_Oid.cpp b/NetKVM/wlh/ParaNdis6_Oid.cpp index 7912bfbd9..2452e90a6 100755 --- a/NetKVM/wlh/ParaNdis6_Oid.cpp +++ b/NetKVM/wlh/ParaNdis6_Oid.cpp @@ -499,12 +499,14 @@ static NDIS_STATUS ParaNdis_OidQuery(PARANDIS_ADAPTER *pContext, tOidDesc *pOid) pInfo = &u.WmiConfig; ulSize = sizeof(u.WmiConfig); u.WmiConfig.NumOfQueues = pContext->nPathBundles; - u.WmiConfig.RxQueueSize = pContext->maxRxBufferPerQueue; + u.WmiConfig.RxQueueSize = pContext->pPathBundles[0].rxPath.GetFreeRxBuffers(); u.WmiConfig.TxQueueSize = pContext->pPathBundles[0].txPath.GetActualQueueSize(); u.WmiConfig.RscEnabledv4 = pContext->ReportedOffloadConfiguration.Rsc.IPv4.Enabled; u.WmiConfig.RscEnabledv6 = pContext->ReportedOffloadConfiguration.Rsc.IPv6.Enabled; u.WmiConfig.Standby = !!virtio_is_feature_enabled(pContext->u64GuestFeatures, VIRTIO_NET_F_STANDBY); u.WmiConfig.MemoryKB = pContext->extraStatistics.allocatedSharedMemory / 1024; + u.WmiConfig.InitTimeMs = pContext->extraStatistics.fastInitTime; + u.WmiConfig.LazyAllocTimeMs = pContext->extraStatistics.lazyAllocTime; break; case OID_VENDOR_3: pInfo = &u.WmiDiag;