I am implementing object disk i/o ops via page fault mechanism. The
whole algorithm is quite complex, but I will give you some sketchy
details so that my question can be answered.

I use C++ smart pointers. Smart pointer has two 32-bit words. It can
hold, a real pointer to object into managed page buffer, or can store
all the info to bring the object from disk. When object is accessed
via smart pointer, I check if smart pointer points to disk object. If
so, I load the object into page buffer and access it. If the pointer
is pointing to memory, then I just return it. The page buffer works as
below. If a page is accessed, I get a page fault. At that moment, I
decide if the page is read into page buffer or not. If not, I read
from the disk. If yes, I check if it is write access, if so I set
dirty flag so that I can write to disk if page is swapped. In order to
avoid objects crossing page boundaries, I use a group of pages as page
segments and guarantee that objects do not cross page segments. The
size of page segment in my application is 64K and I manage memory in
page segment.

Also, I store references to smart pointers for each page segment so
that smart pointers can point to disk objects when segment is swapped
out.

Question:
To test my application with one segment, I get software deadlock when
smart pointer in one segment accesses an object into another segment.
What's causing this deadlock?

Here is the history of page faults in my test case.

========
DiskAddress 0 mapped to segment 0x310000
Fault occurred at address 0x310008 (modify = 1, SegNum = 49)
Page at address 0 read into buffer at 0x310000(Page No. 0)
Comitting segment 0x310000 ...
Buffer page at 0x310000 written to disk address 0(Page No. 0)
All dirty pages in segment 0x310000 committed to disk
Fault occurred at address 0x310208 (modify = 1, SegNum = 49)
********** Segments Status *********
+++ Segment 0x310000 status 1
Clsid = 1
SegData = 0x310000
Address = 0
Store = 0x12df64
PageSize = 4096
nPages = 16
SegSize = 65536
PtrLink 0x2f2510 : PtrLink 0x2f2510 for GenPtr 0x2f24b4(0x2f24b0)
PtrLink 0x2f24e0 : PtrLink 0x2f24e0 for GenPtr 0x2f2544(0x2f2540)
PtrLink 0x2f24f8 : PtrLink 0x2f24f8 for GenPtr 0x2f24cc(0x2f24c8)
********** End of Segments Status *********
Fault occurred at address 0x311000 (modify = 1, SegNum = 49)
Page at address 0x1000 read into buffer at 0x311000(Page No. 1)
Fault occurred at address 0x312008 (modify = 1, SegNum = 49)
Page at address 0x2000 read into buffer at 0x312000(Page No. 2)
Fault occurred at address 0x313008 (modify = 1, SegNum = 49)
Page at address 0x3000 read into buffer at 0x313000(Page No. 3)
Fault occurred at address 0x314008 (modify = 1, SegNum = 49)
Page at address 0x4000 read into buffer at 0x314000(Page No. 4)
Fault occurred at address 0x315008 (modify = 1, SegNum = 49)
Page at address 0x5000 read into buffer at 0x315000(Page No. 5)
Fault occurred at address 0x316008 (modify = 1, SegNum = 49)
Page at address 0x6000 read into buffer at 0x316000(Page No. 6)
Fault occurred at address 0x317008 (modify = 1, SegNum = 49)
Page at address 0x7000 read into buffer at 0x317000(Page No. 7)
Fault occurred at address 0x318000 (modify = 1, SegNum = 49)
Page at address 0x8000 read into buffer at 0x318000(Page No. 8)
Fault occurred at address 0x319028 (modify = 1, SegNum = 49)
Page at address 0x9000 read into buffer at 0x319000(Page No. 9)
Fault occurred at address 0x31a000 (modify = 1, SegNum = 49)
Page at address 0xa000 read into buffer at 0x31a000(Page No. 10)
Fault occurred at address 0x31b000 (modify = 1, SegNum = 49)
Page at address 0xb000 read into buffer at 0x31b000(Page No. 11)
Fault occurred at address 0x31c008 (modify = 1, SegNum = 49)
Page at address 0xc000 read into buffer at 0x31c000(Page No. 12)
Fault occurred at address 0x31d038 (modify = 1, SegNum = 49)
Page at address 0xd000 read into buffer at 0x31d000(Page No. 13)
Fault occurred at address 0x31e008 (modify = 1, SegNum = 49)
Page at address 0xe000 read into buffer at 0x31e000(Page No. 14)
Fault occurred at address 0x31f000 (modify = 1, SegNum = 49)
Page at address 0xf000 read into buffer at 0x31f000(Page No. 15)
Decommiting pages in segment 0x310000 ...
Buffer page at 0x310000 written to disk address 0(Page No. 0)
Buffer page at 0x311000 written to disk address 0x1000(Page No. 1)
Buffer page at 0x312000 written to disk address 0x2000(Page No. 2)
Buffer page at 0x313000 written to disk address 0x3000(Page No. 3)
Buffer page at 0x314000 written to disk address 0x4000(Page No. 4)
Buffer page at 0x315000 written to disk address 0x5000(Page No. 5)
Buffer page at 0x316000 written to disk address 0x6000(Page No. 6)
Buffer page at 0x317000 written to disk address 0x7000(Page No. 7)
Buffer page at 0x318000 written to disk address 0x8000(Page No. 8)
Buffer page at 0x319000 written to disk address 0x9000(Page No. 9)
Buffer page at 0x31a000 written to disk address 0xa000(Page No. 10)
Buffer page at 0x31b000 written to disk address 0xb000(Page No. 11)
Buffer page at 0x31c000 written to disk address 0xc000(Page No. 12)
Buffer page at 0x31d000 written to disk address 0xd000(Page No. 13)
Buffer page at 0x31e000 written to disk address 0xe000(Page No. 14)
Buffer page at 0x31f000 written to disk address 0xf000(Page No. 15)
All dirty pages in segment 0x310000 written to disk
DiskAddress 0x10000 mapped to segment 0x310000
Fault occurred at address 0x310008 (modify = 1, SegNum = 49)
Page at address 0x10000 read into buffer at 0x310000(Page No. 0)
Fault occurred at address 0x3126e0 (modify = 0, SegNum = 49)
Page at address 0x12000 read into buffer at 0x312000(Page No. 2)
Fault occurred at address 0x3126e0 (modify = 1, SegNum = 49)
Fault occurred at address 0x31fd90 (modify = 1, SegNum = 49)
Page at address 0x1f000 read into buffer at 0x31f000(Page No. 15)
^C