DF-5186 / sim_output.txt
BUILD_CLEAN_NOWARN
== interleaving A: both alloc_unr before both inserts ==
objA.map_list.key = 1 (T2's allocation; T1's 0 lost)
T1 insert: 0 (published, on_map=true)
T2 insert: -EINVAL -> free_unr(1) of LIVE key
unr pool after loser: next=2 freed={1}
teardown: free_unr(1) AGAIN -> double free
pool now: n_freed=2 freed[0]=1 freed[1]=1
=> index 1 is reusable while A's entry still claims it: alloc_unr() -> 1 (aliased!)
RESULT: live-key free + double free_unr CONFIRMED
== interleaving B: key write lands AFTER winner's insert ==
obj->map_list.key = alloc_unr()
drm_ht_insert_item(&mm->offset_hash, &obj->map_list)
T1 published node in bucket[0]
obj->map_list.key = alloc_unr()
T2 overwrote key of the already-linked node to 1
drm_ht_insert_item(&mm->offset_hash, &obj->map_list)
T2 insert: 0 (SAME node linked into bucket[1]!)
node reachable from bucket[0]: YES
node reachable from bucket[1]: YES
=> SAME drm_hash_item is in TWO chains
objB (key 1) cannot publish: -EINVAL (collision with corrupted entry) -> dumb create fails
drm_ht_find_item(1) -> objA's node
=> WRONG-OBJECT RESOLUTION: mmap for key 1 maps objA's memory (cross-object mapping)
RESULT: dual-link + wrong-object lookup CONFIRMED