Re: evdev-induced panic (devfs / destroy_dev race?)
- In reply to: Kyle Evans : "evdev-induced panic (devfs / destroy_dev race?)"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Oct 2025 15:17:24 UTC
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