On 10/23/25 07:41, Kyle Evans wrote:
Hi,
Not sure if anyone else has noticed this, but I seem to have scared up an evdev
panic:
[...]
This was seemingly the result of removing my mouse's USB dongle. Presumably
detach revoked the client and
woke it up, which then triggered the above close() from moused to race with
destroy_dev() for invoking the
cdevpriv dtor.
I spent a few minutes thinking about it and didn't really come to a good idea
of what the fix might be,
though I suspect there's nothing evdev can really do about it at the moment and
we might need to somehow
coordinate this in destroy_dev().
Kyle Evans
This thread ended up going largely off-list because I was traveling, but to
kind of summarize the
remainder of the discussion: cdevpriv bits are properly protected by the
cdevpriv_mtx, but I
pitched the following scenario:
Consider threads (U)ser and (D)river:
- (U) has called close(2) and is in the middle of devfs_close_f, maybe has
bumped the thread refcount
- (D) has initiated destroy_dev, waiting for the thread refcount to drop
Let's assume now that (U) releases the thread ref. What stops (D) and (U) from
subsequently racing to
grab the cdevpriv_mtx?
I couldn't immediately see anything that might, so let's pretend that (U) wins
and peels the cdevpriv off,
so now the cdevpriv list is empty. (D) is free to return from destroy_dev while
(U) is in the middle of
executing the dtor, where we destroy the sx that (U) is trying to acquire.
kib created D53303[0] to have destroy_dev() provide a release barrier for
cdevpriv destructors so that
callers can safely release state as all destructors have run, either by
destroy_dev() itself or a
concurrent close(2), which I think is the right balance.
Thanks,
Kyle Evans
[0] https://reviews.freebsd.org/D53303