Page MenuHomeFreeBSD

sound: Drain the dsp cdev before freeing resources
Needs ReviewPublic

Authored by christos on Tue, Sep 29, 12:02 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Oct 14, 8:39 PM
Unknown Object (File)
Wed, Oct 14, 4:10 PM
Unknown Object (File)
Wed, Oct 14, 10:38 AM
Unknown Object (File)
Wed, Oct 14, 9:49 AM
Unknown Object (File)
Wed, Oct 14, 5:10 AM
Unknown Object (File)
Tue, Oct 13, 7:41 PM
Unknown Object (File)
Tue, Oct 13, 5:15 PM
Unknown Object (File)
Tue, Oct 13, 5:13 PM
Subscribers

Details

Reviewers
markj
emaste
kib
Summary

pcm_unregister() freed various resources before destroying the dsp cdev.
A thread that had already passed DSP_REGISTERED() could potentially
dereference those after they were freed. This was easily triggered by
the test case introduced in this commit.

Factor out pcm_killchans()'s channel wakeup/drain loop into a new
pcm_shutdownchans(), which is called before destroy_dev(), so that the
channels are freed only when destroy_dev() has returned.

SD_F_BUSY must not be held while destroying, otherwise a thread sleeping
in PCM_WAIT() would never wake up and destroy_dev() would hang.

Check PCM_REGISTERED() in vchan_create(), since it is the only place
where channels are created at runtime.

MFC after: 1 week
Sponsored by: The FreeBSD Foundation

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77814
Build 74697: arc lint + arc unit

Event Timeline

sys/dev/sound/pcm/sound.c
478–479

What's the point of waiting here if we're not going to acquire the busy lock before releasing the mutex?

christos marked an inline comment as done.

Address Mark's comment and also use PCM_ACQUIRE_QUICK() before pcm_killchans() instead of duplicating what it does.

Friendly bump for this and the rest of the stack.