When a lock departs and is enrolled again, we panic if the new instance
does not belong to the same lock class as the old instance. However,
there are legitimate cases when this may occur while doing kernel
development. In particular, one may unload a kernel module, modify the
lock class used for one of the locks in the module, and load it again.
Witness can otherwise handle this, so downgrade the assertion to a
warning.
Details
Diff Detail
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 10772 Build 11167: arc lint + arc unit
Event Timeline
It used to be in the use case you described that unloading the module would drop the reference count on the witness object to 0 freeing it to be reused. I'm not sure if that behavior was lost somewhere? Otherwise if the refcount is > 1, then there is some other lock still that is using the name with the old lock class and witness checks when that other lock is locked/unlocked will not work correctly. I wonder if this could be fixed by:
if (w->w_refcount == 1) { w->w_class = lock_class; } else if (lock_class != w->w_class) { /* existing panic */ }
It looks like we call depart() when the refcount drops to 0, which leaves the entry intact. In particular, it doesn't call witness_free(). It looks like this might be a regression from r181695; before that, it looks like depart() freed the witness entry.
Yeah, that is the svn revision that I had guessed had broken this. I would prefer the approach I had described earlier (fixup if the refcount was 0 originally) if that works for your use case.