Re: BUG: possible deadlock detected! (sound) [Was: 2.6.17-rc5-mm1]

Arjan van de Ven
2006-05-30T12:59:41Z

On Tue, 2006-05-30 at 14:44 +0200, Takashi Iwai wrote:
> This ops is a unique object assigned to a different "id" string.
>
> The first snd_seq_device_register_driver() called from emu10k1_synth.c
> is the registration for the id "snd-synth-emu10k1".
> Then in init_device(), the corresponding devices are initialized, and
> one callback registers again another device for OSS sequencer with a
> different id "snd-seq-oss" via snd_seq_device_new() inside the lock.
> Now it hits the lock-detector but the lock should belong to a
> different ops object in practice.
>
> This nested lock may happen only in two drivers, emu10k1-synth and
> opl3, and only together with OSS emulation. Since the OSS emulation
> layer don't do active registration from itself, no deadlock should
> happen (in theory -- I may oversee something :)

ok fair enough

Jiri, can you test the patch below? (I don't have this hardware)

The ops structure has complex locking rules, where not all ops are
equal, some are subordinate on others for some complex sound cards. This
requires for lockdep checking that each individual reg_mutex is
considered in separation for its locking rules.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>

---
sound/core/seq/seq_device.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

Index: linux-2.6.17-rc4-mm3-lockdep/sound/core/seq/seq_device.c
===================================================================
--- linux-2.6.17-rc4-mm3-lockdep.orig/sound/core/seq/seq_device.c
+++ linux-2.6.17-rc4-mm3-lockdep/sound/core/seq/seq_device.c
@@ -46,6 +46,7 @@
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/mutex.h>
+#include <linux/lockdep.h>

MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ALSA sequencer device management");
@@ -73,6 +74,8 @@ struct ops_list {
struct mutex reg_mutex;

struct list_head list; /* next driver */
+
+ struct lockdep_type_key reg_mutex_key;
};

@@ -379,7 +382,7 @@ static struct ops_list * create_driver(c

/* set up driver entry */
strlcpy(ops->id, id, sizeof(ops->id));
- mutex_init(&ops->reg_mutex);
+ mutex_init_key(&ops->reg_mutex, id, &ops->reg_mutex_key);
ops->driver = DRIVER_EMPTY;
INIT_LIST_HEAD(&ops->dev_list);
/* lock this instance */