sys: request work item refactoring

This commit is contained in:
Bill Zissimopoulos 2016-11-08 15:31:15 -08:00
parent adeb847c7e
commit 1e93f0d10d
3 changed files with 63 additions and 25 deletions

View File

@ -679,18 +679,25 @@ VOID FspMetaCacheInvalidateItem(FSP_META_CACHE *MetaCache, UINT64 ItemIndex);
#define FSP_FSCTL_TRANSACT_REQ_ALIGNMENT 16 #define FSP_FSCTL_TRANSACT_REQ_ALIGNMENT 16
enum enum
{ {
FspIopRequestMustSucceed = 0x01, FspIopCreateRequestMustSucceed = 0x01,
FspIopRequestNonPaged = 0x02, FspIopCreateRequestNonPaged = 0x02,
FspIopCreateRequestWorkItem = 0x04,
}; };
typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]); typedef VOID FSP_IOP_REQUEST_FINI(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4]);
typedef NTSTATUS FSP_IOP_REQUEST_WORK( typedef NTSTATUS FSP_IOP_REQUEST_WORK(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN CanWait); BOOLEAN CanWait);
typedef struct typedef struct
{
FSP_IOP_REQUEST_WORK *WorkRoutine;
WORK_QUEUE_ITEM WorkQueueItem;
} FSP_FSCTL_TRANSACT_REQ_WORK_ITEM;
typedef struct
{ {
FSP_IOP_REQUEST_FINI *RequestFini; FSP_IOP_REQUEST_FINI *RequestFini;
PVOID Context[4]; PVOID Context[4];
FSP_FSCTL_TRANSACT_RSP *Response; FSP_FSCTL_TRANSACT_RSP *Response;
FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *WorkItem;
__declspec(align(FSP_FSCTL_TRANSACT_REQ_ALIGNMENT)) UINT8 RequestBuf[]; __declspec(align(FSP_FSCTL_TRANSACT_REQ_ALIGNMENT)) UINT8 RequestBuf[];
} FSP_FSCTL_TRANSACT_REQ_HEADER; } FSP_FSCTL_TRANSACT_REQ_HEADER;
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FSCTL_TRANSACT_REQ_HEADER) <= 64, 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); FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader = (PVOID)((PUINT8)Request - sizeof *RequestHeader);
return &RequestHeader->Context[I]; 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( NTSTATUS FspIopCreateRequestFunnel(
PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini, PIRP Irp, PUNICODE_STRING FileName, ULONG ExtraSize, FSP_IOP_REQUEST_FINI *RequestFini,
ULONG Flags, FSP_FSCTL_TRANSACT_REQ **PRequest); ULONG Flags, FSP_FSCTL_TRANSACT_REQ **PRequest);
@ -729,13 +742,13 @@ VOID FspIrpDeleteRequest(PIRP Irp)
#define FspIopCreateRequest(I, F, E, P) \ #define FspIopCreateRequest(I, F, E, P) \
FspIopCreateRequestFunnel(I, F, E, 0, 0, P) FspIopCreateRequestFunnel(I, F, E, 0, 0, P)
#define FspIopCreateRequestMustSucceed(I, F, E, 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)\ #define FspIopCreateRequestEx(I, F, E, RF, P)\
FspIopCreateRequestFunnel(I, F, E, RF, 0, P) FspIopCreateRequestFunnel(I, F, E, RF, 0, P)
#define FspIopCreateRequestMustSucceedEx(I, F, E, RF, P)\ #define FspIopCreateRequestMustSucceedEx(I, F, E, RF, P)\
FspIopCreateRequestFunnel(I, F, E, RF, FspIopRequestMustSucceed, P) FspIopCreateRequestFunnel(I, F, E, RF, FspIopCreateRequestMustSucceed, P)
#define FspIopCreateRequestWorkItem(I, E, RF, P)\ #define FspIopCreateRequestAndWorkItem(I, E, RF, P)\
FspIopCreateRequestFunnel(I, 0, E, RF, FspIopRequestNonPaged, P) FspIopCreateRequestFunnel(I, 0, E, RF, FspIopCreateRequestWorkItem, P)
#define FspIopRequestContext(Request, I)\ #define FspIopRequestContext(Request, I)\
(*FspIopRequestContextAddress(Request, I)) (*FspIopRequestContextAddress(Request, I))
#define FspIopPostWorkRequest(D, R) FspIopPostWorkRequestFunnel(D, R, FALSE) #define FspIopPostWorkRequest(D, R) FspIopPostWorkRequestFunnel(D, R, FALSE)
@ -744,10 +757,6 @@ VOID FspIrpDeleteRequest(PIRP Irp)
#define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE) #define FspIopCompleteIrp(I, R) FspIopCompleteIrpEx(I, R, TRUE)
/* work queue processing */ /* work queue processing */
enum
{
FspWqRequestWorkRoutine = 3,
};
NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp, NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini, FSP_IOP_REQUEST_WORK *WorkRoutine, FSP_IOP_REQUEST_FINI *RequestFini,
BOOLEAN CreateAndPost); BOOLEAN CreateAndPost);

View File

@ -63,6 +63,7 @@ NTSTATUS FspIopCreateRequestFunnel(
PAGED_CODE(); PAGED_CODE();
FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader; FSP_FSCTL_TRANSACT_REQ_HEADER *RequestHeader;
FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = 0;
FSP_FSCTL_TRANSACT_REQ *Request; FSP_FSCTL_TRANSACT_REQ *Request;
*PRequest = 0; *PRequest = 0;
@ -73,19 +74,42 @@ NTSTATUS FspIopCreateRequestFunnel(
if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize) if (FSP_FSCTL_TRANSACT_REQ_SIZEMAX < sizeof *Request + ExtraSize)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
if (FlagOn(Flags, FspIopRequestMustSucceed)) if (FlagOn(Flags, FspIopCreateRequestMustSucceed))
{
RequestHeader = FspAllocatePoolMustSucceed( RequestHeader = FspAllocatePoolMustSucceed(
FlagOn(Flags, FspIopRequestNonPaged) ? NonPagedPool : PagedPool, FlagOn(Flags, FspIopCreateRequestNonPaged) ? NonPagedPool : PagedPool,
sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD,
FSP_ALLOC_INTERNAL_TAG); FSP_ALLOC_INTERNAL_TAG);
if (FlagOn(Flags, FspIopCreateRequestWorkItem))
{
RequestWorkItem = FspAllocatePoolMustSucceed(
NonPagedPool, sizeof *RequestWorkItem, FSP_ALLOC_INTERNAL_TAG);
RtlZeroMemory(RequestWorkItem, sizeof *RequestWorkItem);
}
}
else else
{ {
RequestHeader = ExAllocatePoolWithTag( RequestHeader = ExAllocatePoolWithTag(
FlagOn(Flags, FspIopRequestNonPaged) ? NonPagedPool : PagedPool, FlagOn(Flags, FspIopCreateRequestNonPaged) ? NonPagedPool : PagedPool,
sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD, sizeof *RequestHeader + sizeof *Request + ExtraSize + REQ_HEADER_ALIGN_OVERHEAD,
FSP_ALLOC_INTERNAL_TAG); FSP_ALLOC_INTERNAL_TAG);
if (0 == RequestHeader) if (0 == RequestHeader)
return STATUS_INSUFFICIENT_RESOURCES; 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 #if 0 != REQ_HEADER_ALIGN_MASK
@ -97,6 +121,7 @@ NTSTATUS FspIopCreateRequestFunnel(
RtlZeroMemory(RequestHeader, sizeof *RequestHeader + sizeof *Request + ExtraSize); RtlZeroMemory(RequestHeader, sizeof *RequestHeader + sizeof *Request + ExtraSize);
RequestHeader->RequestFini = RequestFini; RequestHeader->RequestFini = RequestFini;
RequestHeader->WorkItem = RequestWorkItem;
Request = (PVOID)RequestHeader->RequestBuf; Request = (PVOID)RequestHeader->RequestBuf;
Request->Size = (UINT16)(sizeof *Request + ExtraSize); Request->Size = (UINT16)(sizeof *Request + ExtraSize);
@ -110,6 +135,8 @@ NTSTATUS FspIopCreateRequestFunnel(
Request->FileName.Size = FileName->Length + sizeof(WCHAR); Request->FileName.Size = FileName->Length + sizeof(WCHAR);
} }
ASSERT(0 == ((UINT_PTR)Request & (FSP_FSCTL_TRANSACT_REQ_ALIGNMENT - 1)));
if (0 != Irp) if (0 != Irp)
{ {
ASSERT(0 == FspIrpRequest(Irp)); ASSERT(0 == FspIrpRequest(Irp));
@ -132,6 +159,9 @@ VOID FspIopDeleteRequest(FSP_FSCTL_TRANSACT_REQ *Request)
if (0 != RequestHeader->Response) if (0 != RequestHeader->Response)
FspFree(RequestHeader->Response); FspFree(RequestHeader->Response);
if (0 != RequestHeader->WorkItem)
FspFree(RequestHeader->WorkItem);
#if 0 != REQ_HEADER_ALIGN_MASK #if 0 != REQ_HEADER_ALIGN_MASK
RequestHeader = ((PVOID *)RequestHeader)[-1]; RequestHeader = ((PVOID *)RequestHeader)[-1];
#endif #endif

View File

@ -24,6 +24,7 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
BOOLEAN CreateAndPost) BOOLEAN CreateAndPost)
{ {
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem;
if (0 == Request) if (0 == Request)
{ {
@ -42,16 +43,13 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
return Result; return Result;
} }
Result = FspIopCreateRequestWorkItem(Irp, sizeof(WORK_QUEUE_ITEM), Result = FspIopCreateRequestAndWorkItem(Irp, 0, RequestFini, &Request);
RequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
ASSERT(sizeof(FSP_IOP_REQUEST_WORK *) == sizeof(PVOID)); RequestWorkItem = FspIopRequestWorkItem(Request);
RequestWorkItem->WorkRoutine = WorkRoutine;
FspIopRequestContext(Request, FspWqRequestWorkRoutine) = ExInitializeWorkItem(&RequestWorkItem->WorkQueueItem, FspWqWorkRoutine, Irp);
(PVOID)(UINT_PTR)WorkRoutine;
ExInitializeWorkItem((PWORK_QUEUE_ITEM)&Request->Buffer, FspWqWorkRoutine, Irp);
} }
if (!CreateAndPost) if (!CreateAndPost)
@ -64,13 +62,14 @@ NTSTATUS FspWqCreateAndPostIrpWorkItem(PIRP Irp,
VOID FspWqPostIrpWorkItem(PIRP Irp) VOID FspWqPostIrpWorkItem(PIRP Irp)
{ {
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(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(Request->Hint == (UINT_PTR)Irp);
ASSERT(0 != RequestWorkItem);
ASSERT(0 != RequestWorkItem->WorkRoutine);
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
ExQueueWorkItem((PWORK_QUEUE_ITEM)&Request->Buffer, CriticalWorkQueue); ExQueueWorkItem(&RequestWorkItem->WorkQueueItem, CriticalWorkQueue);
} }
static VOID FspWqWorkRoutine(PVOID Context) static VOID FspWqWorkRoutine(PVOID Context)
@ -79,8 +78,8 @@ static VOID FspWqWorkRoutine(PVOID Context)
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject; PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
FSP_IOP_REQUEST_WORK *WorkRoutine = (FSP_IOP_REQUEST_WORK *)(UINT_PTR) FSP_FSCTL_TRANSACT_REQ_WORK_ITEM *RequestWorkItem = FspIopRequestWorkItem(Request);
FspIopRequestContext(Request, FspWqRequestWorkRoutine); FSP_IOP_REQUEST_WORK *WorkRoutine = RequestWorkItem->WorkRoutine;
NTSTATUS Result; NTSTATUS Result;
IoSetTopLevelIrp(Irp); IoSetTopLevelIrp(Irp);