summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-12-19 22:27:50 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-12-19 22:27:50 -0800
commit9bc61112eef7ae06cd794536ab37248b664e45eb (patch)
tree5a7468d3bd35cb2a2eed23b9aab9f143607bdd79
parent06acadc1d70cf8f45654b7b4dc523389a531b6e3 (diff)
parenteefe13156cdfd73e93e62da7d092928f6d146ac4 (diff)
Merge "ALSA: pcm: use lock to protect substream runtime resource"
-rw-r--r--include/sound/pcm.h1
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_timer.c11
3 files changed, 14 insertions, 2 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index a2ead8cbac5e..147e448ed405 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -466,6 +466,7 @@ struct snd_pcm_substream {
const struct snd_pcm_ops *ops;
/* -- runtime information -- */
struct snd_pcm_runtime *runtime;
+ spinlock_t runtime_lock;
/* -- timer section -- */
struct snd_timer *timer; /* timer */
unsigned timer_running: 1; /* time is running */
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index a2c2f06060df..4fc68b126169 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -742,6 +742,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
}
substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock);
+ spin_lock_init(&substream->runtime_lock);
mutex_init(&substream->self_group.mutex);
INIT_LIST_HEAD(&substream->self_group.substreams);
list_add_tail(&substream->link_list, &substream->self_group.substreams);
@@ -1020,9 +1021,11 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
+ unsigned long flags = 0;
if (PCM_RUNTIME_CHECK(substream))
return;
+ spin_lock_irqsave(&substream->runtime_lock, flags);
runtime = substream->runtime;
if (runtime->private_free != NULL)
runtime->private_free(runtime);
@@ -1036,6 +1039,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
put_pid(substream->pid);
substream->pid = NULL;
substream->pstr->substream_opened--;
+ spin_unlock_irqrestore(&substream->runtime_lock, flags);
}
static ssize_t show_pcm_class(struct device *dev,
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index 20ecd8f18080..11ea73f019ba 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -65,9 +65,16 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
{
struct snd_pcm_substream *substream;
-
+ unsigned long ret = 0, flags = 0;
+
substream = timer->private_data;
- return substream->runtime ? substream->runtime->timer_resolution : 0;
+ spin_lock_irqsave(&substream->runtime_lock, flags);
+ if (substream->runtime)
+ ret = substream->runtime->timer_resolution;
+ else
+ ret = 0;
+ spin_unlock_irqrestore(&substream->runtime_lock, flags);
+ return ret;
}
static int snd_pcm_timer_start(struct snd_timer * timer)