From 1e93f0d10d16323805ecdd87ca8222a90370f7be Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 8 Nov 2016 15:31:15 -0800 Subject: [PATCH] sys: request work item refactoring --- src/sys/driver.h | 29 +++++++++++++++++++---------- src/sys/iop.c | 36 +++++++++++++++++++++++++++++++++--- src/sys/wq.c | 23 +++++++++++------------ 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/sys/driver.h b/src/sys/driver.h index 2e68312d..3a651357 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -679,18 +679,25 @@ VOID FspMetaCacheInvalidateItem(FSP_META_CACHE *MetaCache, UINT64 ItemIndex); #define FSP_FSCTL_TRANSACT_REQ_ALIGNMENT 16 enum { - FspIopRequestMustSucceed = 0x01, - FspIopRequestNonPaged = 0x02, + FspIopCreateRequestMustSucceed = 0x01, + FspIopCreateRequestNonPaged = 0x02, + FspIopCreateRequestWorkItem = 0x04, }; typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]); typedef NTSTATUS FSP_IOP_REQUEST_WORK( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN CanWait); typedef struct +{ + FSP_IOP_REQUEST_WORK *WorkRoutine; + WORK_QUEUE_ITEM WorkQueueItem; +} FSP_FSCTL_TRANSACT_REQ_WORK_ITEM; +typedef struct { FSP_IOP_REQUEST_FINI *RequestFini; PVOID Context[4]; FSP_FSCTL_TRANSACT_RSP *Response; + FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *WorkItem; __declspec(align(FSP_FSCTL_TRANSACT_REQ_ALIGNMENT)) UINT8 RequestBuf[]; } FSP_FSCTL_TRANSACT_REQ_HEADER; FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FSCTL_TRANSACT_REQ_HEADER) <= 64, @@ -702,6 +709,12 @@ PVOID *FspIopRequestContextAddress(FSP_FSCTL_TRANSACT_REQ *Request, ULONG I) FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); return &RequestHeader->Context[I]; } +static inline +FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *FspIopRequestWorkItem(FSP_FSCTL_TRANSACT_REQ *Request) +{ + FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader); + return RequestHeader->WorkItem; +} NTSTATUS FspIopCreateRequestFunnel( PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, ULONG Flags, FSP_FSCTL_TRANSACT_REQ **PRequest); @@ -729,13 +742,13 @@ VOID FspIrpDeleteRequest(PIRP Irp) #define FspIopCreateRequest(I, F, E, P) \ FspIopCreateRequestFunnel(I, F, E, 0, 0, P) #define FspIopCreateRequestMustSucceed(I, F, E, P)\ - FspIopCreateRequestFunnel(I, F, E, 0, FspIopRequestMustSucceed, P) + FspIopCreateRequestFunnel(I, F, E, 0, FspIopCreateRequestMustSucceed, P) #define FspIopCreateRequestEx(I, F, E, RF, P)\ FspIopCreateRequestFunnel(I, F, E, RF, 0, P) #define FspIopCreateRequestMustSucceedEx(I, F, E, RF, P)\ - FspIopCreateRequestFunnel(I, F, E, RF, FspIopRequestMustSucceed, P) -#define FspIopCreateRequestWorkItem(I, E, RF, P)\ - FspIopCreateRequestFunnel(I, 0, E, RF, FspIopRequestNonPaged, P) + FspIopCreateRequestFunnel(I, F, E, RF, FspIopCreateRequestMustSucceed, P) +#define FspIopCreateRequestAndWorkItem(I, E, RF, P)\ + FspIopCreateRequestFunnel(I, 0, E, RF, FspIopCreateRequestWorkItem, P) #define FspIopRequestContext(Request, I)\ (*FspIopRequestContextAddress(Request, I)) #define FspIopPostWorkRequest(D, R) FspIopPostWorkRequestFunnel(D, R, FALSE) @@ -744,10 +757,6 @@ VOID FspIrpDeleteRequest(PIRP Irp) #define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE) /* work queue processing */ -enum -{ - FspWqRequestWorkRoutine = 3, -}; NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, BOOLEAN CreateAndPost); diff --git a/src/sys/iop.c b/src/sys/iop.c index 5529d149..b1b38cae 100644 --- a/src/sys/iop.c +++ b/src/sys/iop.c @@ -63,6 +63,7 @@ NTSTATUS FspIopCreateRequestFunnel( PAGED_CODE(); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader; + FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = 0; FSP_FSCTL_TRANSACT_REQ *Request; *PRequest = 0; @@ -73,19 +74,42 @@ NTSTATUS FspIopCreateRequestFunnel( if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) return STATUS_INVALID_PARAMETER; - if (FlagOn(Flags, FspIopRequestMustSucceed)) + if (FlagOn(Flags, FspIopCreateRequestMustSucceed)) + { RequestHeader = FspAllocatePoolMustSucceed( - FlagOn(Flags, FspIopRequestNonPaged) ? NonPagedPool : PagedPool, + FlagOn(Flags, FspIopCreateRequestNonPaged) ? NonPagedPool : PagedPool, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, FSP_ALLOC_INTERNAL_TAG); + + if (FlagOn(Flags, FspIopCreateRequestWorkItem)) + { + RequestWorkItem = FspAllocatePoolMustSucceed( + NonPagedPool, sizeof *RequestWorkItem, FSP_ALLOC_INTERNAL_TAG); + + RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem); + } + } else { RequestHeader = ExAllocatePoolWithTag( - FlagOn(Flags, FspIopRequestNonPaged) ? NonPagedPool : PagedPool, + FlagOn(Flags, FspIopCreateRequestNonPaged) ? NonPagedPool : PagedPool, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, FSP_ALLOC_INTERNAL_TAG); if (0 == RequestHeader) return STATUS_INSUFFICIENT_RESOURCES; + + if (FlagOn(Flags, FspIopCreateRequestWorkItem)) + { + RequestWorkItem = ExAllocatePoolWithTag( + NonPagedPool, sizeof *RequestWorkItem, FSP_ALLOC_INTERNAL_TAG); + if (0 == RequestWorkItem) + { + FspFree(RequestHeader); + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem); + } } #if 0 != REQ_HEADER_ALIGN_MASK @@ -97,6 +121,7 @@ NTSTATUS FspIopCreateRequestFunnel( RtlZeroMemory(RequestHeader, sizeof *RequestHeader + sizeof *Request + ExtraSize); RequestHeader->RequestFini = RequestFini; + RequestHeader->WorkItem = RequestWorkItem; Request = (PVOID)RequestHeader->RequestBuf; Request->Size = (UINT16)(sizeof *Request + ExtraSize); @@ -110,6 +135,8 @@ NTSTATUS FspIopCreateRequestFunnel( Request->FileName.Size = FileName->Length + sizeof(WCHAR); } + ASSERT(0 == ((UINT_PTR)Request & (FSP_FSCTL_TRANSACT_REQ_ALIGNMENT - 1))); + if (0 != Irp) { ASSERT(0 == FspIrpRequest(Irp)); @@ -132,6 +159,9 @@ VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request) if (0 != RequestHeader->Response) FspFree(RequestHeader->Response); + if (0 != RequestHeader->WorkItem) + FspFree(RequestHeader->WorkItem); + #if 0 != REQ_HEADER_ALIGN_MASK RequestHeader = ((PVOID *)RequestHeader)[-1]; #endif diff --git a/src/sys/wq.c b/src/sys/wq.c index b4501091..1c9bd19a 100644 --- a/src/sys/wq.c +++ b/src/sys/wq.c @@ -24,6 +24,7 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, BOOLEAN CreateAndPost) { FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem; if (0 == Request) { @@ -42,16 +43,13 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, return Result; } - Result = FspIopCreateRequestWorkItem(Irp, sizeof(WORK_QUEUE_ITEM), - RequestFini, &Request); + Result = FspIopCreateRequestAndWorkItem(Irp, 0, RequestFini, &Request); if (!NT_SUCCESS(Result)) return Result; - ASSERT(sizeof(FSP_IOP_REQUEST_WORK *) == sizeof(PVOID)); - - FspIopRequestContext(Request, FspWqRequestWorkRoutine) = - (PVOID)(UINT_PTR)WorkRoutine; - ExInitializeWorkItem((PWORK_QUEUE_ITEM)&Request->Buffer, FspWqWorkRoutine, Irp); + RequestWorkItem = FspIopRequestWorkItem(Request); + RequestWorkItem->WorkRoutine = WorkRoutine; + ExInitializeWorkItem(&RequestWorkItem->WorkQueueItem, FspWqWorkRoutine, Irp); } if (!CreateAndPost) @@ -64,13 +62,14 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, VOID FspWqPostIrpWorkItem(PIRP Irp) { FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = FspIopRequestWorkItem(Request); - ASSERT(Request->Kind == FspFsctlTransactReservedKind); - ASSERT(Request->Size == sizeof *Request + sizeof(WORK_QUEUE_ITEM)); ASSERT(Request->Hint == (UINT_PTR)Irp); + ASSERT(0 != RequestWorkItem); + ASSERT(0 != RequestWorkItem->WorkRoutine); IoMarkIrpPending(Irp); - ExQueueWorkItem((PWORK_QUEUE_ITEM)&Request->Buffer, CriticalWorkQueue); + ExQueueWorkItem(&RequestWorkItem->WorkQueueItem, CriticalWorkQueue); } static VOID FspWqWorkRoutine(PVOID Context) @@ -79,8 +78,8 @@ static VOID FspWqWorkRoutine(PVOID Context) PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); - FSP_IOP_REQUEST_WORK *WorkRoutine = (FSP_IOP_REQUEST_WORK *)(UINT_PTR) - FspIopRequestContext(Request, FspWqRequestWorkRoutine); + FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = FspIopRequestWorkItem(Request); + FSP_IOP_REQUEST_WORK *WorkRoutine = RequestWorkItem->WorkRoutine; NTSTATUS Result; IoSetTopLevelIrp(Irp);