Use reference counter and KEVENT instead of remove locks
Driver verifier doesn't like re-initializing remove locks. Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
9e9f1ac9b3
commit
799413a776
21
wintun.c
21
wintun.c
@ -150,7 +150,8 @@ typedef struct _TUN_CTX
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
NET_BUFFER_LIST *Head, *Tail;
|
NET_BUFFER_LIST *Head, *Tail;
|
||||||
IO_REMOVE_LOCK RemoveLock;
|
volatile LONG64 Count;
|
||||||
|
KEVENT Empty;
|
||||||
} ActiveNbls;
|
} ActiveNbls;
|
||||||
} Receive;
|
} Receive;
|
||||||
} Device;
|
} Device;
|
||||||
@ -399,8 +400,8 @@ TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST Net
|
|||||||
NdisFreeNetBufferList(CompletedNbl);
|
NdisFreeNetBufferList(CompletedNbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WasNdisIndicated)
|
if (WasNdisIndicated && InterlockedDecrement64(&Ctx->Device.Receive.ActiveNbls.Count) <= 0)
|
||||||
IoReleaseRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, Nbl);
|
KeSetEvent(&Ctx->Device.Receive.ActiveNbls.Empty, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCInOctets, ReceivedPacketsSize);
|
InterlockedAdd64((LONG64 *)&Ctx->Statistics.ifHCInOctets, ReceivedPacketsSize);
|
||||||
@ -521,8 +522,8 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
|
|||||||
if (!InterlockedGet(&Ctx->Running))
|
if (!InterlockedGet(&Ctx->Running))
|
||||||
goto skipNbl;
|
goto skipNbl;
|
||||||
|
|
||||||
if (!NT_SUCCESS(IoAcquireRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, Nbl)))
|
if (InterlockedIncrement64(&Ctx->Device.Receive.ActiveNbls.Count) == 1)
|
||||||
goto skipNbl;
|
KeClearEvent(&Ctx->Device.Receive.ActiveNbls.Empty);
|
||||||
|
|
||||||
NdisMIndicateReceiveNetBufferLists(
|
NdisMIndicateReceiveNetBufferLists(
|
||||||
Ctx->MiniportAdapterHandle,
|
Ctx->MiniportAdapterHandle,
|
||||||
@ -542,8 +543,7 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
|
|||||||
|
|
||||||
/* Wait for all NBLs to return: 1. To prevent race between proceeding and invalidating ring head. 2. To have
|
/* Wait for all NBLs to return: 1. To prevent race between proceeding and invalidating ring head. 2. To have
|
||||||
* TunDispatchUnregisterBuffers() implicitly wait before releasing ring MDL used by NBL(s). */
|
* TunDispatchUnregisterBuffers() implicitly wait before releasing ring MDL used by NBL(s). */
|
||||||
if (NT_SUCCESS(IoAcquireRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, NULL)))
|
KeWaitForSingleObject(&Ctx->Device.Receive.ActiveNbls.Empty, Executive, KernelMode, FALSE, NULL);
|
||||||
IoReleaseRemoveLockAndWait(&Ctx->Device.Receive.ActiveNbls.RemoveLock, NULL);
|
|
||||||
cleanup:
|
cleanup:
|
||||||
InterlockedSetU(&Ring->Head, MAXULONG);
|
InterlockedSetU(&Ring->Head, MAXULONG);
|
||||||
}
|
}
|
||||||
@ -609,8 +609,6 @@ TunRegisterBuffers(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
|||||||
!IS_POW2(Ctx->Device.Receive.Capacity) || !Rrb->Receive.TailMoved || !Rrb->Receive.Ring))
|
!IS_POW2(Ctx->Device.Receive.Capacity) || !Rrb->Receive.TailMoved || !Rrb->Receive.Ring))
|
||||||
goto cleanupSendUnlockPages;
|
goto cleanupSendUnlockPages;
|
||||||
|
|
||||||
IoInitializeRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, TUN_MEMORY_TAG, 0, 0);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(
|
if (!NT_SUCCESS(
|
||||||
Status = ObReferenceObjectByHandle(
|
Status = ObReferenceObjectByHandle(
|
||||||
Rrb->Receive.TailMoved,
|
Rrb->Receive.TailMoved,
|
||||||
@ -881,7 +879,6 @@ static NDIS_STATUS
|
|||||||
TunRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
|
TunRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
|
||||||
{
|
{
|
||||||
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
|
TUN_CTX *Ctx = (TUN_CTX *)MiniportAdapterContext;
|
||||||
IoInitializeRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, TUN_MEMORY_TAG, 0, 0);
|
|
||||||
InterlockedSet(&Ctx->Running, TRUE);
|
InterlockedSet(&Ctx->Running, TRUE);
|
||||||
return NDIS_STATUS_SUCCESS;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -898,8 +895,7 @@ TunPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS Min
|
|||||||
&Ctx->TransitionLock,
|
&Ctx->TransitionLock,
|
||||||
ExAcquireSpinLockExclusive(&Ctx->TransitionLock)); /* Ensure above change is visible to all readers. */
|
ExAcquireSpinLockExclusive(&Ctx->TransitionLock)); /* Ensure above change is visible to all readers. */
|
||||||
|
|
||||||
if (NT_SUCCESS(IoAcquireRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, NULL)))
|
KeWaitForSingleObject(&Ctx->Device.Receive.ActiveNbls.Empty, Executive, KernelMode, FALSE, NULL);
|
||||||
IoReleaseRemoveLockAndWait(&Ctx->Device.Receive.ActiveNbls.RemoveLock, NULL);
|
|
||||||
|
|
||||||
return NDIS_STATUS_SUCCESS;
|
return NDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -963,6 +959,7 @@ TunInitializeEx(
|
|||||||
KeInitializeEvent(&Ctx->Device.Disconnected, NotificationEvent, TRUE);
|
KeInitializeEvent(&Ctx->Device.Disconnected, NotificationEvent, TRUE);
|
||||||
KeInitializeSpinLock(&Ctx->Device.Send.Lock);
|
KeInitializeSpinLock(&Ctx->Device.Send.Lock);
|
||||||
KeInitializeSpinLock(&Ctx->Device.Receive.Lock);
|
KeInitializeSpinLock(&Ctx->Device.Receive.Lock);
|
||||||
|
KeInitializeEvent(&Ctx->Device.Receive.ActiveNbls.Empty, NotificationEvent, TRUE);
|
||||||
|
|
||||||
NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters = {
|
NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters = {
|
||||||
.Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT,
|
.Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT,
|
||||||
|
Loading…
Reference in New Issue
Block a user