On Sat, Aug 22, 2020 at 09:04:09AM -0700, Michel Lespinasse wrote: > Hi, > > I am wondering about how to describe the following situation to lockdep: > > - lock A would be something that's already implemented (a mutex or > possibly a spinlock). > - lock B is a range lock, which I would be writing the code for > (including lockdep hooks). I do not expect lockdep to know about range > locking, but I want it to treat lock B like any other and detect lock > ordering issues related to it. > - lock A protects a number of structures, including lock B's list of > locked ranges, but other structures as well. > - lock A is intended to be held for only short periods of time, lock > B's ranges might be held for longer.
That's the 'normal' state for blocking locks, no? See how both struct mutex and struct rw_semaphore have internal locks. > Usage would be along the following lines: > > acquire: > A_lock(); > // might access data protected by A here > bool blocked = B_lock(range); // must be called under lock A; will > release lock A if blocking on B. > // might access data protected by A here (especially to re-validate in > case A was released while blocking on B...) > A_unlock() > > release: > A_lock() > // might access data protected by A here > A_B_unlock(range); // must be called under lock A; releases locks A and B. up_{read,write}() / mutex_unlock() release 'B', the actual lock, early, and then take 'A', the internal lock, to actually implement the release. That way lockdep doesn't see the B-A order :-) > There might also be other places that need to lock A for a short time, > either inside and outside of lock B. Any cases that aren't covered by the current implementation of rwsems ?