ReactOS 0.4.15-dev-7942-gd23573b
fxioqueuekm.cpp
Go to the documentation of this file.
1//
2// Copyright (C) Microsoft. All rights reserved.
3//
4#include "../ioprivshared.hpp"
5
6
7extern "C" {
8#if defined(EVENT_TRACING)
9#include "FxIoQueueKm.tmh"
10#endif
11}
12
17 )
18{
20 &Irp->Tail.Overlay.ListEntry);
21
22 Irp->Tail.Overlay.DriverContext[FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY] =
24
26
27 if (Irp->Cancel) {
29
30 Irp->Tail.Overlay.DriverContext[FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY] = NULL;
31
32 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
33 InitializeListHead(&Irp->Tail.Overlay.ListEntry);
34
35 return STATUS_CANCELLED;
36 }
37 else {
38 //
39 // CancelRoutine will complete the IRP
40 //
41 DO_NOTHING();
42 }
43 }
44
46
47 return STATUS_PENDING;
48}
49
50
52PIRP
55 )
56/*++
57
58 Routine Description:
59 Remove an IRP from the pending irp list if it matches with the input
60 fileobject. If the fileobject value is NULL, return the first one from
61 the pending list.
62
63--*/
64{
65 PIRP pIrp;
66 PLIST_ENTRY thisEntry, nextEntry, listHead;
67 PIO_STACK_LOCATION pIrpStack;
68
69 pIrp = NULL;
71
72 for(thisEntry = listHead->Flink;
73 thisEntry != listHead;
74 thisEntry = nextEntry) {
75 nextEntry = thisEntry->Flink;
76
77 pIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry);
79
80 if (FileObject == NULL || FileObject == pIrpStack->FileObject) {
81
82 RemoveEntryList(thisEntry);
83 InitializeListHead(thisEntry);
84
85 if (NULL != IoSetCancelRoutine (pIrp, NULL)) {
86 pIrp->Tail.Overlay.DriverContext[FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY] = NULL;
87 break;
88 }
89 else {
90 //
91 // Irp is canceled and the cancel routines is waiting to run.
92 // Continue to get the next the irp in the list.
93 //
94 DO_NOTHING();
95 }
96 }
97
98 pIrp = NULL;
99 }
100
101 return pIrp;
102}
103
104VOID
107 )
108/*++
109
110Routine Description:
111 Called from dispose to Free all the reserved requests.
112
113 Verify -
114 TRUE - Make sure the number of request freed matches with the count of
115 request created.
116 FALSE - Called when we fail to allocate all the reserved requests
117 during config at init time. So we don't verify because the
118 count of request freed wouldn't match with the configured value.
119--*/
120{
121 ULONG count;
122 KIRQL oldIrql;
123
124 count = 0;
125
126 //
127 // Since forward progress request are allocated only for top level
128 // queues which cant be deleted so we dont need to add a reference on the
129 // queue for each reserved request since the Queue is guaranteed to be
130 // around when the request is being freed even if the Request was forwarded
131 // to another Queue.
132 //
133 m_FwdProgContext->m_PendedReserveLock.Acquire(&oldIrql);
134
138
141 pEntry);
143
144 count++;
145 }
146
147 if (Verify) {
149 }
150
153
154 m_FwdProgContext->m_PendedReserveLock.Release(oldIrql);
155
156 return;
157}
158
159VOID
161 __in FxRequest *ReservedRequest
162 )
163/*++
164
165Routine Description:
166 Reuse the ReservedRequest if there are pended IRPs otherwise
167 add it back to the reserve list.
168
169--*/
170{
171 KIRQL oldIrql;
172 PIRP pIrp;
174
176 pIrp= NULL;
177
178 ASSERT(ReservedRequest->GetRefCnt() == 1);
179
181 ReservedRequest->ClearVerifierFlags(
183 }
184
185 //
186 // Reuse the reserved request for dispatching the next pending IRP.
187 //
188 m_FwdProgContext->m_PendedReserveLock.Acquire(&oldIrql);
189
191
192 m_FwdProgContext->m_PendedReserveLock.Release(oldIrql);
193
194 ReservedRequest->ClearFieldsForReuse();
195
196 if (pIrp != NULL) {
197 //
198 // Associate the reserved request with the Pended IRP
199 //
200 ReservedRequest->m_Irp.SetIrp(pIrp);
201 ReservedRequest->AssignMemoryBuffers(m_Device->GetIoType());
202
204 ReservedRequest->SetVerifierFlags(
206 }
207
208 //
209 // Ignore the return status because QueueRequest will complete the
210 // request on it own if it fails to queue request.
211 //
212 (VOID) QueueRequest(ReservedRequest);
213 }
214 else {
215 PutBackReservedRequest(ReservedRequest);
216 }
217}
218
219VOID
221 __in PLIST_ENTRY IrpListHead,
223 )
224/*++
225
226Routine Description:
227
228 This function is called to retrieve the list of reserved queued IRPs.
229 The IRP's Tail.Overlay.ListEntry field is used to link these structs together.
230
231--*/
232{
233 PIRP irp;
234 KIRQL irql;
235
237
238 do {
240 if (irp != NULL) {
241 //
242 // Add it to the cleanupList. We will complete the IRP after
243 // releasing the lock.
244 //
245 InsertTailList(IrpListHead, &irp->Tail.Overlay.ListEntry);
246 }
247 } while (irp != NULL);
248
250}
251
252VOID
256 )
257/*++
258
259Routine Description:
260
261 Cancel routine for forward progress irp.
262
263--*/
264{
265 KIRQL irql;
266 PFXIO_FORWARD_PROGRESS_CONTEXT m_FwdPrgContext;
267
269
270 IoReleaseCancelSpinLock(Irp->CancelIrql);
271
272 m_FwdPrgContext = (PFXIO_FORWARD_PROGRESS_CONTEXT)
273 Irp->Tail.Overlay.DriverContext[FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY];
274
275 Irp->Tail.Overlay.DriverContext[FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY] = NULL;
276
277 m_FwdPrgContext->m_PendedReserveLock.Acquire(&irql);
278
279 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
280 InitializeListHead(&Irp->Tail.Overlay.ListEntry);
281
282 m_FwdPrgContext->m_PendedReserveLock.Release(irql);
283
284 Irp->IoStatus.Status = STATUS_CANCELLED;
285 Irp->IoStatus.Information = 0;
287
288 return;
289}
290
291VOID
293 VOID
294 )
295/*++
296
297Routine Description:
298
299 This is the kernel mode routine to flush queued DPCs.
300
301Arguments:
302
303Return Value:
304
305--*/
306{
308}
309
310
311VOID
313 VOID
314 )
315/*++
316
317Routine Description:
318
319 This is the kernel mode routine to insert a dpc.
320
321Arguments:
322
323Return Value:
324
325--*/
326{
328}
329
333 __in MdIrp Irp,
334 __deref_out_opt FxRequest **ReservedRequest
335 )
336/*++
337
338Routine Description:
339 Use the policy configured on the queue to decide whether to allocate a
340 reserved request.
341
342--*/
343{
346 KIRQL oldIrql;
349
351
352 *ReservedRequest = NULL;
354
355 switch (m_FwdProgContext->m_Policy) {
356
358 if (IsPagingIo(Irp)) {
360 }
361 else {
363 }
364
365 break;
367
369 break;
370
372
373 //
374 // Call the driver to figure out what action to take.
375 //
377
379
380 //
381 // Make sure the use has returned a valid action
382 //
385
389 "EvtIoExamineIrp callback on WDFQUEUE %p returned an "
390 "invalid action %d, %!STATUS!",
392
394
395 return status;
396 }
397
398 }
399 break;
400
401 default:
402 ASSERTMSG("Invalid forward progress setting ", FALSE);
403 break;
404 }
405
410 "Forward action on WDFQUEUE %p says that framework should fail "
411 "the Irp %p, %!STATUS!",
412 GetHandle(), Irp, status);
413
414 return status;
415 }
416
417 pRequest = NULL;
418
419 m_FwdProgContext->m_PendedReserveLock.Acquire(&oldIrql);
420
423
425
427 pEntry);
428 ASSERT(pRequest != NULL);
429 ASSERT(pRequest->GetRefCnt() == 1);
430
433
436
439 }
440
441 //
442 // if *ReservedRequest is non-null the caller needs to free the
443 // previous request it allocated.
444 //
445 *ReservedRequest = pRequest;
446
448 }
449 else {
450
452 ASSERT(*ReservedRequest == NULL);
453 }
454
455 m_FwdProgContext->m_PendedReserveLock.Release(oldIrql);
456
457 return status;
458}
459
464 )
465/*++
466
467Routine Description:
468 Configure the queue for forward Progress.
469
470--*/
471{
474 ULONG index;
476
478
479 //
480 // If the queue is not a top level queue then return an error
481 //
483
484 //
485 // From v1.11 any queue can be top level (see WdfDeviceWdmDispatchIrpToIoQueue API).
486 //
488 if (m_PkgIo->IsTopLevelQueue(this) == FALSE) {
492 "Setting Forward progress policy on non-top level queue %!STATUS!",
493 status);
494
495 return status;
496 }
497 }
498
500 FxPoolAllocate(GetDriverGlobals(),
503 );
504 if (m_FwdProgContext == NULL) {
508 "Could not allocate memory for forward progress context %!STATUS!",
509 status);
510
511 return status;
512 }
513
514 *m_FwdProgContext = {};
515
516 //
517 // Initialize the things which will not fail first
518 //
519 m_FwdProgContext->m_Policy = Policy->ForwardProgressReservedPolicy;
520
522 Policy->TotalForwardProgressRequests;
523
525 Policy->EvtIoAllocateResourcesForReservedRequest;
526
528 Policy->EvtIoAllocateRequestResources;
529
531 Policy->ForwardProgressReservePolicySettings.Policy.\
532 ExaminePolicy.EvtIoWdmIrpForForwardProgress;
533
537
539
540 for (index = 0;
542 index++)
543 {
545 if (!NT_SUCCESS(status)) {
546 break;
547 }
548
551 }
552
553 //
554 // Since we allow forward progress policy to be set even after AddDevice
555 // when the queue has already started dispatching, we need to make
556 // sure all checks which determine whether the queue is configured for
557 // forward progress succeed. Setting Forward progress on the queue as the
558 // last operation helps with that.
559 //
560 if (NT_SUCCESS(status)) {
562 }
563 else {
565
567
570 }
571
572 return status;
573}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
__inline WDF_DEVICE_IO_TYPE GetIoType(VOID)
Definition: fxdevice.hpp:1084
PFN_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST Method
PFN_WDF_IO_ALLOCATE_REQUEST_RESOURCES Method
PFN_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS Method
WDF_IO_FORWARD_PROGRESS_ACTION Invoke(__in WDFQUEUE Queue, __in PIRP Irp)
BOOLEAN IsPagingIo(__in MdIrp Irp)
Definition: fxioqueuekm.hpp:30
PFXIO_FORWARD_PROGRESS_CONTEXT m_FwdProgContext
Definition: fxioqueue.hpp:241
static MdCancelRoutineType _WdmCancelRoutineForReservedIrp
Definition: fxioqueue.hpp:1703
_Must_inspect_result_ NTSTATUS QueueRequest(__in FxRequest *pRequest)
Definition: fxioqueue.cpp:2245
_Must_inspect_result_ NTSTATUS GetReservedRequest(__in MdIrp Irp, __deref_out_opt FxRequest **ReservedRequest)
VOID ReturnReservedRequest(__in FxRequest *ReservedRequest)
_Must_inspect_result_ NTSTATUS AssignForwardProgressPolicy(__in PWDF_IO_QUEUE_FORWARD_PROGRESS_POLICY Policy)
VOID PutBackReservedRequest(__in FxRequest *ReservedRequest)
Definition: fxioqueue.hpp:1624
BOOLEAN m_SupportForwardProgress
Definition: fxioqueue.hpp:246
_Must_inspect_result_ MdIrp GetForwardProgressIrpLocked(__in_opt PFILE_OBJECT FileObject)
Definition: fxioqueueum.hpp:60
VOID FreeAllReservedRequests(__in BOOLEAN Verify)
Definition: fxioqueueum.hpp:81
_Must_inspect_result_ NTSTATUS QueueForwardProgressIrpLocked(__in MdIrp Irp)
Definition: fxioqueueum.hpp:46
_Must_inspect_result_ NTSTATUS AllocateReservedRequest(__deref_out FxRequest **Request)
Definition: fxioqueue.cpp:6359
VOID FlushQueuedDpcs(VOID)
KDPC m_Dpc
Definition: fxioqueue.hpp:554
VOID GetForwardProgressIrps(__in PLIST_ENTRY IrpListHead, __in_opt MdFileObject FileObject)
VOID InsertQueueDpc(VOID)
FxPkgIo * m_PkgIo
Definition: fxioqueue.hpp:420
PLIST_ENTRY ListEntry()
Definition: fxirpum.cpp:535
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
LONG GetRefCnt(VOID)
Definition: fxobject.hpp:758
__inline BOOLEAN IsTopLevelQueue(__in FxIoQueue *Queue)
Definition: fxpkgio.hpp:373
__inline VOID SetVerifierFlags(__in SHORT Flags)
__inline PLIST_ENTRY GetListEntry(__in FxListEntryNames Index)
Definition: fxrequest.hpp:475
VOID AssignMemoryBuffers(__in WDF_DEVICE_IO_TYPE IoType)
Definition: fxrequest.hpp:1372
VOID FreeRequest(VOID)
Definition: fxrequest.cpp:1022
static FxRequest * _FromOwnerListEntry(__in FxListEntryNames Index, __in PLIST_ENTRY OwnerListEntry)
Definition: fxrequest.hpp:489
__inline VOID Uninitialize()
Definition: mxlockkm.h:104
__inline VOID Initialize()
Definition: mxlockkm.h:43
_In_ PIRP Irp
Definition: csq.h:116
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __deref_out_opt
Definition: dbghelp.h:29
#define TRACINGIO
Definition: dbgtrace.h:66
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
@ Verify
Definition: msg.c:1065
const WCHAR * action
Definition: action.c:7479
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
KIRQL irql
Definition: wave.h:1
#define __drv_useCancelIRQL
Definition: driverspecs.h:332
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxRequest * pRequest
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
struct _FXIO_FORWARD_PROGRESS_CONTEXT * PFXIO_FORWARD_PROGRESS_CONTEXT
struct _FXIO_FORWARD_PROGRESS_CONTEXT FXIO_FORWARD_PROGRESS_CONTEXT
#define FX_IRP_QUEUE_CSQ_CONTEXT_ENTRY
Definition: fxirpqueue.hpp:47
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
@ FxListEntryForwardProgress
Definition: fxrequest.hpp:381
FxIrp * pIrp
FxIrp * irp
@ FXREQUEST_FLAG_RESERVED_REQUEST_ASSOCIATED_WITH_IRP
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
PFILE_OBJECT MdFileObject
Definition: mxgeneralkm.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
WDF_IO_FORWARD_PROGRESS_RESERVED_POLICY m_Policy
Definition: fxioqueue.hpp:168
FxIoQueueForwardProgressAllocateResourcesReserved m_IoReservedResourcesAllocate
Definition: fxioqueue.hpp:156
FxIoQueueForwardProgressAllocateResources m_IoResourcesAllocate
Definition: fxioqueue.hpp:160
FxIoQueueForwardProgressExamineIrp m_IoExamineIrp
Definition: fxioqueue.hpp:164
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:653
@ WdfIoForwardProgressReservedPolicyPagingIO
Definition: wdfio.h:469
@ WdfIoForwardProgressReservedPolicyAlwaysUseReservedRequest
Definition: wdfio.h:467
@ WdfIoForwardProgressReservedPolicyUseExamine
Definition: wdfio.h:468
@ WdfIoForwardProgressActionUseReservedRequest
Definition: wdfio.h:462
@ WdfIoForwardProgressActionInvalid
Definition: wdfio.h:460
@ WdfIoForwardProgressActionFailRequest
Definition: wdfio.h:461
enum _WDF_IO_FORWARD_PROGRESS_ACTION WDF_IO_FORWARD_PROGRESS_ACTION
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998