Reinitialize active NBL remove lock to allow adapter reuse

Before the TunProcessReceiveData() thread terminates or adapter is
paused, we wait for all receive NBLs to be returned. Unfortunately,
IoReleaseRemoveLockAndWait() leaves the remove lock in non reusable
state.

To be able to start receiving packets on existing adapter again, we
(re)initialize the remove lock on ring registration or adapter resume.
The former addresses TunProcessReceiveData()'s
IoReleaseRemoveLockAndWait() call, the later addresses the TunPause()'s.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-07-22 10:31:57 +02:00 committed by Jason A. Donenfeld
parent f48b0b2883
commit 0d9b9b925a

View File

@ -653,6 +653,8 @@ 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,
@ -849,6 +851,7 @@ 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);
InterlockedOr(&Ctx->Flags, TUN_FLAGS_RUNNING); InterlockedOr(&Ctx->Flags, TUN_FLAGS_RUNNING);
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;
} }
@ -928,7 +931,6 @@ 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);
IoInitializeRemoveLock(&Ctx->Device.Receive.ActiveNbls.RemoveLock, TUN_MEMORY_TAG, 0, 0);
NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters = { NET_BUFFER_LIST_POOL_PARAMETERS NblPoolParameters = {
.Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT, .Header = { .Type = NDIS_OBJECT_TYPE_DEFAULT,