From e53ba61f844fb9f80890e90d03044d2585226eca Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 22 Dec 2015 21:58:39 -0800 Subject: [PATCH] sys: ioq: change IRP timeout handling --- src/sys/device.c | 10 +++++----- src/sys/driver.h | 6 ++++-- src/sys/ioq.c | 16 ++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/sys/device.c b/src/sys/device.c index 7b039a93..7233ec14 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -266,6 +266,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) NTSTATUS Result; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); + LARGE_INTEGER IrpTimeout; /* initialize our timer routine */ #pragma prefast(suppress:28133, "We are a filesystem: we do not have AddDevice") @@ -286,7 +287,9 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) ExInitializeResourceLite(&FsvolDeviceExtension->DeleteResource); /* setup our Ioq and expiration fields */ - FspIoqInitialize(&FsvolDeviceExtension->Ioq, FspIopCompleteCanceledIrp); + IrpTimeout.QuadPart = FsvolDeviceExtension->VolumeParams.IrpTimeout * 10000; + /* convert millis to nanos */ + FspIoqInitialize(&FsvolDeviceExtension->Ioq, &IrpTimeout, FspIopCompleteCanceledIrp); KeInitializeSpinLock(&FsvolDeviceExtension->ExpirationLock); ExInitializeWorkItem(&FsvolDeviceExtension->ExpirationWorkItem, FspFsvolDeviceExpirationRoutine, DeviceObject); @@ -396,12 +399,9 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context) PDEVICE_OBJECT DeviceObject = Context; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); - LARGE_INTEGER Timeout; KIRQL Irql; - Timeout.QuadPart = FsvolDeviceExtension->VolumeParams.IrpTimeout * 10000; - /* convert millis to nanos */ - FspIoqRemoveExpired(&FsvolDeviceExtension->Ioq, &Timeout); + FspIoqRemoveExpired(&FsvolDeviceExtension->Ioq); KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql); FsvolDeviceExtension->ExpirationInProgress = FALSE; diff --git a/src/sys/driver.h b/src/sys/driver.h index 4be65ecb..444a2ee1 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -305,12 +305,14 @@ typedef struct KEVENT PendingIrpEvent; LIST_ENTRY PendingIrpList, ProcessIrpList; IO_CSQ PendingIoCsq, ProcessIoCsq; + LARGE_INTEGER IrpTimeout; VOID (*CompleteCanceledIrp)(PIRP Irp); } FSP_IOQ; -VOID FspIoqInitialize(FSP_IOQ *Ioq, VOID (*CompleteCanceledIrp)(PIRP Irp)); +VOID FspIoqInitialize(FSP_IOQ *Ioq, + PLARGE_INTEGER IrpTimeout, VOID (*CompleteCanceledIrp)(PIRP Irp)); VOID FspIoqStop(FSP_IOQ *Ioq); BOOLEAN FspIoqStopped(FSP_IOQ *Ioq); -VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout); +VOID FspIoqRemoveExpired(FSP_IOQ *Ioq); BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp); PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout); BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); diff --git a/src/sys/ioq.c b/src/sys/ioq.c index cc527e86..59f38e1d 100644 --- a/src/sys/ioq.c +++ b/src/sys/ioq.c @@ -188,7 +188,8 @@ static VOID FspIoqProcessCompleteCanceledIrp(PIO_CSQ IoCsq, PIRP Irp) Ioq->CompleteCanceledIrp(Irp); } -VOID FspIoqInitialize(FSP_IOQ *Ioq, VOID (*CompleteCanceledIrp)(PIRP Irp)) +VOID FspIoqInitialize(FSP_IOQ *Ioq, + PLARGE_INTEGER IrpTimeout, VOID (*CompleteCanceledIrp)(PIRP Irp)) { ASSERT(0 != CompleteCanceledIrp); @@ -211,6 +212,7 @@ VOID FspIoqInitialize(FSP_IOQ *Ioq, VOID (*CompleteCanceledIrp)(PIRP Irp)) FspIoqProcessAcquireLock, FspIoqProcessReleaseLock, FspIoqProcessCompleteCanceledIrp); + Ioq->IrpTimeout = *IrpTimeout; Ioq->CompleteCanceledIrp = CompleteCanceledIrp; } @@ -239,15 +241,11 @@ BOOLEAN FspIoqStopped(FSP_IOQ *Ioq) return Result; } -VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout) +VOID FspIoqRemoveExpired(FSP_IOQ *Ioq) { FSP_IOQ_PEEK_CONTEXT PeekContext; PeekContext.IrpHint = 0; PeekContext.ExpirationTime = KeQueryInterruptTime(); - if (PeekContext.ExpirationTime >= (ULONGLONG)Timeout->QuadPart) - PeekContext.ExpirationTime -= Timeout->QuadPart; - else - PeekContext.ExpirationTime = 0; PIRP Irp; while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, &PeekContext))) Ioq->CompleteCanceledIrp(Irp); @@ -258,7 +256,8 @@ VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout) BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp) { NTSTATUS Result; - FspIrpTimestamp(Irp) = KeQueryInterruptTime(); + if (0 == FspIrpTimestamp(Irp)) + FspIrpTimestamp(Irp) = KeQueryInterruptTime() + Ioq->IrpTimeout.QuadPart; Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, 0); return NT_SUCCESS(Result); } @@ -284,7 +283,8 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout) BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp) { NTSTATUS Result; - FspIrpTimestamp(Irp) = KeQueryInterruptTime(); + if (0 == FspIrpTimestamp(Irp)) + FspIrpTimestamp(Irp) = KeQueryInterruptTime() + Ioq->IrpTimeout.QuadPart; Result = IoCsqInsertIrpEx(&Ioq->ProcessIoCsq, Irp, 0, 0); return NT_SUCCESS(Result); }