Use synchronize_rcu()-like semantics for exclusive transition lock
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
33cac1114c
commit
248d4268df
20
wintun.c
20
wintun.c
@ -986,10 +986,11 @@ static void
|
|||||||
TunDispatchClose(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
TunDispatchClose(_Inout_ TUN_CTX *Ctx, _Inout_ IRP *Irp)
|
||||||
{
|
{
|
||||||
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(Irp);
|
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
KIRQL irql = ExAcquireSpinLockExclusive(&Ctx->TransitionLock);
|
|
||||||
ASSERT(InterlockedGet64(&Ctx->Device.RefCount) > 0);
|
ASSERT(InterlockedGet64(&Ctx->Device.RefCount) > 0);
|
||||||
BOOLEAN last_handle = InterlockedDecrement64(&Ctx->Device.RefCount) <= 0;
|
BOOLEAN last_handle = InterlockedDecrement64(&Ctx->Device.RefCount) <= 0;
|
||||||
ExReleaseSpinLockExclusive(&Ctx->TransitionLock, irql);
|
ExReleaseSpinLockExclusive(
|
||||||
|
&Ctx->TransitionLock,
|
||||||
|
ExAcquireSpinLockExclusive(&Ctx->TransitionLock)); // Ensure above change is visible to all readers.
|
||||||
if (last_handle)
|
if (last_handle)
|
||||||
{
|
{
|
||||||
NDIS_HANDLE handle = InterlockedGetPointer(&Ctx->MiniportAdapterHandle);
|
NDIS_HANDLE handle = InterlockedGetPointer(&Ctx->MiniportAdapterHandle);
|
||||||
@ -1073,9 +1074,10 @@ TunDispatchPnP(DEVICE_OBJECT *DeviceObject, IRP *Irp)
|
|||||||
{
|
{
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||||
case IRP_MN_SURPRISE_REMOVAL: {
|
case IRP_MN_SURPRISE_REMOVAL: {
|
||||||
KIRQL irql = ExAcquireSpinLockExclusive(&ctx->TransitionLock);
|
|
||||||
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_PRESENT);
|
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_PRESENT);
|
||||||
ExReleaseSpinLockExclusive(&ctx->TransitionLock, irql);
|
ExReleaseSpinLockExclusive(
|
||||||
|
&ctx->TransitionLock,
|
||||||
|
ExAcquireSpinLockExclusive(&ctx->TransitionLock)); // Ensure above change is visible to all readers.
|
||||||
TunQueueClear(ctx, NDIS_STATUS_ADAPTER_REMOVED);
|
TunQueueClear(ctx, NDIS_STATUS_ADAPTER_REMOVED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1109,9 +1111,10 @@ TunPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS Min
|
|||||||
{
|
{
|
||||||
TUN_CTX *ctx = (TUN_CTX *)MiniportAdapterContext;
|
TUN_CTX *ctx = (TUN_CTX *)MiniportAdapterContext;
|
||||||
|
|
||||||
KIRQL irql = ExAcquireSpinLockExclusive(&ctx->TransitionLock);
|
|
||||||
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_RUNNING);
|
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_RUNNING);
|
||||||
ExReleaseSpinLockExclusive(&ctx->TransitionLock, irql);
|
ExReleaseSpinLockExclusive(
|
||||||
|
&ctx->TransitionLock,
|
||||||
|
ExAcquireSpinLockExclusive(&ctx->TransitionLock)); // Ensure above change is visible to all readers.
|
||||||
TunQueueClear(ctx, NDIS_STATUS_PAUSED);
|
TunQueueClear(ctx, NDIS_STATUS_PAUSED);
|
||||||
|
|
||||||
return TunCompletePause(ctx, FALSE);
|
return TunCompletePause(ctx, FALSE);
|
||||||
@ -1468,9 +1471,10 @@ TunHaltEx(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction)
|
|||||||
ASSERT(!InterlockedGet64(&ctx->ActiveNBLCount)); // Adapter should not be halted if there are (potential)
|
ASSERT(!InterlockedGet64(&ctx->ActiveNBLCount)); // Adapter should not be halted if there are (potential)
|
||||||
// active NBLs present.
|
// active NBLs present.
|
||||||
|
|
||||||
KIRQL irql = ExAcquireSpinLockExclusive(&ctx->TransitionLock);
|
|
||||||
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_PRESENT);
|
InterlockedAnd(&ctx->Flags, ~TUN_FLAGS_PRESENT);
|
||||||
ExReleaseSpinLockExclusive(&ctx->TransitionLock, irql);
|
ExReleaseSpinLockExclusive(
|
||||||
|
&ctx->TransitionLock,
|
||||||
|
ExAcquireSpinLockExclusive(&ctx->TransitionLock)); // Ensure above change is visible to all readers.
|
||||||
|
|
||||||
for (IRP *pending_irp; (pending_irp = IoCsqRemoveNextIrp(&ctx->Device.ReadQueue.Csq, NULL)) != NULL;)
|
for (IRP *pending_irp; (pending_irp = IoCsqRemoveNextIrp(&ctx->Device.ReadQueue.Csq, NULL)) != NULL;)
|
||||||
TunCompleteRequest(ctx, pending_irp, STATUS_FILE_FORCED_CLOSED, IO_NO_INCREMENT);
|
TunCompleteRequest(ctx, pending_irp, STATUS_FILE_FORCED_CLOSED, IO_NO_INCREMENT);
|
||||||
|
Loading…
Reference in New Issue
Block a user