mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
ALSA: pcm - Fix race with proc files
The PCM proc files may open a race against substream close, which can end up with an Oops. Use the open_mutex to protect for it. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
8699a0b657
commit
901d46d5a8
@ -372,14 +372,17 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_pcm_substream *substream = entry->private_data;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
mutex_lock(&substream->pcm->open_mutex);
|
||||
runtime = substream->runtime;
|
||||
if (!runtime) {
|
||||
snd_iprintf(buffer, "closed\n");
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
|
||||
snd_iprintf(buffer, "no setup\n");
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
|
||||
snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
|
||||
@ -398,20 +401,25 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
|
||||
snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
|
||||
}
|
||||
#endif
|
||||
unlock:
|
||||
mutex_unlock(&substream->pcm->open_mutex);
|
||||
}
|
||||
|
||||
static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_pcm_substream *substream = entry->private_data;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
|
||||
mutex_lock(&substream->pcm->open_mutex);
|
||||
runtime = substream->runtime;
|
||||
if (!runtime) {
|
||||
snd_iprintf(buffer, "closed\n");
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
|
||||
snd_iprintf(buffer, "no setup\n");
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
|
||||
snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
|
||||
@ -421,24 +429,29 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
|
||||
snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
|
||||
snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
|
||||
snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
|
||||
unlock:
|
||||
mutex_unlock(&substream->pcm->open_mutex);
|
||||
}
|
||||
|
||||
static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
|
||||
struct snd_info_buffer *buffer)
|
||||
{
|
||||
struct snd_pcm_substream *substream = entry->private_data;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
struct snd_pcm_status status;
|
||||
int err;
|
||||
|
||||
mutex_lock(&substream->pcm->open_mutex);
|
||||
runtime = substream->runtime;
|
||||
if (!runtime) {
|
||||
snd_iprintf(buffer, "closed\n");
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
memset(&status, 0, sizeof(status));
|
||||
err = snd_pcm_status(substream, &status);
|
||||
if (err < 0) {
|
||||
snd_iprintf(buffer, "error %d\n", err);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
|
||||
snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
|
||||
@ -452,6 +465,8 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
|
||||
snd_iprintf(buffer, "-----\n");
|
||||
snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
|
||||
snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
|
||||
unlock:
|
||||
mutex_unlock(&substream->pcm->open_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user