diff options
author | Simon Rozman <simon@rozman.si> | 2019-07-18 08:55:12 +0200 |
---|---|---|
committer | Simon Rozman <simon@rozman.si> | 2019-07-18 13:52:16 +0200 |
commit | 043abc0a8e5148c4f9ec5cee4886e6cdc1024d14 (patch) | |
tree | 909a4ed4eee5f4cffbde1e9b74c9313968745f52 /wintun.c | |
parent | Piggy-back on top of NDIS' device object instead of adding our own (diff) | |
download | wintun-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.c | 16 |
1 files changed, 9 insertions, 7 deletions
@@ -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); |