Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netkvm: enhancing host throughput by combining virtio header and data in a single memory block #1089

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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