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>
This commit is contained in:
parent
58ce3c5000
commit
043abc0a8e
16
wintun.c
16
wintun.c
@ -262,10 +262,6 @@ TunSendNetBufferLists(
|
|||||||
{
|
{
|
||||||
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
|
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
|
||||||
LONG64 SentPacketsCount = 0, SentPacketsSize = 0, ErrorPacketsCount = 0, DiscardedPacketsCount = 0;
|
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)
|
for (NET_BUFFER_LIST *Nbl = NetBufferLists, *NblNext; Nbl; Nbl = NblNext)
|
||||||
{
|
{
|
||||||
@ -281,12 +277,18 @@ TunSendNetBufferLists(
|
|||||||
RequiredRingSpace += TUN_ALIGN(sizeof(TUN_PACKET) + PacketSize);
|
RequiredRingSpace += TUN_ALIGN(sizeof(TUN_PACKET) + PacketSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KIRQL Irql = ExAcquireSpinLockShared(&Ctx->TransitionLock);
|
||||||
|
LONG Flags = InterlockedGet(&Ctx->Flags);
|
||||||
|
|
||||||
NDIS_STATUS Status;
|
NDIS_STATUS Status;
|
||||||
if ((Status = NDIS_STATUS_ADAPTER_REMOVED, !(Flags & TUN_FLAGS_PRESENT)) ||
|
if ((Status = NDIS_STATUS_ADAPTER_REMOVED, !(Flags & TUN_FLAGS_PRESENT)) ||
|
||||||
(Status = NDIS_STATUS_PAUSED, !(Flags & TUN_FLAGS_RUNNING)) ||
|
(Status = NDIS_STATUS_PAUSED, !(Flags & TUN_FLAGS_RUNNING)) ||
|
||||||
(Status = NDIS_STATUS_MEDIA_DISCONNECTED, KeReadStateEvent(&Ctx->Device.Disconnected)))
|
(Status = NDIS_STATUS_MEDIA_DISCONNECTED, KeReadStateEvent(&Ctx->Device.Disconnected)))
|
||||||
goto skipNbl;
|
goto skipNbl;
|
||||||
|
|
||||||
|
TUN_RING *Ring = Ctx->Device.Send.Ring;
|
||||||
|
ULONG RingCapacity = Ctx->Device.Send.Capacity;
|
||||||
|
|
||||||
/* Allocate space for packet(s) in the ring. */
|
/* Allocate space for packet(s) in the ring. */
|
||||||
ULONG RingHead = InterlockedGetU(&Ring->Head);
|
ULONG RingHead = InterlockedGetU(&Ring->Head);
|
||||||
if (Status = NDIS_STATUS_ADAPTER_NOT_READY, RingHead >= RingCapacity)
|
if (Status = NDIS_STATUS_ADAPTER_NOT_READY, RingHead >= RingCapacity)
|
||||||
@ -358,6 +360,7 @@ TunSendNetBufferLists(
|
|||||||
Ctx->MiniportAdapterHandle, CompletedNbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
|
Ctx->MiniportAdapterHandle, CompletedNbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
|
||||||
}
|
}
|
||||||
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
KeReleaseInStackQueuedSpinLock(&LockHandle);
|
||||||
|
ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cleanupKeReleaseInStackQueuedSpinLock:
|
cleanupKeReleaseInStackQueuedSpinLock:
|
||||||
@ -365,12 +368,11 @@ TunSendNetBufferLists(
|
|||||||
skipNbl:
|
skipNbl:
|
||||||
NET_BUFFER_LIST_STATUS(Nbl) = Status;
|
NET_BUFFER_LIST_STATUS(Nbl) = Status;
|
||||||
NET_BUFFER_LIST_NEXT_NBL(Nbl) = NULL;
|
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;
|
DiscardedPacketsCount += PacketsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
|
|
||||||
|
|
||||||
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutOctets, SentPacketsSize);
|
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutOctets, SentPacketsSize);
|
||||||
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastOctets, SentPacketsSize);
|
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastOctets, SentPacketsSize);
|
||||||
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastPkts, SentPacketsCount);
|
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCOutUcastPkts, SentPacketsCount);
|
||||||
|
Loading…
Reference in New Issue
Block a user