aboutsummaryrefslogtreecommitdiffstats
path: root/wintun.c
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2019-07-18 08:55:12 +0200
committerSimon Rozman <simon@rozman.si>2019-07-18 13:52:16 +0200
commit043abc0a8e5148c4f9ec5cee4886e6cdc1024d14 (patch)
tree909a4ed4eee5f4cffbde1e9b74c9313968745f52 /wintun.c
parentPiggy-back on top of NDIS' device object instead of adding our own (diff)
downloadwintun-043abc0a8e5148c4f9ec5cee4886e6cdc1024d14.tar.xz
wintun-043abc0a8e5148c4f9ec5cee4886e6cdc1024d14.zip
Minimize TransitionLock when sending packets
We do not need to share-lock the TransitionLock for complete NBL chain. This commit should improve better state transition response, thou until NDIS is sending a single NBL per MINIPORT_SEND_NET_BUFFER_LISTS call, this should not have a considerable effect. Since the skibNbl: call of NdisMSendNetBufferListsComplete() is made inside the TransactionLock at dispatch IRQL, a dispatch IRQL hint was added to the NdisMSendNetBufferListsComplete() call. Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to 'wintun.c')
-rw-r--r--wintun.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/wintun.c b/wintun.c
index 030f316..d7f7104 100644
--- a/wintun.c
+++ b/wintun.c
@@ -262,10 +262,6 @@ TunSendNetBufferLists(
{
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
LONG64 SentPacketsCount = 0, SentPacketsSize = 0, ErrorPacketsCount = 0, DiscardedPacketsCount = 0;
- KIRQL Irql = ExAcquireSpinLockShared(&Ctx->TransitionLock);
- LONG Flags = InterlockedGet(&Ctx->Flags);
- TUN_RING *Ring = Ctx->Device.Send.Ring;
- ULONG RingCapacity = Ctx->Device.Send.Capacity;
for (NET_BUFFER_LIST *Nbl = NetBufferLists, *NblNext; Nbl; Nbl = NblNext)
{
@@ -281,12 +277,18 @@ TunSendNetBufferLists(
RequiredRingSpace += TUN_ALIGN(sizeof(TUN_PACKET) + PacketSize);
}
+ KIRQL Irql = ExAcquireSpinLockShared(&Ctx->TransitionLock);
+ LONG Flags = InterlockedGet(&Ctx->Flags);
+
NDIS_STATUS Status;
if ((Status = NDIS_STATUS_ADAPTER_REMOVED, !(Flags & TUN_FLAGS_PRESENT)) ||
(Status = NDIS_STATUS_PAUSED, !(Flags & TUN_FLAGS_RUNNING)) ||
(Status = NDIS_STATUS_MEDIA_DISCONNECTED, KeReadStateEvent(&Ctx->Device.Disconnected)))
goto skipNbl;
+ TUN_RING *Ring = Ctx->Device.Send.Ring;
+ ULONG RingCapacity = Ctx->Device.Send.Capacity;
+
/* Allocate space for packet(s) in the ring. */
ULONG RingHead = InterlockedGetU(&Ring->Head);
if (Status = NDIS_STATUS_ADAPTER_NOT_READY, RingHead >= RingCapacity)
@@ -358,6 +360,7 @@ TunSendNetBufferLists(
Ctx->MiniportAdapterHandle, CompletedNbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
}
KeReleaseInStackQueuedSpinLock(&LockHandle);
+ ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
continue;
cleanupKeReleaseInStackQueuedSpinLock:
@@ -365,12 +368,11 @@ TunSendNetBufferLists(
skipNbl:
NET_BUFFER_LIST_STATUS(Nbl) = Status;
NET_BUFFER_LIST_NEXT_NBL(Nbl) = NULL;
- NdisMSendNetBufferListsComplete(Ctx->MiniportAdapterHandle, Nbl, 0);
+ NdisMSendNetBufferListsComplete(Ctx->MiniportAdapterHandle, Nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
+ ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
DiscardedPacketsCount += PacketsCount;
}
- ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
-
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutOctets, SentPacketsSize);
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastOctets, SentPacketsSize);
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastPkts, SentPacketsCount);