mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:43:04 +00:00
- Call IRP_MN_START_DEVICE in a critical region, since NT drivers depend on this implementation detail (on NT, an ERESOURCE+CriticalRegion is always held when parsing a new device node, so all related IRP_MNs are actually received under a critical region. For now, I only made IRP_MN_START_DEVICE behave as such. i8042prt from the DDK depends on this behavior.
- Cleaned up Fast Mutex Implementation. - Disabled a hard-coded bugcheck and instead disabled soem code. svn path=/trunk/; revision=26294
This commit is contained in:
parent
aa7e29c22e
commit
52041c5b65
3 changed files with 68 additions and 75 deletions
|
@ -9,37 +9,32 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#include <internal/debug.h>
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiAcquireFastMutex(IN PFAST_MUTEX FastMutex);
|
KiAcquireFastMutex(
|
||||||
|
IN PFAST_MUTEX FastMutex
|
||||||
|
);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FORCEINLINE
|
||||||
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
ExiAcquireFastMutexUnsafe(IN PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
PKTHREAD Thread = KeGetCurrentThread();
|
PKTHREAD Thread = KeGetCurrentThread();
|
||||||
|
|
||||||
/* Enter the Critical Region */
|
DPRINT("Sanity print: %d %d %p\n",
|
||||||
KeEnterCriticalRegion();
|
KeGetCurrentIrql(), Thread->CombinedApcDisable, Thread->Teb);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
||||||
(Thread == NULL) ||
|
|
||||||
(Thread->CombinedApcDisable != 0) ||
|
(Thread->CombinedApcDisable != 0) ||
|
||||||
(Thread->Teb == NULL) ||
|
(Thread->Teb == NULL) ||
|
||||||
(Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
(Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
||||||
|
ASSERT(FastMutex->Owner != Thread);
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
|
||||||
(Thread == NULL) ||
|
|
||||||
(Thread->CombinedApcDisable != 0));
|
|
||||||
|
|
||||||
ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
|
|
||||||
|
|
||||||
/* Decrease the count */
|
/* Decrease the count */
|
||||||
if (InterlockedDecrement(&FastMutex->Count))
|
if (InterlockedDecrement(&FastMutex->Count))
|
||||||
|
@ -52,24 +47,14 @@ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
||||||
FastMutex->Owner = Thread;
|
FastMutex->Owner = Thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FORCEINLINE
|
||||||
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex)
|
ExiReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
|
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
||||||
(KeGetCurrentThread() == NULL) ||
|
|
||||||
(KeGetCurrentThread()->CombinedApcDisable != 0) ||
|
(KeGetCurrentThread()->CombinedApcDisable != 0) ||
|
||||||
(KeGetCurrentThread()->Teb == NULL) ||
|
(KeGetCurrentThread()->Teb == NULL) ||
|
||||||
(KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
(KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
||||||
|
|
||||||
|
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
|
||||||
(KeGetCurrentThread() == NULL) ||
|
|
||||||
(KeGetCurrentThread()->CombinedApcDisable != 0));
|
|
||||||
ASSERT(FastMutex->Owner == KeGetCurrentThread());
|
ASSERT(FastMutex->Owner == KeGetCurrentThread());
|
||||||
|
|
||||||
/* Erase the owner */
|
/* Erase the owner */
|
||||||
|
@ -79,8 +64,35 @@ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex)
|
||||||
if (InterlockedIncrement(&FastMutex->Count) <= 0)
|
if (InterlockedIncrement(&FastMutex->Count) <= 0)
|
||||||
{
|
{
|
||||||
/* Someone was waiting for it, signal the waiter */
|
/* Someone was waiting for it, signal the waiter */
|
||||||
KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
|
KeSetEventBoostPriority(&FastMutex->Gate, NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
|
||||||
|
{
|
||||||
|
/* Enter the Critical Region */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
/* Acquire the mutex unsafely */
|
||||||
|
ExiAcquireFastMutexUnsafe(FastMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(IN OUT PFAST_MUTEX FastMutex)
|
||||||
|
{
|
||||||
|
/* Release the mutex unsafely */
|
||||||
|
ExiReleaseFastMutexUnsafe(FastMutex);
|
||||||
|
|
||||||
/* Leave the critical region */
|
/* Leave the critical region */
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
@ -91,16 +103,16 @@ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExAcquireFastMutex(PFAST_MUTEX FastMutex)
|
ExAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
||||||
|
|
||||||
/* Raise IRQL to APC */
|
/* Raise IRQL to APC */
|
||||||
OldIrql = KfRaiseIrql(APC_LEVEL);
|
OldIrql = KfRaiseIrql(APC_LEVEL);
|
||||||
|
|
||||||
/* Decrease the count */
|
/* Decrease the count */
|
||||||
if (InterlockedDecrement(&FastMutex->Count))
|
if (InterlockedDecrement(&FastMutex->Count) != 0)
|
||||||
{
|
{
|
||||||
/* Someone is still holding it, use slow path */
|
/* Someone is still holding it, use slow path */
|
||||||
KiAcquireFastMutex(FastMutex);
|
KiAcquireFastMutex(FastMutex);
|
||||||
|
@ -116,7 +128,7 @@ ExAcquireFastMutex(PFAST_MUTEX FastMutex)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExReleaseFastMutex (PFAST_MUTEX FastMutex)
|
ExReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ASSERT_IRQL(APC_LEVEL);
|
ASSERT_IRQL(APC_LEVEL);
|
||||||
|
@ -141,25 +153,10 @@ ExReleaseFastMutex (PFAST_MUTEX FastMutex)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
ExAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
PKTHREAD Thread = KeGetCurrentThread();
|
/* Acquire the mutex unsafely */
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
ExiAcquireFastMutexUnsafe(FastMutex);
|
||||||
(Thread == NULL) ||
|
|
||||||
(Thread->CombinedApcDisable != 0) ||
|
|
||||||
(Thread->Teb == NULL) ||
|
|
||||||
(Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
|
||||||
ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
|
|
||||||
|
|
||||||
/* Decrease the count */
|
|
||||||
if (InterlockedDecrement(&FastMutex->Count))
|
|
||||||
{
|
|
||||||
/* Someone is still holding it, use slow path */
|
|
||||||
KiAcquireFastMutex(FastMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the owner */
|
|
||||||
FastMutex->Owner = Thread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -167,24 +164,10 @@ ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
|
/* Release the mutex unsafely */
|
||||||
(KeGetCurrentThread() == NULL) ||
|
ExiReleaseFastMutexUnsafe(FastMutex);
|
||||||
(KeGetCurrentThread()->CombinedApcDisable != 0) ||
|
|
||||||
(KeGetCurrentThread()->Teb == NULL) ||
|
|
||||||
(KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
|
|
||||||
ASSERT(FastMutex->Owner == KeGetCurrentThread());
|
|
||||||
|
|
||||||
/* Erase the owner */
|
|
||||||
FastMutex->Owner = NULL;
|
|
||||||
|
|
||||||
/* Increase the count */
|
|
||||||
if (InterlockedIncrement(&FastMutex->Count) <= 0)
|
|
||||||
{
|
|
||||||
/* Someone was waiting for it, signal the waiter */
|
|
||||||
KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -192,10 +175,10 @@ ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex)
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
|
ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
||||||
|
|
||||||
/* Raise to APC_LEVEL */
|
/* Raise to APC_LEVEL */
|
||||||
OldIrql = KfRaiseIrql(APC_LEVEL);
|
OldIrql = KfRaiseIrql(APC_LEVEL);
|
||||||
|
|
|
@ -572,7 +572,6 @@ IoWriteErrorLogEntry(IN PVOID ElEntry)
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
|
|
||||||
/* Get the main header */
|
/* Get the main header */
|
||||||
KEBUGCHECK(0);
|
|
||||||
LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry -
|
LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry -
|
||||||
sizeof(ERROR_LOG_ENTRY));
|
sizeof(ERROR_LOG_ENTRY));
|
||||||
|
|
||||||
|
@ -586,12 +585,14 @@ IoWriteErrorLogEntry(IN PVOID ElEntry)
|
||||||
/* Check if the worker is runnign */
|
/* Check if the worker is runnign */
|
||||||
if (!IopLogWorkerRunning)
|
if (!IopLogWorkerRunning)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
/* It's not, initialize it and queue it */
|
/* It's not, initialize it and queue it */
|
||||||
ExInitializeWorkItem(&IopErrorLogWorkItem,
|
ExInitializeWorkItem(&IopErrorLogWorkItem,
|
||||||
IopLogWorker,
|
IopLogWorker,
|
||||||
&IopErrorLogWorkItem);
|
&IopErrorLogWorkItem);
|
||||||
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
|
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
|
||||||
IopLogWorkerRunning = TRUE;
|
IopLogWorkerRunning = TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock and return */
|
/* Release the lock and return */
|
||||||
|
|
|
@ -141,12 +141,21 @@ IopStartDevice(
|
||||||
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
|
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
|
||||||
Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated;
|
Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows NT Drivers receive IRP_MN_START_DEVICE in a critical region and
|
||||||
|
* actually _depend_ on this!. This is because NT will lock the Device Node
|
||||||
|
* with an ERESOURCE, which of course requires APCs to be disabled.
|
||||||
|
*/
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
Status = IopInitiatePnpIrp(
|
Status = IopInitiatePnpIrp(
|
||||||
Fdo,
|
Fdo,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
IRP_MN_START_DEVICE,
|
IRP_MN_START_DEVICE,
|
||||||
&Stack);
|
&Stack);
|
||||||
|
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("IopInitiatePnpIrp() failed\n");
|
DPRINT("IopInitiatePnpIrp() failed\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue