Skip to content

Commit

Permalink
netkvm: enhancing host throughput by combining virtio header and data…
Browse files Browse the repository at this point in the history
… in a single memory block

for the problem description
please visit virtio-win#1078
  • Loading branch information
zjmletang committed Apr 17, 2024
1 parent 8b6f5ef commit 88b423d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 15 deletions.
37 changes: 23 additions & 14 deletions NetKVM/Common/ParaNdis_RX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,21 @@ static BOOLEAN ParaNdis_BindRxBufferToPacket(

for (i = PARANDIS_FIRST_RX_DATA_PAGE; i < p->BufferSGLength; i++)
{
*NextMdlLinkage = NdisAllocateMdl(
pContext->MiniportHandle,
p->PhysicalPages[i].Virtual,
p->PhysicalPages[i].size);
//For the first physical page, which contains the VirtioHeader information, special handling is required.
if (0 == i)
{
*NextMdlLinkage = NdisAllocateMdl(
pContext->MiniportHandle,
(PVOID)((PCHAR)p->PhysicalPages[i].Virtual + pContext->nVirtioHeaderSize),
p->PhysicalPages[i].size - pContext->nVirtioHeaderSize);
}
else
{
*NextMdlLinkage = NdisAllocateMdl(
pContext->MiniportHandle,
(PVOID)((PCHAR)p->PhysicalPages[i].Virtual),
p->PhysicalPages[i].size);
}
if (*NextMdlLinkage == NULL) goto error_exit;

NextMdlLinkage = &(NDIS_MDL_LINKAGE(*NextMdlLinkage));
Expand All @@ -66,6 +77,7 @@ static void ParaNdis_FreeRxBufferDescriptor(PARANDIS_ADAPTER *pContext, pRxNetDe
{
ParaNdis_FreePhysicalMemory(pContext, &p->PhysicalPages[i]);
}
ParaNdis_FreePhysicalMemory(pContext, &p->IndirectArea);

if (p->BufferSGArray) NdisFreeMemory(p->BufferSGArray, 0, 0);
if (p->PhysicalPages) NdisFreeMemory(p->PhysicalPages, 0, 0);
Expand Down Expand Up @@ -164,7 +176,7 @@ pRxNetDescriptor CParaNdisRX::CreateRxDescriptorOnInit()
while (ulNumPages > 0)
{
// Allocate the first page separately, the rest can be one contiguous block
ULONG ulPagesToAlloc = (p->BufferSGLength == 0 ? 1 : ulNumPages);
ULONG ulPagesToAlloc = ulNumPages;

while (!ParaNdis_InitialAllocatePhysicalMemory(
m_Context,
Expand All @@ -185,14 +197,11 @@ pRxNetDescriptor CParaNdisRX::CreateRxDescriptorOnInit()
p->BufferSGLength++;
}

//First page is for virtio header, size needs to be adjusted correspondingly
p->BufferSGArray[0].length = m_Context->nVirtioHeaderSize;

ULONG indirectAreaOffset = ALIGN_UP(m_Context->nVirtioHeaderSize, ULONGLONG);
//Pre-cache indirect area addresses
p->IndirectArea.Physical.QuadPart = p->PhysicalPages[0].Physical.QuadPart + indirectAreaOffset;
p->IndirectArea.Virtual = RtlOffsetToPointer(p->PhysicalPages[0].Virtual, indirectAreaOffset);
p->IndirectArea.size = PAGE_SIZE - indirectAreaOffset;
//Allocate an entire physical page to store the indirect Area separately.
//Subsequently, the last page of the packet can be utilized to store the indirect area, optimizing memory usage.
//Currently, this is only for discussion purposes.
if (!ParaNdis_InitialAllocatePhysicalMemory(m_Context, PAGE_SIZE, &p->IndirectArea))
goto error_exit;

if (!ParaNdis_BindRxBufferToPacket(m_Context, p))
goto error_exit;
Expand Down Expand Up @@ -438,7 +447,7 @@ VOID CParaNdisRX::ProcessRxRing(CCHAR nCurrCpuReceiveQueue)

// basic MAC-based analysis + L3 header info
BOOLEAN packetAnalysisRC = ParaNdis_AnalyzeReceivedPacket(
pBufferDescriptor->PhysicalPages[PARANDIS_FIRST_RX_DATA_PAGE].Virtual,
PVOID((PCHAR)(pBufferDescriptor->PhysicalPages[PARANDIS_FIRST_RX_DATA_PAGE].Virtual) + m_Context->nVirtioHeaderSize),
nFullLength - m_Context->nVirtioHeaderSize,
&pBufferDescriptor->PacketInfo);

Expand Down
2 changes: 1 addition & 1 deletion NetKVM/Common/ndis56common.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ struct _tagRxNetDescriptor {
LIST_ENTRY listEntry;
LIST_ENTRY ReceiveQueueListEntry;

#define PARANDIS_FIRST_RX_DATA_PAGE (1)
#define PARANDIS_FIRST_RX_DATA_PAGE (0)
struct VirtIOBufferDescriptor *BufferSGArray;
tCompletePhysicalAddress *PhysicalPages;
ULONG BufferSGLength;
Expand Down

0 comments on commit 88b423d

Please sign in to comment.