Author: sir_richard
Date: Sat Feb 25 18:51:21 2012
New Revision: 55858
URL: http://svn.reactos.org/svn/reactos?rev=55858&view=rev
Log:
[NTOS]: Compute the size of, and allocate, the Pool Tracker Table and the Big Page Tracker Table, which are the core data structures that make pool tagging functionality work.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/expool.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
Modified: trunk/reactos/ntoskrnl/mm/ARM3/expool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/expool.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] Sat Feb 25 18:51:21 2012
@@ -24,8 +24,11 @@
POOL_DESCRIPTOR NonPagedPoolDescriptor;
PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
PPOOL_DESCRIPTOR PoolVector[2];
-PVOID PoolTrackTable;
PKGUARDED_MUTEX ExpPagedPoolMutex;
+SIZE_T PoolTrackTableSize, PoolTrackTableMask;
+SIZE_T PoolBigPageTableSize, PoolBigPageTableHash;
+PPOOL_TRACKER_TABLE PoolTrackTable, PoolBigPageTable;
+KSPIN_LOCK ExpTaggedPoolLock;
/* Pool block/header/list access macros */
#define POOL_ENTRY(x) (PPOOL_HEADER)((ULONG_PTR)(x) - sizeof(POOL_HEADER))
@@ -329,6 +332,11 @@
ExpInitializePoolListHead(NextEntry);
NextEntry++;
}
+
+ //
+ // Note that ReactOS does not support Session Pool Yet
+ //
+ ASSERT(PoolType != PagedPoolSession);
}
VOID
@@ -338,12 +346,178 @@
IN ULONG Threshold)
{
PPOOL_DESCRIPTOR Descriptor;
+ SIZE_T TableSize;
+ ULONG i;
//
// Check what kind of pool this is
//
if (PoolType == NonPagedPool)
{
+ //
+ // Compute the track table size and convert it from a power of two to an
+ // actual byte size
+ //
+ // NOTE: On checked builds, we'll assert if the registry table size was
+ // invalid, while on retail builds we'll just break out of the loop at
+ // that point.
+ //
+ TableSize = min(PoolTrackTableSize, MmSizeOfNonPagedPoolInBytes >> 8);
+ for (i = 0; i < 32; i++)
+ {
+ if (TableSize & 1)
+ {
+ ASSERT((TableSize & ~1) == 0);
+ if (!(TableSize & ~1)) break;
+ }
+ TableSize >>= 1;
+ }
+
+ //
+ // If we hit bit 32, than no size was defined in the registry, so
+ // we'll use the default size of 2048 entries.
+ //
+ // Otherwise, use the size from the registry, as long as it's not
+ // smaller than 64 entries.
+ //
+ if (i == 32)
+ {
+ PoolTrackTableSize = 2048;
+ }
+ else
+ {
+ PoolTrackTableSize = max(1 << i, 64);
+ }
+
+ //
+ // Loop trying with the biggest specified size first, and cut it down
+ // by a power of two each iteration in case not enough memory exist
+ //
+ while (TRUE)
+ {
+ //
+ // Do not allow overflow
+ //
+ if ((PoolTrackTableSize + 1) > (MAXULONG_PTR / sizeof(POOL_TRACKER_TABLE)))
+ {
+ PoolTrackTableSize >>= 1;
+ continue;
+ }
+
+ //
+ // Allocate the tracker table and exit the loop if this worked
+ //
+ PoolTrackTable = MiAllocatePoolPages(NonPagedPool,
+ (PoolTrackTableSize + 1) *
+ sizeof(POOL_TRACKER_TABLE));
+ if (PoolTrackTable) break;
+
+ //
+ // Otherwise, as long as we're not down to the last bit, keep
+ // iterating
+ //
+ if (PoolTrackTableSize == 1)
+ {
+ KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+ TableSize,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF);
+ }
+ PoolTrackTableSize >>= 1;
+ }
+
+ //
+ // Finally, add one entry, compute the hash, and zero the table
+ //
+ PoolTrackTableSize++;
+ PoolTrackTableMask = PoolTrackTableSize - 2;
+
+ RtlZeroMemory(PoolTrackTable,
+ PoolTrackTableSize * sizeof(POOL_TRACKER_TABLE));
+
+ //
+ // We now do the exact same thing with the tracker table for big pages
+ //
+ TableSize = min(PoolBigPageTableSize, MmSizeOfNonPagedPoolInBytes >> 8);
+ for (i = 0; i < 32; i++)
+ {
+ if (TableSize & 1)
+ {
+ ASSERT((TableSize & ~1) == 0);
+ if (!(TableSize & ~1)) break;
+ }
+ TableSize >>= 1;
+ }
+
+ //
+ // For big pages, the default tracker table is 4096 entries, while the
+ // minimum is still 64
+ //
+ if (i == 32)
+ {
+ PoolBigPageTableSize = 4096;
+ }
+ else
+ {
+ PoolBigPageTableSize = max(1 << i, 64);
+ }
+
+ //
+ // Again, run the exact same loop we ran earlier, but this time for the
+ // big pool tracker instead
+ //
+ while (TRUE)
+ {
+ if ((PoolBigPageTableSize + 1) > (MAXULONG_PTR / sizeof(POOL_TRACKER_BIG_PAGES)))
+ {
+ PoolBigPageTableSize >>= 1;
+ continue;
+ }
+
+ PoolBigPageTable = MiAllocatePoolPages(NonPagedPool,
+ PoolBigPageTableSize *
+ sizeof(POOL_TRACKER_BIG_PAGES));
+ if (PoolBigPageTable) break;
+
+ if (PoolBigPageTableSize == 1)
+ {
+ KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+ TableSize,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF);
+ }
+
+ PoolBigPageTableSize >>= 1;
+ }
+
+ //
+ // An extra entry is not needed for for the big pool tracker, so just
+ // compute the hash and zero it
+ //
+ PoolBigPageTableHash = PoolBigPageTableSize - 1;
+ RtlZeroMemory(PoolBigPageTable,
+ PoolBigPageTableSize * sizeof(POOL_TRACKER_BIG_PAGES));
+
+ //
+ // During development, print this out so we can see what's happening
+ //
+ DPRINT1("EXPOOL: Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
+ PoolTrackTable, PoolTrackTableSize * sizeof(POOL_TRACKER_TABLE));
+ DPRINT1("EXPOOL: Big Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
+ PoolBigPageTable, PoolBigPageTableSize * sizeof(POOL_TRACKER_BIG_PAGES));
+
+ //
+ // No support for NUMA systems at this time
+ //
+ ASSERT(KeNumberNodes == 1);
+
+ //
+ // Initialize the tag spinlock
+ //
+ KeInitializeSpinLock(&ExpTaggedPoolLock);
+
//
// Initialize the nonpaged pool descriptor
//
@@ -356,6 +530,11 @@
}
else
{
+ //
+ // No support for NUMA systems at this time
+ //
+ ASSERT(KeNumberNodes == 1);
+
//
// Allocate the pool descriptor
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Feb 25 18:51:21 2012
@@ -345,10 +345,29 @@
C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE);
C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY));
+typedef struct _POOL_TRACKER_TABLE
+{
+ ULONG Key;
+ ULONG NonPagedAllocs;
+ ULONG NonPagedFrees;
+ SIZE_T NonPagedBytes;
+ ULONG PagedAllocs;
+ ULONG PagedFrees;
+ SIZE_T PagedBytes;
+} POOL_TRACKER_TABLE, *PPOOL_TRACKER_TABLE;
+
+typedef struct _POOL_TRACKER_BIG_PAGES
+{
+ PVOID Va;
+ ULONG Key;
+ ULONG NumberOfPages;
+ PVOID QuotaObject;
+} POOL_TRACKER_BIG_PAGES, *PPOOL_TRACKER_BIG_PAGES;
+
extern ULONG ExpNumberOfPagedPools;
extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
-extern PVOID PoolTrackTable;
+extern PPOOL_TRACKER_TABLE PoolTrackTable;
//
// END FIXFIX
Author: cgutman
Date: Sat Feb 25 05:46:19 2012
New Revision: 55852
URL: http://svn.reactos.org/svn/reactos?rev=55852&view=rev
Log:
[USBHUB]
- Fix reset event handling in cases where reset does not end up in a new device created
- My MacBook Pro completes USB initialization free of hangs now (usbstor disabled)
Modified:
trunk/reactos/drivers/usb/usbhub/fdo.c
Modified: trunk/reactos/drivers/usb/usbhub/fdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/fdo.c?r…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] Sat Feb 25 05:46:19 2012
@@ -330,6 +330,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reset port %d\n", PortId);
+ SignalResetComplete = TRUE;
continue;
}
}
@@ -348,6 +349,11 @@
}
else if (PortStatus.Change & USB_PORT_STATUS_RESET)
{
+ //
+ // Request event signalling later
+ //
+ SignalResetComplete = TRUE;
+
//
// Clear Reset
//
@@ -411,11 +417,6 @@
// This is a new device
//
Status = CreateUsbChildDeviceObject(DeviceObject, PortId, NULL, PortStatus.Status);
-
- //
- // Request event signalling later
- //
- SignalResetComplete = TRUE;
}
}
Author: cgutman
Date: Sat Feb 25 04:45:30 2012
New Revision: 55851
URL: http://svn.reactos.org/svn/reactos?rev=55851&view=rev
Log:
[USBHUB]
- Handle errors returned from the HCD correctly
[USBEHCI]
- Discard any changes on ports that were given to the companion controller
Modified:
trunk/reactos/drivers/usb/usbehci/hardware.cpp
trunk/reactos/drivers/usb/usbhub/fdo.c
Modified: trunk/reactos/drivers/usb/usbehci/hardware.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/hardwa…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/hardware.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/hardware.cpp [iso-8859-1] Sat Feb 25 04:45:30 2012
@@ -1446,6 +1446,15 @@
for (i = 0; i < PortCount; i++)
{
PortStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * i));
+
+ // Check if we actually own the port
+ if (PortStatus & EHCI_PRT_RELEASEOWNERSHIP)
+ {
+ //Discard anything on this port but ack any status changes
+ This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus);
+ continue;
+ }
+
//
// Device connected or removed
//
Modified: trunk/reactos/drivers/usb/usbhub/fdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/fdo.c?r…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] Sat Feb 25 04:45:30 2012
@@ -300,6 +300,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear connection change for port %d\n", PortId);
+ continue;
}
//
@@ -313,6 +314,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to delete child device object after disconnect\n");
+ continue;
}
}
else
@@ -328,6 +330,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reset port %d\n", PortId);
+ continue;
}
}
}
@@ -340,6 +343,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear enable change on port %d\n", PortId);
+ continue;
}
}
else if (PortStatus.Change & USB_PORT_STATUS_RESET)
@@ -351,6 +355,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear reset change on port %d\n", PortId);
+ continue;
}
//
@@ -373,6 +378,7 @@
if(PortStatus.Change & USB_PORT_STATUS_RESET)
{
DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
+ continue;
}
//