"Possible deadlock", any tips for debugging?

Part of the driver stack for my custom GPU (a WDDM KMDOD driver, a filter driver to provide user-mode DMA and event notification, and a driver to handle audio) seems to be related to a “possible deadlock” being reported by WinDBG when the OS tries to put one of the displays to sleep.

Possible deadlock. Use !locks FFFFAA03C5008C90 to determine the resource owner
Break instruction exception - code 80000003 (first chance)
nt!ExpWaitForResource+0x1f24fa:
fffff805`5742edda cc              int     3
2: kd> !locks -v FFFFAA03C5008C90

Resource @ 0xffffaa03c5008c90    Exclusively owned
    Contention Count = 131318
    NumberOfSharedWaiters = 1
    NumberOfExclusiveWaiters = 20
     Threads: ffffaa03c2e212c0-01<*> 

     THREAD ffffaa03c2e212c0  Cid 02d8.0334  Teb: 000000320e010000 Win32Thread: ffffaa03c6ac2c70 WAIT: (WrResource) KernelMode Non-Alertable
         ffffa8856718dd00  SynchronizationEvent
     IRP List:
         ffffaa03c8a5ec70: (0006,0118) Flags: 00060000  Mdl: 00000000
     Not impersonating
     DeviceMap                 ffffbf8fef639c00
     Owning Process            ffffaa03c41212c0       Image:         csrss.exe
     Attached Process          N/A            Image:         N/A
     Wait Start TickCount      2580583        Ticks: 252 (0:00:00:03.937)
     Context Switch Count      828            IdealProcessor: 0             
     UserTime                  00:00:00.000
     KernelTime                00:00:00.234
     Win32 Start Address 0x00007fffb2aa3060
     Stack Init ffffa8856718ec90 Current ffffa8856718d860
     Base ffffa8856718f000 Limit ffffa88567189000 Call 0000000000000000
     Priority 15 BasePriority 13 PriorityDecrement 32 IoPriority 2 PagePriority 5
     Child-SP          RetAddr               Call Site
     ffffa885`6718d8a0 fffff805`57241330     nt!KiSwapContext+0x76
     ffffa885`6718d9e0 fffff805`5724085f     nt!KiSwapThread+0x500
     ffffa885`6718da90 fffff805`57240103     nt!KiCommitThreadWait+0x14f
     ffffa885`6718db30 fffff805`5723c94d     nt!KeWaitForSingleObject+0x233
     ffffa885`6718dc20 fffff805`5724679e     nt!ExpWaitForResource+0x6d
     ffffa885`6718dca0 fffff805`65dd86c4     nt!ExAcquireResourceExclusiveLite+0x1fe
     ffffa885`6718dd30 fffff805`65dd85c2     dxgkrnl!DXGADAPTER::AcquireCoreResourceExclusiveWithTracking+0x70
     ffffa885`6718dea0 fffff805`65e0f559     dxgkrnl!DXGADAPTER::AcquireCoreResourceExclusive+0xea
     ffffa885`6718df00 fffff805`65e0f498     dxgkrnl!DXGADAPTER::AcquireCoreSync+0x85
     ffffa885`6718df40 fffff805`65e0f3da     dxgkrnl!DxgkAcquireAdapterCoreSync+0x68
     ffffa885`6718df90 fffff805`65e63743     dxgkrnl!DpiAcquireCoreSyncAccessSafe+0x10e
     ffffa885`6718dfd0 fffff805`65e0ed96     dxgkrnl!DxgkPowerOnOffMonitor+0x9f
     ffffa885`6718e0f0 fffff805`65e1621f     dxgkrnl!DpiGdoDispatchInternalIoctl+0x586
     ffffa885`6718e1a0 fffff805`57235cf5     dxgkrnl!DpiDispatchInternalIoctl+0xff
     ffffa885`6718e2d0 ffffd2a1`49bf0afe     nt!IofCallDriver+0x55
     ffffa885`6718e310 ffffd2a1`49c87c1f     win32kbase!GreDeviceIoControlImpl+0xf2
     ffffa885`6718e3b0 ffffd2a1`49c876df     win32kbase!DrvSetWddmDeviceMonitorPowerState+0x51f
     ffffa885`6718e520 ffffd2a1`49c871e1     win32kbase!DrvSetMonitorPowerState+0x2f
     ffffa885`6718e550 ffffd2a1`49cb6784     win32kbase!PowerOffMonitor+0x3d1
     ffffa885`6718e6c0 ffffd2a1`49c26922     win32kbase!xxxUserPowerEventCalloutWorker+0x8fcd4
     ffffa885`6718ea30 ffffd2a1`48e415d0     win32kbase!xxxUserPowerCalloutWorker+0xe2
     ffffa885`6718eaa0 ffffd2a1`48d6474d     win32kfull!NtUserCallNoParam+0x70
     ffffa885`6718ead0 fffff805`57411138     win32k!NtUserCallNoParam+0x15
     ffffa885`6718eb00 00007fff`b2d210e4     nt!KiSystemServiceCopyEnd+0x28 (TrapFrame @ ffffa885`6718eb00)
     00000032`0e3bf8b8 00000000`00000000     0x00007fff`b2d210e4

ffffaa03c27750c0-01    

     THREAD ffffaa03c27750c0  Cid 083c.0998  Teb: 000000777c208000 Win32Thread: ffffaa03c630ebb0 WAIT: (WrResource) KernelMode Non-Alertable
         ffffa88567bd4688  SynchronizationEvent
     Not impersonating
     DeviceMap                 ffffbf8fef639c00
     Owning Process            ffffaa03c1f6e0c0       Image:         atieclxx.exe
     Attached Process          N/A            Image:         N/A
     Wait Start TickCount      2580579        Ticks: 256 (0:00:00:04.000)
     Context Switch Count      424            IdealProcessor: 0             
     UserTime                  00:00:00.000
     KernelTime                00:00:00.093
     Win32 Start Address 0x00007ff7a0748b10
     Stack Init ffffa88567bd4c90 Current ffffa88567bd41d0
     Base ffffa88567bd5000 Limit ffffa88567bcf000 Call 0000000000000000
     Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
     Child-SP          RetAddr               Call Site
     ffffa885`67bd4210 fffff805`57241330     nt!KiSwapContext+0x76
     ffffa885`67bd4350 fffff805`5724085f     nt!KiSwapThread+0x500
     ffffa885`67bd4400 fffff805`57240103     nt!KiCommitThreadWait+0x14f
     ffffa885`67bd44a0 fffff805`5723c94d     nt!KeWaitForSingleObject+0x233
     ffffa885`67bd4590 fffff805`57246f3a     nt!ExpWaitForResource+0x6d
     ffffa885`67bd4610 fffff805`57248663     nt!ExpAcquireResourceSharedLite+0x4da
     ffffa885`67bd46d0 ffffd2a1`49c6e452     nt!ExEnterCriticalRegionAndAcquireResourceShared+0x43
     ffffa885`67bd4710 fffff805`65cfa1f8     win32kbase!DxgkEngEnterUserCrit+0x92
     ffffa885`67bd4880 fffff805`65e204e3     dxgkrnl!DXGUSERCRIT::Acquire+0x2c
     ffffa885`67bd48b0 fffff805`65f11481     dxgkrnl!DxgkEnumAdaptersInternal+0xaf
     ffffa885`67bd4920 fffff805`65f13549     dxgkrnl!DxgkEnumAdaptersImpl+0xa9
     ffffa885`67bd4ad0 fffff805`57411138     dxgkrnl!DxgkEnumAdapters+0x9
     ffffa885`67bd4b00 00007fff`b2d24ba4     nt!KiSystemServiceCopyEnd+0x28 (TrapFrame @ ffffa885`67bd4b00)
     00000077`7cffea38 00000000`00000000     0x00007fff`b2d24ba4

     Threads Waiting On Exclusive Access:
              ffffaa03be10e040       ffffaa03c4489280       ffffaa03ca8bd580       ffffaa03ca0d7040       
              ffffaa03c96e9080       ffffaa03bdba2040       ffffaa03c633a080       ffffaa03c856d240       
              ffffaa03be31a080       ffffaa03ca841040       ffffaa03ca772080       ffffaa03c414b080       
              ffffaa03ca09e080       ffffaa03ca0b5080       ffffaa03ca02a0c0       ffffaa03ca6a50c0       
              ffffaa03ca0755c0       ffffaa03c9d09040       ffffaa03bdb90080       
1 total locks

None of the threads shown have any of my drivers in the callstack, and based on the image name in the last thread shown there it appears that it’s actually the driver for the on-board graphics that’s trying to take the lock being held by the other thread. I’m fairly certain that my driver is at fault somehow (as it seems unlikely that AMD’s GPU drivers would have issues like this - every time the display goes to sleep the entire machine locks up? I know software standards have gotten more lax lately, but that would be a bit beyond what anyone would consider reasonable!), but I’m not sure how to go about getting more information about what it might be doing to cause this kind of problem.

Any advice would be greatly appreciated!

There is a lot that can go wrong when exposing hardware level constructs like DMA to UM, but your exact problem is more likely to be memory corruption - write through some pointer clobbered something important owned by someone else.

There are no sure fire ways of debugging a problem like this that I know of