panic: lock (sleep mutex) vnode interlock not locked

Don Lewis truckman at FreeBSD.org
Wed Aug 10 10:45:14 GMT 2005


On 10 Aug, Suleiman Souhlal wrote:
> Hello,
> 
> On Aug 10, 2005, at 12:18 PM, Suleiman Souhlal wrote:
> 
>> Hi,
>>
>> On Aug 10, 2005, at 12:02 PM, Don Lewis wrote:
>>
>>
>>> What is preventing VI_DOOMED from being set while we're waiting for
>>> VOP_LOCK()?  Contrary to what the VOP_LOCK(9) man page says about
>>> LK_INTERLOCK, it looks like lockmgr() drops the vnode interlock  
>>> before
>>> it attempts to grab the vnode lock.
>>>
>>
>> VI_DOOMED is only set by vgonel(), and it requires both the vnode  
>> and the interlock locked.
> 
> I read your message a bit too fast. I think you are right. We should  
> probably move the check for VI_DOOMED etc, after we've acquired the  
> vnode lock.

Or possibly duplicate the check to allow the expensive VOP_LOCK() to be
quickly skipped if the vnode isn't a potential candidate.

vnlru_free() calls vtryrecycle(), which first locks the vnode, then
locks the vnode interlock, checks v_usecount and VI_DOOMED, and then may
possibly call vgonel().

vlrureclaim() uses the opposite locking order.  It first grabs the vnode
interlock, checks the vnode status, and then calls VOP_LOCK(), which
first drops the interlock and then tries to grab the vnode lock.

If vtryrecycle() already has the vnode lock, then vlrureclaim() will
sleep in VOP_LOCK(), and vtryrecycle() can grab the vnode interlock and
call vgonel(), which will set VI_DOOMED, and then vtryrecycle() will
drop both the vnode lock and interlock.  This then allows vlrureclaim()
to wake up, get the vnode lock, and then the vnode interlock, and
finally call vgonel() even though VI_DOOMED is set.



More information about the freebsd-current mailing list