Author: tfaber Date: Fri Oct 24 10:03:42 2014 New Revision: 64952
URL: http://svn.reactos.org/svn/reactos?rev=64952&view=rev Log: [NTOS:IO] - Serialize device enumeration requests CORE-8697 #resolve
Modified: trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Fri Oct 24 10:03:42 2014 @@ -1277,6 +1277,8 @@ extern PVOID IopTriageDumpDataBlocks[64]; extern PIO_BUS_TYPE_GUID_LIST PnpBusTypeGuidList; extern PDRIVER_OBJECT IopRootDriverObject; +extern KSPIN_LOCK IopDeviceRelationsSpinLock; +extern LIST_ENTRY IopDeviceRelationsRequestList;
// // Inlined Functions
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpinit.c [iso-8859-1] Fri Oct 24 10:03:42 2014 @@ -385,6 +385,8 @@
/* Initialize locks and such */ KeInitializeSpinLock(&IopDeviceTreeLock); + KeInitializeSpinLock(&IopDeviceRelationsSpinLock); + InitializeListHead(&IopDeviceRelationsRequestList);
/* Get the default interface */ PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Fri Oct 24 10:03:42 2014 @@ -30,12 +30,16 @@
PDRIVER_OBJECT IopRootDriverObject; 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 { + LIST_ENTRY RequestListEntry; PDEVICE_OBJECT DeviceObject; DEVICE_RELATION_TYPE Type; - PIO_WORKITEM WorkItem; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
/* FUNCTIONS *****************************************************************/ @@ -890,20 +894,34 @@ return Status; }
-static VOID NTAPI -IopAsynchronousInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InvalidateContext) -{ - PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; - - IoSynchronousInvalidateDeviceRelations( - Data->DeviceObject, - Data->Type); - - ObDereferenceObject(Data->DeviceObject); - IoFreeWorkItem(Data->WorkItem); - ExFreePool(Data); +static +VOID +NTAPI +IopDeviceRelationsWorker( + _In_ PVOID Context) +{ + PLIST_ENTRY ListEntry; + PINVALIDATE_DEVICE_RELATION_DATA Data; + KIRQL OldIrql; + + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + while (!IsListEmpty(&IopDeviceRelationsRequestList)) + { + ListEntry = RemoveHeadList(&IopDeviceRelationsRequestList); + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + Data = CONTAINING_RECORD(ListEntry, + INVALIDATE_DEVICE_RELATION_DATA, + RequestListEntry); + + IoSynchronousInvalidateDeviceRelations(Data->DeviceObject, + Data->Type); + + ObDereferenceObject(Data->DeviceObject); + ExFreePool(Data); + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + } + IopDeviceRelationsRequestInProgress = FALSE; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); }
NTSTATUS @@ -4670,29 +4688,32 @@ IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type) { - PIO_WORKITEM WorkItem; PINVALIDATE_DEVICE_RELATION_DATA Data; + KIRQL OldIrql;
Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); if (!Data) return; - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - ExFreePool(Data); - return; - }
ObReferenceObject(DeviceObject); Data->DeviceObject = DeviceObject; Data->Type = Type; - Data->WorkItem = WorkItem; - - IoQueueWorkItem( - WorkItem, - IopAsynchronousInvalidateDeviceRelations, - DelayedWorkQueue, - Data); + + KeAcquireSpinLock(&IopDeviceRelationsSpinLock, &OldIrql); + InsertTailList(&IopDeviceRelationsRequestList, &Data->RequestListEntry); + if (IopDeviceRelationsRequestInProgress) + { + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + return; + } + IopDeviceRelationsRequestInProgress = TRUE; + KeReleaseSpinLock(&IopDeviceRelationsSpinLock, OldIrql); + + ExInitializeWorkItem(&IopDeviceRelationsWorkItem, + IopDeviceRelationsWorker, + NULL); + ExQueueWorkItem(&IopDeviceRelationsWorkItem, + DelayedWorkQueue); }
/*