Development discussion of WireGuard
 help / color / mirror / Atom feed
* wintun 0.13 driver - performance issue
@ 2022-01-14 19:43 Alejandro Pablo Achterberg
  0 siblings, 0 replies; only message in thread
From: Alejandro Pablo Achterberg @ 2022-01-14 19:43 UTC (permalink / raw)
  To: wireguard

Hi everyone !
I have this issue to share to see if it can be considered a natural limitation of the implementation or (more probably) that I am making some bad decisions.
I modified the example.c included in wintun-0.13 code to test higher rates of packet sending.
I am building Multicast UDP packets 200 bytes long that are received at a consumer application -that opens a socket to the wintun adapter registering the multicast group to the socket-.
I turned off all console logging during the test run.
I'm running on a Windows Server 2019, 8 cores, 32 GB RAM, Visual Studio Community 2019.
What I get is that the example can send the 100 Kpps (and up to ~300 Kpps) without problems, but not with the consumer application reading packets from the wintun adapter.
When the consumer application is reading packets from the wintun interface the top sending rate falls about 15-20%.
It keeps below 85 Kpps and shows some events of problems at WintunAllocateSendPacket(). I set the Rings capacity to the MAX allowed of 64 MB.
Trying to fix this behaviour I modified the ERROR_BUFFER_OVERFLOW error handling doing a wait on the Alertable state of the Receive Ring and settting the Receive.Tailmoved event when that happens.
This is the SendPackets() method:
static DWORD WINAPI
SendPackets(_Inout_ DWORD_PTR SessionPtr)
{
TUN_SESSION* Session = (TUN_SESSION*)SessionPtr;
while (!HaveQuit)
{
BYTE* Packet = WintunAllocateSendPacket(Session, 228);
if (Packet)
{
MakeIpPacket(Packet);
WintunSendPacket(Session, Packet);
++sentPkts;
spin(RATE, PPS);
}
else {
if (GetLastError() != ERROR_BUFFER_OVERFLOW) {
return LogLastError(L"Packet write failed");
}
else {
while (Session->Descriptor.Receive.Ring->Alertable != 1) {
spin(1000, FALSE);
}
SetEvent(Session->Descriptor.Receive.TailMoved);
++sendDelay;
}
}
}
return ERROR_SUCCESS;
}
and this is my spin() function:
// Packets per second sent can be defined as PPS using windows timers or with their period using a count loop
static boolean PPS = TRUE;
static LONG RATE = 115000;
static void
spin(LONGLONG rate, boolean isPPS) {
LARGE_INTEGER StartingTime, CurrentTime, ElapsedMicroseconds;
LONGLONG nano;
if (isPPS) {
nano = 1e9 / rate;
QueryPerformanceCounter(&StartingTime);
while (TRUE) {
if (HaveQuit)
break;
QueryPerformanceCounter(&CurrentTime);
ElapsedMicroseconds.QuadPart = CurrentTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000; // guard against loss-of-precision
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000; // nanoseconds
if (nano < ElapsedMicroseconds.QuadPart) {
break;
}
}
}
else {
if (rate < 1000) {
return;
}
nano = rate;
while (nano > 0) {
if (HaveQuit)
break;
--nano;
}
}
}
Statistics reported look like this when sending to the wintun interface and without the consumer application active.
Rate of 100 Kpps is easily reached.
"Delayed" counts are ERROR_BUFFER_OVERFLOW events from WintunAllocateSendPacket().
> .\wintunprj.exe
2022-01-11 21:09:19.0371 [+] Wintun library loaded
2022-01-11 21:09:19.0377 [+] WintunCreateAdapter: Creating adapter
2022-01-11 21:09:19.0477 [+] SelectDriver: Using existing driver 0.13
2022-01-11 21:09:19.0757 [+] Wintun v0.13 loaded
2022-01-11 21:09:19.0762 [+] Starting -----------------------------
2022-01-11 21:09:19.0774 [+] Run started with PPS: 115000
2022-01-11 21:09:26.0764 [+] Elapsed time in seconds: 6.985698
2022-01-11 21:09:26.0766 [+] 757111 packets sent, 42 packets received
2022-01-11 21:09:26.0768 [+] Packets sent at 108380 pps
2022-01-11 21:09:26.0769 [+] Final Sending problem counts - delayed: 0
And the statistics look like this with the consumer application active.
Packet rate drops to 84 Kpps.
Delayed events are present but they don't look significant actually...
.\wintunprj.exe
2022-01-11 21:33:22.0198 [+] Wintun library loaded
2022-01-11 21:33:22.0204 [+] WintunCreateAdapter: Creating adapter
2022-01-11 21:33:22.0282 [+] SelectDriver: Using existing driver 0.13
2022-01-11 21:33:22.0564 [+] Wintun v0.13 loaded
2022-01-11 21:33:22.0576 [+] Starting -----------------------------
2022-01-11 21:33:22.0594 [+] Run started with PPS: 115000
2022-01-11 21:34:39.0068 [+] Elapsed time in seconds: 76.470261
2022-01-11 21:34:39.0070 [+] 6455902 packets sent, 45 packets received
2022-01-11 21:34:39.0072 [+] Packets sent at 84424 pps
2022-01-11 21:34:39.0074 [+] Final Sending problem counts - delayed: 5
Any thoughts or ideas on how is this happening and changes due will be really appreciated !
Thanks,
Alex

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-16 21:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-14 19:43 wintun 0.13 driver - performance issue Alejandro Pablo Achterberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).