| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
| |
It turns out that snd_uaudio(4) uses sound(4)'s channel lock for its USB
transfer callbacks. I will try to address this at some point, because
this is layering violation, but for now we need to revert the commit, as
it causes a lock recursion panic with USB audio devices.
This reverts commit e254ef87a30bfcaabc6e4d8e0ecf05f6949a4f06.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Do not create mutexes with snd_mtxcreate(). It doesn't provide any
value, plus it first allocates the mutex with malloc(9). Allocate
mutexes in the stack and use mtx_* functions directly instead of the
snd_mtx* wrappers.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: kib, markj
Differential Revision: https://reviews.freebsd.org/D53855
|
| |
|
|
|
|
|
|
|
|
|
|
| |
There is no scenario where chn_intr() is called with the channel lock
already held.
No functional change intended.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: kib, markj
Differential Revision: https://reviews.freebsd.org/D53854
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
INVARIANTS kernels may trigger a KASSERT panic from sndbuf_acquire(),
when fuzzing write(2) using stress2, because of a race in chn_write().
In the case of chn_write(), what sndbuf_acquire() does is extend the
ready-to-read area of the buffer by a specified amount of bytes. The
KASSERT in question makes sure the number of bytes we want to extend the
ready area by, is less than or equal to the number of free bytes in the
buffer. This makes sense, because we cannot extend the ready area to
something larger than what is available (i.e., free) in the first place.
What chn_write() currently does for every write is; calculate the
appropriate write size, let's say X, unlock the channel, uiomove() X
bytes to the channel's buffer, lock the channel, and call
sndbuf_acquire() to extend the ready area by X bytes. The problem with
this approach, however, is the following.
Suppose an empty channel buffer with a length of 1024 bytes, and 2
threads, (A) and (B), where (B) is a higher-priority one. Suppose thread
(A) wants to write 1024 bytes. It unlocks the channel and uiomove()s
1024 bytes to the channel buffer. At the same time, thread (B) picks up
the lock, and because it is higher priority, it keeps dominating the
lock for a few iterations. By the time thread (A) picks up the lock
again, it tries to call sndbuf_acquire() with a size of 1024 bytes,
which was calculated before it performed the uiomove(). In this case,
there is a very high chance that the buffer will not be empty, that is,
have a free area of 1024 bytes, as was the case when thread (A) started
executing, and so the KASSERT will trigger a panic because the condition
(bytes <= free) is not met.
Another scenario that can trigger a panic is the following: suppose a
buffer with a size of 4 bytes, and two threads: (A) and (B). In the
first iteration, thread (A) wants to write 2 bytes, while the buffer is
empty, BUT the pointer (sndbuf_getfreeptr()) is at the end (i.e.,
buf[3]). In the first iteration of the loop, because of the way we
calculate t, we'll end up writing only 1 byte, so after sz -= t, sz will
be 1, and so we'll need one more iteration in the inner loop, to write
the remaining 1 byte. Now we're at the end of the first loop, thread (A)
unlocks the channel, it has written 1 byte, it needs to write 1 more,
and the buffer is left with 3 empty slots. Now thread (B) picks up the
lock, and it wants to write 3 (or more) bytes. Eventually it writes the
3 bytes, and it leaves the buffer with 0 free slots. By the time thread
(A) picks up the lock again, and continues with the second iteration of
the inner loop, it will try to write the last byte, but sndbuf_acquire()
will panic because there is no free space anymore.
To fix this, get rid of the inner loop and calculate the write size on
each iteration. Also, call sndbuf_acquire() before unlocking the
channel. In the scenarios explained above, we'll end up entering the
chn_sleep() case. Modify it as well, so that we do not kill the channel
if we need to sleep more.
Do the same for chn_read() to avoid possible similar panics from
sndbuf_dispose().
Reported by: pho
Tested by: christos, pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: pho, kib
Differential Revision: https://reviews.freebsd.org/D53666
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
With the parameters we provide feeder_getclass(), the only thing we
really care about is the feeder's class type. We can simplify (and make
the code more readable) that by simply passing the type to
feeder_getclass(). Apart from being simpler, we can now also retire
feedertab_entry->desc and cmpdesc().
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D53553
|
| |
|
|
|
|
|
|
| |
No functional change intended.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53528
|
| |
|
|
|
|
|
|
|
|
| |
If b exists, it will get destroyed by sndbuf_destroy() (which calls
sndbuf_free()) a few lines below, so the additional sndbuf_free() here
is redundant.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53527
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Since we always use the channel name as the "drv" argument, we can just
get rid of it and fetch it in sndbuf_create(). Also, put the "channel"
argument first, as it is more intuitive.
No functional change intended.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D53520
|
| |
|
|
|
|
|
|
|
|
| |
Redundant, and if we at some point really need this, we can fetch it
from snd_dbuf->channel->dev.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D53519
|
| |
|
|
|
|
|
|
| |
Co-authored by: meka@tilda.center
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D53029
|
| |
|
|
|
|
|
|
|
|
| |
Lock around uses of devclass_*() and replace leftover
CTLFLAG_NEEDGIANTs with CTLFLAG_MPSAFE.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: imp, jhb
Differential Revision: https://reviews.freebsd.org/D46700
|
| |
|
|
|
|
|
|
|
| |
Reduce ifdefs, and add aliases for the unsigned formats.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D48009
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Even though the OSS manual [1] advises against using AFMT_FLOAT, there
are applications that expect the sound driver to support it, and might
not work properly without it.
This patch adds AFMT_F32_LE|BE (as well as AFMT_FLOAT for OSS
compatibility) in sys/soundcard.h and implements AFMT_F32_LE|BE <->
AFMT_S32_LE|BE conversion functions. As a result, applications can
write/read floats to/from sound(4), but internally, because sound(4)
works with integers, we convert floating point samples to integer ones,
before doing any processing.
The reason for encoding/decoding IEEE754s manually, instead of using
fpu_kern(9), is that fpu_kern(9) is not supported by all architectures,
and also introduces significant overhead.
The IEEE754 encoding/decoding implementation has been written by Ariff
Abdullah [2].
[1] http://manuals.opensound.com/developer/AFMT_FLOAT.html
[2] https://people.freebsd.org/~ariff/utils/ieee754.c
PR: 157050, 184380, 264973, 280612, 281390
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D47638
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Make vchanrate and vchanformat reflect the primary channel's software
buffer's rate and format respectively. Fix previous inconsistencies.
Get rid of the initializations in vchan_create() and move them to
chn_init().
Without the feeder_rate_round check in sysctl_dev_pcm_vchanrate(), we
can set the software rate to anything between feeder_rate_min and
feeder_rate_max. If we keep the check, however, the rate is limited to
whatever the driver's min/max is, which can be a problem if, for
example, the driver supports only a single rate, in which case we won't
be able to set anything other than the driver rate.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D48961
|
| |
|
|
|
|
|
| |
Only to files I've currently made significant contributions to.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
|
| |
|
|
|
|
| |
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D48966
|
| |
|
|
|
|
|
|
|
|
| |
This gives us a slight performance boost since we do not have to go
through chn_setparam() and the driver functions.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch, emaste
Differential Revision: https://reviews.freebsd.org/D48012
|
| |
|
|
|
|
|
| |
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch, emaste
Differential Revision: https://reviews.freebsd.org/D48011
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactor pcm_chnalloc() and merge with parts of vchan_setnew() (now
removed) and dsp_open()’s channel creation into a new dsp_chn_alloc()
function. The function is responsible for either using a free HW channel
(if vchans are disabled), or allocating a new vchan.
Clean up allocated vchans associated with a given dsp_cdevpriv on
dsp_close() instead of leaving them unused.
hw.snd.vchans_enable (previously hw.snd.maxautovchans) and
dev.pcm.X.{play|rec}.vchans now work as tunables to only enable/disable
vchans, as opposed to setting their number and/or (de-)allocating
vchans. Since these sysctls do not trigger any (de-)allocations anymore,
their effect is instantaneous, whereas before we could have frozen the
machine (when trying to allocate new vchans) when setting
dev.pcm.X.{play|rec}.vchans to a very large value.
Create a new "primary" channel sublist so that we do not waste time
looping through all channels in dsp_chn_alloc(), since we are only
looking for a parent channel to either use, or add a new vchan to. This
guarantees a steady traversal speed, as the parent channels are most
likely going to be just a handful (2). What was currently in place was a
loop through the whole channel list, which meant that the traversal
would take longer the more channels were added to that list.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D47917
|
| |
|
|
|
|
|
|
|
| |
There is no good reason to initialize with AFMT_U8 at 8000Hz.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D48434
|
| |
|
|
|
|
|
|
|
|
| |
An empty children list does not mean that there is an error.
Reported by: Florian Walpen <dev@submerge.ch>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D48156
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Commit 27b932e32fab ("sound: Safely remove channel from list in one
pass") optimized CHN_REMOVE_SAFE() to perform almost equally to
CHN_REMOVE(), so we can turn CHN_REMOVE_SAFE() into CHN_REMOVE() without
fears of performance regressions, while also being more robust.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D48249
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove uses of cv_waiters in PCM_RELEASE and CHN_BROADCAST, and also use
a counter around cv_timedwait_sig() in chn_sleep(), which is checked in
pcm_killchans(), as opposed to reading cv_waiters directly, which is a
layering violation.
While here, move CHN_BROADCAST below the channel lock operations.
Reported by: avg, jhb, markj
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, avg
Differential Revision: https://reviews.freebsd.org/D47780
|
| |
|
|
|
|
|
|
|
| |
No functional change intended.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, markj
Differential Revision: https://reviews.freebsd.org/D47733
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The KASSERT in chn_sleep() can be triggered if more than one thread
wants to sleep on a given channel at the same time. While this is not
really a common scenario, tools such as stress2, which use fork() and
the child process(es) inherit the parent's FDs as a result, we can end
up triggering such scenarios.
Fix this by removing CHN_F_SLEEPING altogether, which is not very useful
in the first place:
- CHN_BROADCAST() checks cv_waiters already, so there is no need to
check CHN_F_SLEEPING as well.
- We can check whether cv_waiters is 0 in pcm_killchans(), instead of
whether CHN_F_SLEEPING is not set.
Reported by: dougm, pho (stress2)
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, markj
Differential Revision: https://reviews.freebsd.org/D47559
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consider the following scenario:
1. CHN currently has its trigger set to PCMTRIG_STOP.
2. Thread A locks CHN, calls CHANNEL_TRIGGER(PCMTRIG_START), sets the
trigger to PCMTRIG_START and unlocks.
3. Thread B picks up the lock, calls CHANNEL_TRIGGER(PCMTRIG_ABORT) and
returns a non-zero value, so it returns from chn_trigger() as well.
4. Thread A picks up the lock and adds CHN to the list, which is
_wrong_, because the last call to CHANNEL_TRIGGER() was with
PCMTRIG_ABORT, meaning the channel is stopped, yet we are adding it
to the list and marking it as started.
Another problematic scenario:
1. Thread A locks CHN, sets the trigger to PCMTRIG_ABORT, and unlocks
CHN. It then locks PCM and _removes_ CHN from the list.
2. In the meantime, since thread A unlocked CHN, thread B has locked it,
set the trigger to PCMTRIG_START, unlocked it, and is now blocking on
PCM held by thread A.
3. At the same time, thread C locks CHN, sets the trigger back to
PCMTRIG_ABORT, unlocks CHN, and is also blocking on PCM. However,
once thread A unlocks PCM, because thread C is higher-priority than
thread B, it picks up the PCM lock instead of thread B, and because
CHN is already removed from the list, and thread B hasn't added it
back yet, we take a page fault in CHN_REMOVE() by trying to remove a
non-existent element.
To fix the former scenario, set the channel trigger before the call to
CHANNEL_TRIGGER() (could also come after, doesn't really matter) and
check if anything changed one we lock CHN back.
To fix the latter scenario, use the SAFE variants of CHN_INSERT_HEAD()
and CHN_REMOVE(). A similar scenario can occur in vchan_trigger(), so do
the trigger setting after we've locked the parent channel.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D47461
|
| |
|
|
|
|
|
|
|
| |
No longer used.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D47269
|
| |
|
|
|
| |
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before de8c0d15a64fa ("sound: Get rid of snd_clone and use
DEVFS_CDEVPRIV(9)"), sound(4) would create one device for each allocated
channel. The device names would be chosen from dsp_cdevs[], and created
with dsp_unit2name(). Additionally, dsp_cdevs[] was also used to match
these devices names, as well as OSSv4 aliases in dsp_clone().
Since sound(4) does not create separate devices for each channel
anymore, the meaning and use dsp_cdevs[] has changed. Part of it no
longer corresponds to devices at all, but instead is used to create
channel names, and another part is used to match only OSSv4 aliases in
dsp_clone().
To address this confusion, separate dsp_cdevs[] into a dsp_aliases[]
array, and move dsp_unit2name() to pcm/channel.c and rename it to
chn_mkname().
While here, get rid of the SND_DEV_DSPHW_* channel types, and simply use
the existing PCMDIR_* constants as the channel types. There is no need
to duplicate the same meaning twice.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D47199
|
| |
|
|
|
|
|
|
|
| |
These malloc(9) calls are in contexts where sleeping is permitted.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, zlei, markj, emaste
Differential Revision: https://reviews.freebsd.org/D46845
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The current channel naming convention is:
pcmX:[virtual_]play|record:dspX.[v]p|rY
- pcmX and dspX share the same unit numbers
- "[v]p|r" gives us the same information as "[virtual_]play|record"
Remove the redundant information, so that the channel names become more
readable: dspX.[virtual_]play|record.Y
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D46836
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently we create and destroy channels with the following consistent
pattern:
- chn_init() -> pcm_chn_add()
- pcm_chn_remove() -> chn_kill()
Instead of calling two separate functions, merge pcm_chn_add() with
chn_init(), and pcm_chn_remove() with chn_kill().
Another benefit of this change is that we avoid the confusion caused by
having pcm_chn_add(), as well as pcm_addchan().
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, markj
Differential Revision: https://reviews.freebsd.org/D46835
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently it is possible to assign a unit number that already exists.
Suppose the following channel list:
[vp2]
If we create 3 channels, we'll end up with the following list:
[vp0, vp1, vp2, vp2]
This happens because chn_init() does not check if the unit number we are
assigning already exists. While fixing this is trivial when the channel
list is sorted in ascending order, it is way more involved when sorted
in descending order. Even though sorting the list in descending order
would require deliberately modifying pcm_chn_add(), and is most likely
not going to happen, make the mechanism more robust by using a unr(9)
allocator for each channel type.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D46680
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The VCHAN count is checked in vchan_setnew(), and there is no reason to
cap the hardware channels in the first place.
This is part of a series of follow-up patches.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D46521
|
| |
|
|
|
|
|
| |
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, markj, emaste
Differential Revision: https://reviews.freebsd.org/D46100
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Remove unnecessary CHN_[UN]LOCKs.
- Improve device_printf() messages.
- Remove redundant checks.
- Remove 0 assignments, since the channel is allocated with M_ZERO.
- Re-organize sections in a more coherent way.
- Remove "out1" label, just return NULL directly.
- Rename "out2" to "fail" and simplify logic.
- Do not check the return value of dsp_unit2name(), as it is guaranteed
not to fail (we pass a valid channel type).
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D45985
|
| |
|
|
|
|
|
|
|
| |
Avoid layering violation. No functional change intended.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D45983
|
| |
|
|
|
|
|
|
|
|
| |
In case chn_init() fails, we are leaking memory by not freeing the
feeder.
Sponsored by: The FreeBSD Foundation
MFC after: 2 days
Reviewed by: dev_submerge.ch, markj
Differential Revision: https://reviews.freebsd.org/D45979
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
If dsp_unit2name() fails, we'll get to out2 with b, bs and devinfo
uninitialized, which will result in a panic.
Reported by: Pierre Pronchery <pierre@freebsdfoundation.org>
Reported by: Coverity Scan
CID: 1545029, 1545025
Pull-request: https://github.com/freebsd/freebsd-src/pull/1240
Sponsored by: The FreeBSD Foundation
MFC after: 1 day
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D45272
|
| |
|
|
|
|
|
|
|
|
| |
c is allocated with M_ZERO.
Reported by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 day
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D45273
|
| |
|
|
|
|
|
|
|
| |
It is always -1 (i.e unused).
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D45095
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Follow-up of b3ea087c05d8c75978a302cbb3fa92ce1afa3e49 ("sound: Merge
pcm_chn_destroy() and chn_kill()")
While here, add device_printf()'s to all failure points. Also fix an
existing bug where we'd unlock an already unlocked channel, in case we
went to "out" (now "out2") before locking the channel.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: dev_submerge.ch
Differential Revision: https://reviews.freebsd.org/D44993
|
| |
|
|
|
|
|
|
|
|
|
| |
This check is not related to channel initializion, but is also
unnecessary, since sysctl_hw_snd_timeout() takes care of checking if
chn_timeout is within bounds.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D44992
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Improve code layering. These are channel functions, and so they do not
belong in pcm/sound.c.
While here, assert in chn_ref() that new refcount won't be negative.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D44985
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
pcm_chn_destroy() acts like a wrapper around chn_kill(), and
additionally calls a few more functions that should in fact be part of
chn_kill()'s logic. Merge pcm_chn_destroy()'s functionality in
chn_kill() to improve readability, as well as code layering.
While here, convert chn_kill() to void as it currently always returns 0.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D44984
|
| |
|
|
|
|
|
| |
Sponsored by: The FreeBSD Foundation
MFC after: 1 day
Reviewed by: markj, emaste
Differential Revision: https://reviews.freebsd.org/D44959
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
detach
Currently we are force-destroying all channels unconditionally in
pcm_killchan(). However, since asynchronous audio device detach is
possible as of 44e128fe9d92, if we do not check whether the channel is
sleeping or not and forcefully kill it, we will get a panic from
cv_timedwait_sig() (called from chn_sleep()), because it will try to use
a freed lock/cv.
Modify pcm_killchan() (renamed to pcm_killchans() since that's a more
appropriate name now) to loop through the channel list and destroy only
the channels that are awake, otherwise wake up the sleeping thread and
try again. This loop is repeated until all channels are awakened and
destroyed.
To reduce code duplication, implement chn_shutdown() which wakes up the
channel and sets CHN_F_DEAD, and use it in pcm_unregister() and
pcm_killchans().
Reported by: KASAN
Fixes: 44e128fe9d92 ("sound: Implement asynchronous device detach")
Sponsored by: The FreeBSD Foundation
MFC after: 1 day
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D44923
|
| |
|
|
|
|
|
|
|
| |
It is marked as obsolete and there are no consumers of it anymore.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj, emaste
Differential Revision: https://reviews.freebsd.org/D44853
|
| |
|
|
|
| |
Reviewed by: kbowling, imp, emaste
Differential Revision: https://reviews.freebsd.org/D41499
|
| |
|
|
| |
Remove /SND_DECLARE_FILE\("\$FreeBSD\$"\);/
|