https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6f0e37b042414a5b4530b…
commit 6f0e37b042414a5b4530b89f1bf2b719a6e9147f
Author: Victor Perevertkin <victor.perevertkin(a)reactos.org>
AuthorDate: Sun Nov 15 17:33:42 2020 +0300
Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org>
CommitDate: Mon Jan 4 16:50:32 2021 +0300
[NTOS:PNP][NTOS:IO] Do not create a device object + node on every driver load
- Remove the usage of IopCreateDeviceNode and change it to
PipAllocateDeviceNode where required
---
ntoskrnl/include/internal/io.h | 13 ++-----
ntoskrnl/io/iomgr/driver.c | 85 +++++-------------------------------------
ntoskrnl/io/pnpmgr/devaction.c | 16 ++++----
ntoskrnl/io/pnpmgr/devnode.c | 40 +++++++++++++++++---
ntoskrnl/io/pnpmgr/pnpreport.c | 13 +++----
5 files changed, 61 insertions(+), 106 deletions(-)
diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 628929f1cff..4e81a6f1c83 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -615,18 +615,14 @@ IopGetSystemPowerDeviceObject(
);
PDEVICE_NODE
-NTAPI
PipAllocateDeviceNode(
IN PDEVICE_OBJECT PhysicalDeviceObject
);
-NTSTATUS
-IopCreateDeviceNode(
- IN PDEVICE_NODE ParentNode,
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PUNICODE_STRING ServiceName,
- OUT PDEVICE_NODE *DeviceNode
-);
+VOID
+PiInsertDevNode(
+ _In_ PDEVICE_NODE DeviceNode,
+ _In_ PDEVICE_NODE ParentNode);
NTSTATUS
IopFreeDeviceNode(
@@ -1160,7 +1156,6 @@ IopLoadUnloadDriver(
NTSTATUS
FASTCALL
IopInitializeDriverModule(
- IN PDEVICE_NODE DeviceNode,
IN PLDR_DATA_TABLE_ENTRY ModuleObject,
IN PUNICODE_STRING ServiceName,
IN BOOLEAN FileSystemDriver,
diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index 3b033f9ab32..f3f4c5a79a8 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -464,10 +464,6 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
*
* Initialize a loaded driver.
*
- * Parameters
- * DeviceNode
- * Pointer to device node.
- *
* ModuleObject
* Module object representing the driver. It can be retrieve by
* IopLoadServiceModule.
@@ -485,7 +481,6 @@ MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
NTSTATUS
FASTCALL
IopInitializeDriverModule(
- IN PDEVICE_NODE DeviceNode,
IN PLDR_DATA_TABLE_ENTRY ModuleObject,
IN PUNICODE_STRING ServiceName,
IN BOOLEAN FileSystemDriver,
@@ -626,8 +621,7 @@ IopAttachFilterDriversCallback(
return Status;
}
- Status = IopInitializeDriverModule(DeviceNode,
- ModuleObject,
+ Status = IopInitializeDriverModule(ModuleObject,
&ServiceName,
FALSE,
&DriverObject);
@@ -827,7 +821,6 @@ NTSTATUS
NTAPI
IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
{
- PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
PWCHAR Buffer, FileNameWithoutPath;
@@ -885,21 +878,6 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
FileExtension[0] = UNICODE_NULL;
}
- /*
- * Determine the right device object
- */
- /* Use IopRootDeviceNode for now */
- Status = IopCreateDeviceNode(IopRootDeviceNode,
- NULL,
- &ServiceName,
- &DeviceNode);
- RtlFreeUnicodeString(&ServiceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName,
Status);
- return Status;
- }
-
/* Lookup the new Ldr entry in PsLoadedModuleList */
NextEntry = PsLoadedModuleList.Flink;
while (NextEntry != &PsLoadedModuleList)
@@ -919,23 +897,18 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
/*
* Initialize the driver
*/
- Status = IopInitializeDriverModule(DeviceNode,
- LdrEntry,
- &DeviceNode->ServiceName,
+ Status = IopInitializeDriverModule(LdrEntry,
+ &ServiceName,
FALSE,
&DriverObject);
+ RtlFreeUnicodeString(&ServiceName);
if (!NT_SUCCESS(Status))
{
+ DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName,
Status);
return Status;
}
- Status = IopInitializeDevice(DeviceNode, DriverObject);
- if (NT_SUCCESS(Status))
- {
- Status = IopStartDevice(DeviceNode);
- }
-
/* Remove extra reference from IopInitializeDriverModule */
ObDereferenceObject(DriverObject);
@@ -960,7 +933,6 @@ IopInitializeBootDrivers(VOID)
{
PLIST_ENTRY ListHead, NextEntry, NextEntry2;
PLDR_DATA_TABLE_ENTRY LdrEntry;
- PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
LDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
@@ -971,10 +943,6 @@ IopInitializeBootDrivers(VOID)
PBOOT_DRIVER_LIST_ENTRY BootEntry;
DPRINT("IopInitializeBootDrivers()\n");
- /* Use IopRootDeviceNode for now */
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode);
- if (!NT_SUCCESS(Status)) return;
-
/* Setup the module object for the RAW FS Driver */
ModuleObject.DllBase = NULL;
ModuleObject.SizeOfImage = 0;
@@ -982,8 +950,7 @@ IopInitializeBootDrivers(VOID)
RtlInitUnicodeString(&DriverName, L"RAW");
/* Initialize it */
- Status = IopInitializeDriverModule(DeviceNode,
- &ModuleObject,
+ Status = IopInitializeDriverModule(&ModuleObject,
&DriverName,
TRUE,
&DriverObject);
@@ -993,24 +960,6 @@ IopInitializeBootDrivers(VOID)
return;
}
- /* Now initialize the associated device */
- Status = IopInitializeDevice(DeviceNode, DriverObject);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- ObDereferenceObject(DriverObject);
- return;
- }
-
- /* Start it up */
- Status = IopStartDevice(DeviceNode);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- ObDereferenceObject(DriverObject);
- return;
- }
-
/* Get highest group order index */
IopGroupIndex = PpInitGetGroupOrderIndex(NULL);
if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
@@ -1943,7 +1892,6 @@ IopLoadUnloadDriver(
UNICODE_STRING ServiceName;
NTSTATUS Status;
ULONG Type;
- PDEVICE_NODE DeviceNode;
PLDR_DATA_TABLE_ENTRY ModuleObject;
PVOID BaseAddress;
WCHAR *cur;
@@ -2069,21 +2017,10 @@ IopLoadUnloadDriver(
/*
* Initialize the driver module if it's loaded for the first time
*/
- Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName,
&DeviceNode);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
- ExReleaseResourceLite(&IopDriverLoadResource);
- KeLeaveCriticalRegion();
- MmUnloadSystemImage(ModuleObject);
- return Status;
- }
+ IopDisplayLoadingMessage(&ServiceName);
- IopDisplayLoadingMessage(&DeviceNode->ServiceName);
-
- Status = IopInitializeDriverModule(DeviceNode,
- ModuleObject,
- &DeviceNode->ServiceName,
+ Status = IopInitializeDriverModule(ModuleObject,
+ &ServiceName,
(Type == SERVICE_FILE_SYSTEM_DRIVER ||
Type == SERVICE_RECOGNIZER_DRIVER),
DriverObject);
@@ -2098,10 +2035,6 @@ IopLoadUnloadDriver(
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
-
- /* Initialize and start device */
- IopInitializeDevice(DeviceNode, *DriverObject);
- Status = IopStartDevice(DeviceNode);
}
else
{
diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c
index 34d71e18a2e..99e4e2b944d 100644
--- a/ntoskrnl/io/pnpmgr/devaction.c
+++ b/ntoskrnl/io/pnpmgr/devaction.c
@@ -1079,8 +1079,10 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED)
{
/* Initialize the driver */
- Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
- &DeviceNode->ServiceName, FALSE, &DriverObject);
+ Status = IopInitializeDriverModule(ModuleObject,
+ &DeviceNode->ServiceName,
+ FALSE,
+ &DriverObject);
if (!NT_SUCCESS(Status))
DeviceNode->Problem = CM_PROB_FAILED_DRIVER_ENTRY;
}
@@ -2183,13 +2185,11 @@ PipEnumerateDevice(
if (!ChildDeviceNode)
{
/* One doesn't exist, create it */
- Status = IopCreateDeviceNode(
- DeviceNode,
- ChildDeviceObject,
- NULL,
- &ChildDeviceNode);
- if (NT_SUCCESS(Status))
+ ChildDeviceNode = PipAllocateDeviceNode(ChildDeviceObject);
+ if (ChildDeviceNode)
{
+ PiInsertDevNode(ChildDeviceNode, DeviceNode);
+
/* Mark the node as enumerated */
ChildDeviceNode->Flags |= DNF_ENUMERATED;
diff --git a/ntoskrnl/io/pnpmgr/devnode.c b/ntoskrnl/io/pnpmgr/devnode.c
index 230fcce100b..0442e1765c2 100644
--- a/ntoskrnl/io/pnpmgr/devnode.c
+++ b/ntoskrnl/io/pnpmgr/devnode.c
@@ -31,7 +31,6 @@ IopGetDeviceNode(
}
PDEVICE_NODE
-NTAPI
PipAllocateDeviceNode(
_In_opt_ PDEVICE_OBJECT PhysicalDeviceObject)
{
@@ -39,19 +38,22 @@ PipAllocateDeviceNode(
PAGED_CODE();
/* Allocate it */
- DeviceNode = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_NODE),
TAG_IO_DEVNODE);
- if (!DeviceNode) return DeviceNode;
+ DeviceNode = ExAllocatePoolZero(NonPagedPool, sizeof(DEVICE_NODE), TAG_IO_DEVNODE);
+ if (!DeviceNode)
+ {
+ return NULL;
+ }
/* Statistics */
InterlockedIncrement(&IopNumberDeviceNodes);
/* Set it up */
- RtlZeroMemory(DeviceNode, sizeof(DEVICE_NODE));
DeviceNode->InterfaceType = InterfaceTypeUndefined;
DeviceNode->BusNumber = -1;
DeviceNode->ChildInterfaceType = InterfaceTypeUndefined;
DeviceNode->ChildBusNumber = -1;
DeviceNode->ChildBusTypeIndex = -1;
+ DeviceNode->State = DeviceNodeUninitialized;
// KeInitializeEvent(&DeviceNode->EnumerationMutex, SynchronizationEvent,
TRUE);
InitializeListHead(&DeviceNode->DeviceArbiterList);
InitializeListHead(&DeviceNode->DeviceTranslatorList);
@@ -72,6 +74,32 @@ PipAllocateDeviceNode(
return DeviceNode;
}
+VOID
+PiInsertDevNode(
+ _In_ PDEVICE_NODE DeviceNode,
+ _In_ PDEVICE_NODE ParentNode)
+{
+ KIRQL oldIrql;
+
+ ASSERT(DeviceNode->Parent == NULL);
+
+ KeAcquireSpinLock(&IopDeviceTreeLock, &oldIrql);
+ DeviceNode->Parent = ParentNode;
+ DeviceNode->Sibling = NULL;
+ if (ParentNode->LastChild == NULL)
+ {
+ ParentNode->Child = DeviceNode;
+ ParentNode->LastChild = DeviceNode;
+ }
+ else
+ {
+ ParentNode->LastChild->Sibling = DeviceNode;
+ ParentNode->LastChild = DeviceNode;
+ }
+ KeReleaseSpinLock(&IopDeviceTreeLock, oldIrql);
+ DeviceNode->Level = ParentNode->Level + 1;
+}
+
/**
* @brief Creates a device node
*
@@ -84,7 +112,7 @@ PipAllocateDeviceNode(
*
* @return Status, indicating the result of an operation
*/
-
+#if 0
NTSTATUS
IopCreateDeviceNode(
_In_ PDEVICE_NODE ParentNode,
@@ -94,7 +122,6 @@ IopCreateDeviceNode(
{
PDEVICE_NODE Node;
NTSTATUS Status;
- KIRQL OldIrql;
UNICODE_STRING FullServiceName;
UNICODE_STRING LegacyPrefix = RTL_CONSTANT_STRING(L"LEGACY_");
UNICODE_STRING UnknownDeviceName = RTL_CONSTANT_STRING(L"UNKNOWN");
@@ -249,6 +276,7 @@ IopCreateDeviceNode(
return STATUS_SUCCESS;
}
+#endif
NTSTATUS
IopFreeDeviceNode(
diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c
index ae0ac9566d3..4c5e36cb147 100644
--- a/ntoskrnl/io/pnpmgr/pnpreport.c
+++ b/ntoskrnl/io/pnpmgr/pnpreport.c
@@ -242,16 +242,15 @@ IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
}
/* Create the device node for the new PDO */
- Status = IopCreateDeviceNode(IopRootDeviceNode,
- Pdo,
- NULL,
- &DeviceNode);
- if (!NT_SUCCESS(Status))
+ DeviceNode = PipAllocateDeviceNode(Pdo);
+ if (!DeviceNode)
{
- DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
- return Status;
+ DPRINT("PipAllocateDeviceNode() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
}
+ PiInsertDevNode(DeviceNode, IopRootDeviceNode);
+
/* We're enumerated already */
IopDeviceNodeSetFlag(DeviceNode, DNF_ENUMERATED);