diff options
| author | Cen Zhang <zzzccc427@gmail.com> | 2026-03-16 11:50:47 +0300 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2026-03-16 20:05:55 +0300 |
| commit | 032322b44c02f5e8a127d1dca6798f91cc72eb1d (patch) | |
| tree | 2a9378b6b29bfba02e89474708044e2b7e336c4a /include | |
| parent | 103a7b97c63905ab4d1463bf040e27f668e6a340 (diff) | |
| download | linux-032322b44c02f5e8a127d1dca6798f91cc72eb1d.tar.xz | |
ALSA: pcm: oss: use proper stream lock for runtime->state access
__snd_pcm_set_state() writes runtime->state under the PCM stream lock.
However, the OSS I/O functions snd_pcm_oss_write3(), snd_pcm_oss_read3(),
snd_pcm_oss_writev3() and snd_pcm_oss_readv3() read runtime->state
without holding the stream lock, only holding oss.params_lock (a
different mutex that does not synchronize with the stream lock).
Since __snd_pcm_set_state() is called from IRQ context (e.g.,
snd_pcm_period_elapsed -> snd_pcm_update_state -> __snd_pcm_xrun ->
snd_pcm_stop -> snd_pcm_post_stop) while the OSS read/write paths
run in process context, these are concurrent accesses that constitute
a data race.
Rather than using READ_ONCE()/WRITE_ONCE() barriers, introduce a
snd_pcm_get_state() helper that reads runtime->state under the stream
lock, matching the locking discipline used elsewhere in the PCM layer.
Also export snd_pcm_set_state() for completeness.
Use snd_pcm_get_state() in all four OSS I/O functions, caching the
result in a local variable where the same snapshot is used for
multiple comparisons to avoid taking the lock repeatedly.
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Link: https://patch.msgid.link/20260316085047.2876451-1-zzzccc427@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'include')
| -rw-r--r-- | include/sound/pcm.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index a7860c047503..76fc33dce537 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -729,6 +729,10 @@ static inline void __snd_pcm_set_state(struct snd_pcm_runtime *runtime, runtime->status->state = state; /* copy for mmap */ } +void snd_pcm_set_state(struct snd_pcm_substream *substream, + snd_pcm_state_t state); +snd_pcm_state_t snd_pcm_get_state(struct snd_pcm_substream *substream); + /** * bytes_to_samples - Unit conversion of the size from bytes to samples * @runtime: PCM runtime instance |
