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

Try using latest xdp #4652

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
[submodule "submodules/xdp-for-windows"]
path = submodules/xdp-for-windows
url = https://github.com/microsoft/xdp-for-windows.git
branch = release/1.0
branch = 59b1b84168adc0ab939f74c967bc2d8fa769f59c
5 changes: 5 additions & 0 deletions src/platform/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ endif()
add_library(msquic_platform STATIC ${SOURCES})

if("${CX_PLATFORM}" STREQUAL "windows")
target_compile_definitions(msquic_platform PRIVATE
XDP_API_VERSION=3
XDPAPI_ASSERT_INTERNAL
ami-GS marked this conversation as resolved.
Show resolved Hide resolved
XDP_INCLUDE_WINCOMMON
)
target_link_libraries(
msquic_platform
PUBLIC
Expand Down
94 changes: 41 additions & 53 deletions src/platform/datapath_raw_xdp_win.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define _CRT_SECURE_NO_WARNINGS 1 // TODO - Remove

#include <xdp/wincommon.h>
#include "datapath_raw_win.h"
#include "datapath_raw_xdp.h"
#include <wbemidl.h>
Expand Down Expand Up @@ -42,9 +43,6 @@ typedef struct XDP_DATAPATH {
BOOLEAN TxAlwaysPoke;
BOOLEAN SkipXsum;
BOOLEAN Running; // Signal to stop partitions.
XDP_LOAD_API_CONTEXT XdpApiLoadContext;
const XDP_API_TABLE *XdpApi;
XDP_QEO_SET_FN *XdpQeoSet;

XDP_PARTITION Partitions[0];
} XDP_DATAPATH;
Expand Down Expand Up @@ -165,32 +163,37 @@ CxPlatGetRssQueueProcessors(
_Out_writes_to_(*Count, *Count) uint32_t* Queues
)
{
UNREFERENCED_PARAMETER(Xdp);
nibanks marked this conversation as resolved.
Show resolved Hide resolved
uint32_t TxRingSize = 1;
XDP_TX_PACKET TxPacket = { 0 };
CreateNoOpEthernetPacket(&TxPacket);

for (uint16_t i = 0; i < *Count; ++i) {
HANDLE TxXsk = NULL;
QUIC_STATUS Status = Xdp->XdpApi->XskCreate(&TxXsk);
QUIC_STATUS Status = XskCreate(&TxXsk);
if (QUIC_FAILED(Status)) { return Status; }

XSK_UMEM_REG TxUmem = {0};
UINT32 EnableAffinity = 1;
ami-GS marked this conversation as resolved.
Show resolved Hide resolved
TxUmem.Address = &TxPacket;
TxUmem.ChunkSize = sizeof(XDP_TX_PACKET);
TxUmem.Headroom = FIELD_OFFSET(XDP_TX_PACKET, FrameBuffer);
TxUmem.TotalSize = sizeof(XDP_TX_PACKET);

Status = Xdp->XdpApi->XskSetSockopt(TxXsk, XSK_SOCKOPT_UMEM_REG, &TxUmem, sizeof(TxUmem));
Status = XskSetSockopt(TxXsk, XSK_SOCKOPT_UMEM_REG, &TxUmem, sizeof(TxUmem));
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

Status = Xdp->XdpApi->XskSetSockopt(TxXsk, XSK_SOCKOPT_TX_RING_SIZE, &TxRingSize, sizeof(TxRingSize));
Status = XskSetSockopt(TxXsk, XSK_SOCKOPT_TX_RING_SIZE, &TxRingSize, sizeof(TxRingSize));
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

Status = Xdp->XdpApi->XskSetSockopt(TxXsk, XSK_SOCKOPT_TX_COMPLETION_RING_SIZE, &TxRingSize, sizeof(TxRingSize));
Status = XskSetSockopt(TxXsk, XSK_SOCKOPT_TX_COMPLETION_RING_SIZE, &TxRingSize, sizeof(TxRingSize));
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

Status = XskSetSockopt(TxXsk, XSK_SOCKOPT_TX_PROCESSOR_AFFINITY, &EnableAffinity, sizeof(EnableAffinity));
ami-GS marked this conversation as resolved.
Show resolved Hide resolved
nibanks marked this conversation as resolved.
Show resolved Hide resolved
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

uint32_t Flags = XSK_BIND_FLAG_TX;
Status = Xdp->XdpApi->XskBind(TxXsk, InterfaceIndex, i, Flags);
Status = XskBind(TxXsk, InterfaceIndex, i, Flags);
if (QUIC_FAILED(Status)) {
CloseHandle(TxXsk);
if (Status == E_INVALIDARG) { // No more queues. Break out.
Expand All @@ -205,7 +208,7 @@ CxPlatGetRssQueueProcessors(
return Status;
}

Status = Xdp->XdpApi->XskActivate(TxXsk, 0);
Status = XskActivate(TxXsk, 0);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -218,7 +221,7 @@ CxPlatGetRssQueueProcessors(

XSK_RING_INFO_SET TxRingInfo;
uint32_t TxRingInfoSize = sizeof(TxRingInfo);
Status = Xdp->XdpApi->XskGetSockopt(TxXsk, XSK_SOCKOPT_RING_INFO, &TxRingInfo, &TxRingInfoSize);
Status = XskGetSockopt(TxXsk, XSK_SOCKOPT_RING_INFO, &TxRingInfo, &TxRingInfoSize);
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

XSK_RING TxRing, TxCompletionRing;
Expand All @@ -235,7 +238,7 @@ CxPlatGetRssQueueProcessors(
XskRingProducerSubmit(&TxRing, 1);

XSK_NOTIFY_RESULT_FLAGS OutFlags;
Status = Xdp->XdpApi->XskNotifySocket(TxXsk, XSK_NOTIFY_FLAG_POKE_TX|XSK_NOTIFY_FLAG_WAIT_TX, XDP_MAX_SYNC_WAIT_TIMEOUT_MS, &OutFlags);
Status = XskNotifySocket(TxXsk, XSK_NOTIFY_FLAG_POKE_TX|XSK_NOTIFY_FLAG_WAIT_TX, XDP_MAX_SYNC_WAIT_TIMEOUT_MS, &OutFlags);
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

uint32_t CompIndex;
Expand All @@ -247,7 +250,7 @@ CxPlatGetRssQueueProcessors(

PROCESSOR_NUMBER ProcNumber;
uint32_t ProcNumberSize = sizeof(PROCESSOR_NUMBER);
Status = Xdp->XdpApi->XskGetSockopt(TxXsk, XSK_SOCKOPT_TX_PROCESSOR_AFFINITY, &ProcNumber, &ProcNumberSize);
Status = XskGetSockopt(TxXsk, XSK_SOCKOPT_TX_PROCESSOR_AFFINITY, &ProcNumber, &ProcNumberSize);
if (QUIC_FAILED(Status)) { CloseHandle(TxXsk); return Status; }

const CXPLAT_PROCESSOR_GROUP_INFO* Group = &CxPlatProcessorGroupInfo[ProcNumber.Group];
Expand Down Expand Up @@ -400,7 +403,7 @@ CxPlatDpRawInterfaceInitialize(
goto Error;
}

Status = Xdp->XdpApi->XdpInterfaceOpen(Interface->ActualIfIndex, &Interface->XdpHandle);
Status = XdpInterfaceOpen(Interface->ActualIfIndex, &Interface->XdpHandle);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand Down Expand Up @@ -479,7 +482,7 @@ CxPlatDpRawInterfaceInitialize(
goto Error;
}

Status = Xdp->XdpApi->XskCreate(&Queue->RxXsk);
Status = XskCreate(&Queue->RxXsk);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -495,7 +498,7 @@ CxPlatDpRawInterfaceInitialize(
RxUmem.Headroom = RxHeadroom;
RxUmem.TotalSize = Xdp->RxBufferCount * RxPacketSize;

Status = Xdp->XdpApi->XskSetSockopt(Queue->RxXsk, XSK_SOCKOPT_UMEM_REG, &RxUmem, sizeof(RxUmem));
Status = XskSetSockopt(Queue->RxXsk, XSK_SOCKOPT_UMEM_REG, &RxUmem, sizeof(RxUmem));
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -506,7 +509,7 @@ CxPlatDpRawInterfaceInitialize(
}

Status =
Xdp->XdpApi->XskSetSockopt(
XskSetSockopt(
Queue->RxXsk, XSK_SOCKOPT_RX_FILL_RING_SIZE, &Xdp->RxRingSize,
sizeof(Xdp->RxRingSize));
if (QUIC_FAILED(Status)) {
Expand All @@ -519,7 +522,7 @@ CxPlatDpRawInterfaceInitialize(
}

Status =
Xdp->XdpApi->XskSetSockopt(
XskSetSockopt(
Queue->RxXsk, XSK_SOCKOPT_RX_RING_SIZE, &Xdp->RxRingSize, sizeof(Xdp->RxRingSize));
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
Expand All @@ -531,7 +534,7 @@ CxPlatDpRawInterfaceInitialize(
}

uint32_t Flags = XSK_BIND_FLAG_RX;
Status = Xdp->XdpApi->XskBind(Queue->RxXsk, Interface->ActualIfIndex, i, Flags);
Status = XskBind(Queue->RxXsk, Interface->ActualIfIndex, i, Flags);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -541,7 +544,7 @@ CxPlatDpRawInterfaceInitialize(
goto Error;
}

Status = Xdp->XdpApi->XskActivate(Queue->RxXsk, 0);
Status = XskActivate(Queue->RxXsk, 0);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -553,7 +556,7 @@ CxPlatDpRawInterfaceInitialize(

XSK_RING_INFO_SET RxRingInfo;
uint32_t RxRingInfoSize = sizeof(RxRingInfo);
Status = Xdp->XdpApi->XskGetSockopt(Queue->RxXsk, XSK_SOCKOPT_RING_INFO, &RxRingInfo, &RxRingInfoSize);
Status = XskGetSockopt(Queue->RxXsk, XSK_SOCKOPT_RING_INFO, &RxRingInfo, &RxRingInfoSize);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand Down Expand Up @@ -601,7 +604,7 @@ CxPlatDpRawInterfaceInitialize(
goto Error;
}

Status = Xdp->XdpApi->XskCreate(&Queue->TxXsk);
Status = XskCreate(&Queue->TxXsk);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -617,7 +620,7 @@ CxPlatDpRawInterfaceInitialize(
TxUmem.Headroom = FIELD_OFFSET(XDP_TX_PACKET, FrameBuffer);
TxUmem.TotalSize = Xdp->TxBufferCount * sizeof(XDP_TX_PACKET);

Status = Xdp->XdpApi->XskSetSockopt(Queue->TxXsk, XSK_SOCKOPT_UMEM_REG, &TxUmem, sizeof(TxUmem));
Status = XskSetSockopt(Queue->TxXsk, XSK_SOCKOPT_UMEM_REG, &TxUmem, sizeof(TxUmem));
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -628,7 +631,7 @@ CxPlatDpRawInterfaceInitialize(
}

Status =
Xdp->XdpApi->XskSetSockopt(
XskSetSockopt(
Queue->TxXsk, XSK_SOCKOPT_TX_RING_SIZE, &Xdp->TxRingSize, sizeof(Xdp->TxRingSize));
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
Expand All @@ -640,7 +643,7 @@ CxPlatDpRawInterfaceInitialize(
}

Status =
Xdp->XdpApi->XskSetSockopt(
XskSetSockopt(
Queue->TxXsk, XSK_SOCKOPT_TX_COMPLETION_RING_SIZE, &Xdp->TxRingSize,
sizeof(Xdp->TxRingSize));
if (QUIC_FAILED(Status)) {
Expand All @@ -653,7 +656,7 @@ CxPlatDpRawInterfaceInitialize(
}

Flags = XSK_BIND_FLAG_TX; // TODO: support native/generic forced flags.
Status = Xdp->XdpApi->XskBind(Queue->TxXsk, Interface->ActualIfIndex, i, Flags);
Status = XskBind(Queue->TxXsk, Interface->ActualIfIndex, i, Flags);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -663,7 +666,7 @@ CxPlatDpRawInterfaceInitialize(
goto Error;
}

Status = Xdp->XdpApi->XskActivate(Queue->TxXsk, 0);
Status = XskActivate(Queue->TxXsk, 0);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand All @@ -675,7 +678,7 @@ CxPlatDpRawInterfaceInitialize(

XSK_RING_INFO_SET TxRingInfo;
uint32_t TxRingInfoSize = sizeof(TxRingInfo);
Status = Xdp->XdpApi->XskGetSockopt(Queue->TxXsk, XSK_SOCKOPT_RING_INFO, &TxRingInfo, &TxRingInfoSize);
Status = XskGetSockopt(Queue->TxXsk, XSK_SOCKOPT_RING_INFO, &TxRingInfo, &TxRingInfoSize);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand Down Expand Up @@ -765,7 +768,7 @@ CxPlatDpRawInterfaceUpdateRules(

HANDLE NewRxProgram;
QUIC_STATUS Status =
Interface->Xdp->XdpApi->XdpCreateProgram(
XdpCreateProgram(
Interface->ActualIfIndex,
&RxHook,
i,
Expand Down Expand Up @@ -943,12 +946,6 @@ CxPlatDpRawInitialize(
}

CxPlatListInitializeHead(&Xdp->Interfaces);
if (QUIC_FAILED(XdpLoadApi(XDP_API_VERSION_1, &Xdp->XdpApiLoadContext, &Xdp->XdpApi))) {
nibanks marked this conversation as resolved.
Show resolved Hide resolved
Status = QUIC_STATUS_NOT_SUPPORTED;
goto Error;
}

Xdp->XdpQeoSet = (XDP_QEO_SET_FN *)Xdp->XdpApi->XdpGetRoutine(XDP_QEO_SET_FN_NAME);

CxPlatXdpReadConfig(Xdp);
Xdp->PollingIdleTimeoutUs = Config ? Config->PollingIdleTimeoutUs : 0;
Expand Down Expand Up @@ -1160,10 +1157,6 @@ CxPlatDpRawInitialize(
CxPlatDpRawInterfaceUninitialize(Interface);
CxPlatFree(Interface, IF_TAG);
}

if (Xdp->XdpApi) {
XdpUnloadApi(Xdp->XdpApiLoadContext, Xdp->XdpApi);
}
}

return Status;
Expand All @@ -1190,7 +1183,6 @@ CxPlatDpRawRelease(
CxPlatDpRawInterfaceUninitialize(Interface);
CxPlatFree(Interface, IF_TAG);
}
XdpUnloadApi(Xdp->XdpApiLoadContext, Xdp->XdpApi);
CxPlatDataPathUninitializeComplete((CXPLAT_DATAPATH_RAW*)Xdp);
}
}
Expand Down Expand Up @@ -1278,15 +1270,11 @@ RawSocketUpdateQeo(

BOOLEAN AtLeastOneSucceeded = FALSE;
for (CXPLAT_LIST_ENTRY* Entry = Xdp->Interfaces.Flink; Entry != &Xdp->Interfaces; Entry = Entry->Flink) {
if (Xdp->XdpQeoSet != NULL) {
Status =
Xdp->XdpQeoSet(
CONTAINING_RECORD(Entry, XDP_INTERFACE, Link)->XdpHandle,
Connections,
sizeof(Connections));
} else {
Status = E_NOINTERFACE;
}
Status =
XdpQeoSet(
CONTAINING_RECORD(Entry, XDP_INTERFACE, Link)->XdpHandle,
Connections,
sizeof(Connections));
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
LibraryErrorStatus,
Expand Down Expand Up @@ -1543,7 +1531,7 @@ CxPlatXdpRx(
XSK_ERROR ErrorStatus;
QUIC_STATUS XskStatus;
uint32_t ErrorSize = sizeof(ErrorStatus);
XskStatus = Xdp->XdpApi->XskGetSockopt(Queue->RxXsk, XSK_SOCKOPT_RX_ERROR, &ErrorStatus, &ErrorSize);
XskStatus = XskGetSockopt(Queue->RxXsk, XSK_SOCKOPT_RX_ERROR, &ErrorStatus, &ErrorSize);
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Expand Down Expand Up @@ -1702,7 +1690,7 @@ CxPlatXdpTx(
MemoryBarrier();
if (Xdp->TxAlwaysPoke || XskRingProducerNeedPoke(&Queue->TxRing)) {
XSK_NOTIFY_RESULT_FLAGS OutFlags;
QUIC_STATUS Status = Xdp->XdpApi->XskNotifySocket(Queue->TxXsk, XSK_NOTIFY_FLAG_POKE_TX, 0, &OutFlags);
QUIC_STATUS Status = XskNotifySocket(Queue->TxXsk, XSK_NOTIFY_FLAG_POKE_TX, 0, &OutFlags);
CXPLAT_DBG_ASSERT(QUIC_SUCCEEDED(Status));
UNREFERENCED_PARAMETER(Status);
}
Expand All @@ -1712,7 +1700,7 @@ CxPlatXdpTx(
XSK_ERROR ErrorStatus;
QUIC_STATUS XskStatus;
uint32_t ErrorSize = sizeof(ErrorStatus);
XskStatus = Xdp->XdpApi->XskGetSockopt(Queue->TxXsk, XSK_SOCKOPT_TX_ERROR, &ErrorStatus, &ErrorSize);
XskStatus = XskGetSockopt(Queue->TxXsk, XSK_SOCKOPT_TX_ERROR, &ErrorStatus, &ErrorSize);
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
Expand Down Expand Up @@ -1781,7 +1769,7 @@ CxPlatXdpExecute(
&Queue->RxIoSqe.DatapathSqe.Sqe.Overlapped,
sizeof(Queue->RxIoSqe.DatapathSqe.Sqe.Overlapped));
HRESULT hr =
Xdp->XdpApi->XskNotifyAsync(
XskNotifyAsync(
Queue->RxXsk, XSK_NOTIFY_FLAG_WAIT_RX,
&Queue->RxIoSqe.DatapathSqe.Sqe.Overlapped);
if (hr == HRESULT_FROM_WIN32(ERROR_IO_PENDING)) {
Expand All @@ -1805,7 +1793,7 @@ CxPlatXdpExecute(
&Queue->TxIoSqe.DatapathSqe.Sqe.Overlapped,
sizeof(Queue->TxIoSqe.DatapathSqe.Sqe.Overlapped));
HRESULT hr =
Xdp->XdpApi->XskNotifyAsync(
XskNotifyAsync(
Queue->TxXsk, XSK_NOTIFY_FLAG_WAIT_TX,
&Queue->TxIoSqe.DatapathSqe.Sqe.Overlapped);
if (hr == HRESULT_FROM_WIN32(ERROR_IO_PENDING)) {
Expand Down
Loading