[NTOS:IO]

- Serialize device enumeration requests
CORE-8697 #resolve

svn path=/trunk/; revision=64952
This commit is contained in:
Thomas Faber 2014-10-24 10:03:42 +00:00
parent fcae57435c
commit 2b44442ffa
3 changed files with 50 additions and 25 deletions

View file

@ -1277,6 +1277,8 @@ extern ULONG IopNumTriageDumpDataBlocks;
extern PVOID IopTriageDumpDataBlocks[64]; extern PVOID IopTriageDumpDataBlocks[64];
extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList; extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList;
extern PDRIVER_OBJECT IopRootDriverObject; extern PDRIVER_OBJECT IopRootDriverObject;
extern KSPIN_LOCK IopDeviceRelationsSpinLock;
extern LIST_ENTRY IopDeviceRelationsRequestList;
// //
// Inlined Functions // Inlined Functions

View file

@ -385,6 +385,8 @@ IopInitializePlugPlayServices(VOID)
/* Initialize locks and such */ /* Initialize locks and such */
KeInitializeSpinLock(&IopDeviceTreeLock); KeInitializeSpinLock(&IopDeviceTreeLock);
KeInitializeSpinLock(&IopDeviceRelationsSpinLock);
InitializeListHead(&IopDeviceRelationsRequestList);
/* Get the default interface */ /* Get the default interface */
PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType(); PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();

View file

@ -30,12 +30,16 @@ extern BOOLEAN PnpSystemInit;
PDRIVER_OBJECT IopRootDriverObject; PDRIVER_OBJECT IopRootDriverObject;
PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL; PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList = NULL;
LIST_ENTRY IopDeviceRelationsRequestList;
WORK_QUEUE_ITEM IopDeviceRelationsWorkItem;
BOOLEAN IopDeviceRelationsRequestInProgress;
KSPIN_LOCK IopDeviceRelationsSpinLock;
typedef struct _INVALIDATE_DEVICE_RELATION_DATA typedef struct _INVALIDATE_DEVICE_RELATION_DATA
{ {
LIST_ENTRY RequestListEntry;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
DEVICE_RELATION_TYPE Type; DEVICE_RELATION_TYPE Type;
PIO_WORKITEM WorkItem;
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -890,20 +894,34 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
return Status; return Status;
} }
static VOID NTAPI static
IopAsynchronousInvalidateDeviceRelations( VOID
IN PDEVICE_OBJECT DeviceObject, NTAPI
IN PVOID InvalidateContext) IopDeviceRelationsWorker(
_In_ PVOID Context)
{ {
PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; PLIST_ENTRY ListEntry;
PINVALIDATE_DEVICE_RELATION_DATA Data;
KIRQL OldIrql;
IoSynchronousInvalidateDeviceRelations( KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
Data->DeviceObject, while (!IsListEmpty(&IopDeviceRelationsRequestList))
{
ListEntry = RemoveHeadList(&IopDeviceRelationsRequestList);
KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
Data = CONTAINING_RECORD(ListEntry,
INVALIDATE_DEVICE_RELATION_DATA,
RequestListEntry);
IoSynchronousInvalidateDeviceRelations(Data->DeviceObject,
Data->Type); Data->Type);
ObDereferenceObject(Data->DeviceObject); ObDereferenceObject(Data->DeviceObject);
IoFreeWorkItem(Data->WorkItem);
ExFreePool(Data); ExFreePool(Data);
KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
}
IopDeviceRelationsRequestInProgress = FALSE;
KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
} }
NTSTATUS NTSTATUS
@ -4670,29 +4688,32 @@ IoInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN DEVICE_RELATION_TYPE Type) IN DEVICE_RELATION_TYPE Type)
{ {
PIO_WORKITEM WorkItem;
PINVALIDATE_DEVICE_RELATION_DATA Data; PINVALIDATE_DEVICE_RELATION_DATA Data;
KIRQL OldIrql;
Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
if (!Data) if (!Data)
return; return;
WorkItem = IoAllocateWorkItem(DeviceObject);
if (!WorkItem)
{
ExFreePool(Data);
return;
}
ObReferenceObject(DeviceObject); ObReferenceObject(DeviceObject);
Data->DeviceObject = DeviceObject; Data->DeviceObject = DeviceObject;
Data->Type = Type; Data->Type = Type;
Data->WorkItem = WorkItem;
IoQueueWorkItem( KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql);
WorkItem, InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry);
IopAsynchronousInvalidateDeviceRelations, if (IopDeviceRelationsRequestInProgress)
DelayedWorkQueue, {
Data); KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
return;
}
IopDeviceRelationsRequestInProgress = TRUE;
KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql);
ExInitializeWorkItem(&IopDeviceRelationsWorkItem,
IopDeviceRelationsWorker,
NULL);
ExQueueWorkItem(&IopDeviceRelationsWorkItem,
DelayedWorkQueue);
} }
/* /*