ALSA: Remove BKL from open multiplexer
authorTakashi Iwai <tiwai@suse.de>
Wed, 7 Apr 2010 16:52:08 +0000 (18:52 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 9 Apr 2010 08:28:36 +0000 (10:28 +0200)
Use a local mutex instead of BKL.  This should suffice since each device
type has also its open_mutex.
Also, a bit of clean-up of the legacy device auto-loading code.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/sound.c

index 563d196..ac42af4 100644 (file)
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
 
 EXPORT_SYMBOL(snd_lookup_minor_data);
 
-static int __snd_open(struct inode *inode, struct file *file)
+#ifdef CONFIG_MODULES
+static struct snd_minor *autoload_device(unsigned int minor)
+{
+       int dev;
+       mutex_unlock(&sound_mutex); /* release lock temporarily */
+       dev = SNDRV_MINOR_DEVICE(minor);
+       if (dev == SNDRV_MINOR_CONTROL) {
+               /* /dev/aloadC? */
+               int card = SNDRV_MINOR_CARD(minor);
+               if (snd_cards[card] == NULL)
+                       snd_request_card(card);
+       } else if (dev == SNDRV_MINOR_GLOBAL) {
+               /* /dev/aloadSEQ */
+               snd_request_other(minor);
+       }
+       mutex_lock(&sound_mutex); /* reacuire lock */
+       return snd_minors[minor];
+}
+#else /* !CONFIG_MODULES */
+#define autoload_device(minor) NULL
+#endif /* CONFIG_MODULES */
+
+static int snd_open(struct inode *inode, struct file *file)
 {
        unsigned int minor = iminor(inode);
        struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
 
        if (minor >= ARRAY_SIZE(snd_minors))
                return -ENODEV;
+       mutex_lock(&sound_mutex);
        mptr = snd_minors[minor];
        if (mptr == NULL) {
-#ifdef CONFIG_MODULES
-               int dev = SNDRV_MINOR_DEVICE(minor);
-               if (dev == SNDRV_MINOR_CONTROL) {
-                       /* /dev/aloadC? */
-                       int card = SNDRV_MINOR_CARD(minor);
-                       if (snd_cards[card] == NULL)
-                               snd_request_card(card);
-               } else if (dev == SNDRV_MINOR_GLOBAL) {
-                       /* /dev/aloadSEQ */
-                       snd_request_other(minor);
-               }
-#ifndef CONFIG_SND_DYNAMIC_MINORS
-               /* /dev/snd/{controlC?,seq} */
-               mptr = snd_minors[minor];
-               if (mptr == NULL)
-#endif
-#endif
+               mptr = autoload_device(minor);
+               if (!mptr) {
+                       mutex_unlock(&sound_mutex);
                        return -ENODEV;
+               }
        }
        old_fops = file->f_op;
        file->f_op = fops_get(mptr->f_ops);
        if (file->f_op == NULL) {
                file->f_op = old_fops;
-               return -ENODEV;
+               err = -ENODEV;
        }
-       if (file->f_op->open)
+       mutex_unlock(&sound_mutex);
+       if (err < 0)
+               return err;
+
+       if (file->f_op->open) {
                err = file->f_op->open(inode, file);
-       if (err) {
-               fops_put(file->f_op);
-               file->f_op = fops_get(old_fops);
+               if (err) {
+                       fops_put(file->f_op);
+                       file->f_op = fops_get(old_fops);
+               }
        }
        fops_put(old_fops);
        return err;
 }
 
-
-/* BKL pushdown: nasty #ifdef avoidance wrapper */
-static int snd_open(struct inode *inode, struct file *file)
-{
-       int ret;
-
-       lock_kernel();
-       ret = __snd_open(inode, file);
-       unlock_kernel();
-       return ret;
-}
-
 static const struct file_operations snd_fops =
 {
        .owner =        THIS_MODULE,