Subject: kern/20149: switching with held simple lock in amap_unref()
To: None <gnats-bugs@gnats.NetBSD.org, tech-kern@netbsd.org>
From: Aymeric Vincent <vincent@labri.fr>
List: tech-kern
Date: 04/03/2004 18:47:29
   Hi,

I'm seeing the same symptoms as described in PR kern/20149 on macppc 
and I also believe it's not port-specific.

Namely, amap_unref() acquires a lock on the amap it is working on and 
calls amap_pp_adjref() which can happen to indirectly call uvm_anfree() 
on some anon formerly contained in the amap.

However, uvm_anfree() can go to sleep() if the anon is BUSY and this 
happens sometimes, at least when the system is paging/swapping.

I'm not sure if there is an easy workaround, but it is obviously wrong 
that a code path can sleep() when a lock is held. Maybe we should 
prepare a list of anon's to free and have them freed in some other 
context (by a thread seems overkill?).

Here is the backtrace produced with LOCKDEBUG set:

at simple_lock_switchcheck
at mi_switch
/* interesting part below */
at ltsleep
at uvm_anfree
at amap_wiperange
at amap_pp_adjref
at amap_unref
/* less insteresting from here */
at uvm_unmap_detach
at uvmspace_free
at uvm_proc_exit
at exit1
at sys_exit

  Aymeric