sys: ioq: change IRP timeout handling

This commit is contained in:
Bill Zissimopoulos 2015-12-22 21:58:39 -08:00
parent 1abbf5b0f6
commit e53ba61f84
3 changed files with 17 additions and 15 deletions

View File

@ -266,6 +266,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
NTSTATUS Result; NTSTATUS Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
LARGE_INTEGER IrpTimeout;
/* initialize our timer routine */ /* initialize our timer routine */
#pragma prefast(suppress:28133, "We are a filesystem: we do not have AddDevice") #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); ExInitializeResourceLite(&FsvolDeviceExtension->DeleteResource);
/* setup our Ioq and expiration fields */ /* 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); KeInitializeSpinLock(&FsvolDeviceExtension->ExpirationLock);
ExInitializeWorkItem(&FsvolDeviceExtension->ExpirationWorkItem, ExInitializeWorkItem(&FsvolDeviceExtension->ExpirationWorkItem,
FspFsvolDeviceExpirationRoutine, DeviceObject); FspFsvolDeviceExpirationRoutine, DeviceObject);
@ -396,12 +399,9 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
PDEVICE_OBJECT DeviceObject = Context; PDEVICE_OBJECT DeviceObject = Context;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
LARGE_INTEGER Timeout;
KIRQL Irql; KIRQL Irql;
Timeout.QuadPart = FsvolDeviceExtension->VolumeParams.IrpTimeout * 10000; FspIoqRemoveExpired(&FsvolDeviceExtension->Ioq);
/* convert millis to nanos */
FspIoqRemoveExpired(&FsvolDeviceExtension->Ioq, &Timeout);
KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql); KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql);
FsvolDeviceExtension->ExpirationInProgress = FALSE; FsvolDeviceExtension->ExpirationInProgress = FALSE;

View File

@ -305,12 +305,14 @@ typedef struct
KEVENT PendingIrpEvent; KEVENT PendingIrpEvent;
LIST_ENTRY PendingIrpList, ProcessIrpList; LIST_ENTRY PendingIrpList, ProcessIrpList;
IO_CSQ PendingIoCsq, ProcessIoCsq; IO_CSQ PendingIoCsq, ProcessIoCsq;
LARGE_INTEGER IrpTimeout;
VOID (*CompleteCanceledIrp)(PIRP Irp); VOID (*CompleteCanceledIrp)(PIRP Irp);
} FSP_IOQ; } 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); VOID FspIoqStop(FSP_IOQ *Ioq);
BOOLEAN FspIoqStopped(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); BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout); PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout);
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);

View File

@ -188,7 +188,8 @@ static VOID FspIoqProcessCompleteCanceledIrp(PIO_CSQ IoCsq, PIRP Irp)
Ioq->CompleteCanceledIrp(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); ASSERT(0 != CompleteCanceledIrp);
@ -211,6 +212,7 @@ VOID FspIoqInitialize(FSP_IOQ *Ioq, VOID (*CompleteCanceledIrp)(PIRP Irp))
FspIoqProcessAcquireLock, FspIoqProcessAcquireLock,
FspIoqProcessReleaseLock, FspIoqProcessReleaseLock,
FspIoqProcessCompleteCanceledIrp); FspIoqProcessCompleteCanceledIrp);
Ioq->IrpTimeout = *IrpTimeout;
Ioq->CompleteCanceledIrp = CompleteCanceledIrp; Ioq->CompleteCanceledIrp = CompleteCanceledIrp;
} }
@ -239,15 +241,11 @@ BOOLEAN FspIoqStopped(FSP_IOQ *Ioq)
return Result; return Result;
} }
VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout) VOID FspIoqRemoveExpired(FSP_IOQ *Ioq)
{ {
FSP_IOQ_PEEK_CONTEXT PeekContext; FSP_IOQ_PEEK_CONTEXT PeekContext;
PeekContext.IrpHint = 0; PeekContext.IrpHint = 0;
PeekContext.ExpirationTime = KeQueryInterruptTime(); PeekContext.ExpirationTime = KeQueryInterruptTime();
if (PeekContext.ExpirationTime >= (ULONGLONG)Timeout->QuadPart)
PeekContext.ExpirationTime -= Timeout->QuadPart;
else
PeekContext.ExpirationTime = 0;
PIRP Irp; PIRP Irp;
while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, &PeekContext))) while (0 != (Irp = IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, &PeekContext)))
Ioq->CompleteCanceledIrp(Irp); Ioq->CompleteCanceledIrp(Irp);
@ -258,7 +256,8 @@ VOID FspIoqRemoveExpired(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout)
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp) BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
{ {
NTSTATUS Result; NTSTATUS Result;
FspIrpTimestamp(Irp) = KeQueryInterruptTime(); if (0 == FspIrpTimestamp(Irp))
FspIrpTimestamp(Irp) = KeQueryInterruptTime() + Ioq->IrpTimeout.QuadPart;
Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, 0); Result = IoCsqInsertIrpEx(&Ioq->PendingIoCsq, Irp, 0, 0);
return NT_SUCCESS(Result); return NT_SUCCESS(Result);
} }
@ -284,7 +283,8 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, PLARGE_INTEGER Timeout)
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp) BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp)
{ {
NTSTATUS Result; NTSTATUS Result;
FspIrpTimestamp(Irp) = KeQueryInterruptTime(); if (0 == FspIrpTimestamp(Irp))
FspIrpTimestamp(Irp) = KeQueryInterruptTime() + Ioq->IrpTimeout.QuadPart;
Result = IoCsqInsertIrpEx(&Ioq->ProcessIoCsq, Irp, 0, 0); Result = IoCsqInsertIrpEx(&Ioq->ProcessIoCsq, Irp, 0, 0);
return NT_SUCCESS(Result); return NT_SUCCESS(Result);
} }