diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-10-21 09:32:13 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-10-21 12:17:02 -0400 |
commit | dde1c652d7b1e69a3f1959697f039ad6dfaeb5dd (patch) | |
tree | bf0d5cd0cdc609592862947b2872f4114bf669d5 /sound | |
parent | b1974f965a506c131b60cd3e483340884e831920 (diff) |
ALSA: pcm: Fix false lockdep warnings
As PCM core handles the multiple linked streams in parallel, lockdep
gets confused (partly because of weak annotations) and spews the
false-positive warnings. This hasn't been a problem for long time but
the latest PCM lock path update seems to have woken up a sleeping
dog.
Here is an attempt to paper over this issue: pass the lock subclass
just calculated from the depth in snd_pcm_action_group(). Also, a
(possibly) wrong lock subclass set in snd_pcm_action_lock_mutex() is
dropped, too.
Reported-and-tested-by: Arthur Marsh <arthur.marsh@internode.on.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_native.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 815396d8427f..166d59cdc86b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -781,16 +781,15 @@ static int snd_pcm_action_group(struct action_ops *ops, | |||
781 | { | 781 | { |
782 | struct snd_pcm_substream *s = NULL; | 782 | struct snd_pcm_substream *s = NULL; |
783 | struct snd_pcm_substream *s1; | 783 | struct snd_pcm_substream *s1; |
784 | int res = 0; | 784 | int res = 0, depth = 1; |
785 | 785 | ||
786 | snd_pcm_group_for_each_entry(s, substream) { | 786 | snd_pcm_group_for_each_entry(s, substream) { |
787 | if (do_lock && s != substream) { | 787 | if (do_lock && s != substream) { |
788 | if (s->pcm->nonatomic) | 788 | if (s->pcm->nonatomic) |
789 | mutex_lock_nested(&s->self_group.mutex, | 789 | mutex_lock_nested(&s->self_group.mutex, depth); |
790 | SINGLE_DEPTH_NESTING); | ||
791 | else | 790 | else |
792 | spin_lock_nested(&s->self_group.lock, | 791 | spin_lock_nested(&s->self_group.lock, depth); |
793 | SINGLE_DEPTH_NESTING); | 792 | depth++; |
794 | } | 793 | } |
795 | res = ops->pre_action(s, state); | 794 | res = ops->pre_action(s, state); |
796 | if (res < 0) | 795 | if (res < 0) |
@@ -906,8 +905,7 @@ static int snd_pcm_action_lock_mutex(struct action_ops *ops, | |||
906 | down_read(&snd_pcm_link_rwsem); | 905 | down_read(&snd_pcm_link_rwsem); |
907 | if (snd_pcm_stream_linked(substream)) { | 906 | if (snd_pcm_stream_linked(substream)) { |
908 | mutex_lock(&substream->group->mutex); | 907 | mutex_lock(&substream->group->mutex); |
909 | mutex_lock_nested(&substream->self_group.mutex, | 908 | mutex_lock(&substream->self_group.mutex); |
910 | SINGLE_DEPTH_NESTING); | ||
911 | res = snd_pcm_action_group(ops, substream, state, 1); | 909 | res = snd_pcm_action_group(ops, substream, state, 1); |
912 | mutex_unlock(&substream->self_group.mutex); | 910 | mutex_unlock(&substream->self_group.mutex); |
913 | mutex_unlock(&substream->group->mutex); | 911 | mutex_unlock(&substream->group->mutex); |