Commit 4cf19b848f92641eeb2585949a09eedec57fb53a

Authored by Takashi Iwai
1 parent 5b5cd553e3

ALSA: Remove BKL from open multiplexer

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>

Showing 1 changed file with 38 additions and 35 deletions Side-by-side Diff

... ... @@ -120,8 +120,30 @@
120 120  
121 121 EXPORT_SYMBOL(snd_lookup_minor_data);
122 122  
123   -static int __snd_open(struct inode *inode, struct file *file)
  123 +#ifdef CONFIG_MODULES
  124 +static struct snd_minor *autoload_device(unsigned int minor)
124 125 {
  126 + int dev;
  127 + mutex_unlock(&sound_mutex); /* release lock temporarily */
  128 + dev = SNDRV_MINOR_DEVICE(minor);
  129 + if (dev == SNDRV_MINOR_CONTROL) {
  130 + /* /dev/aloadC? */
  131 + int card = SNDRV_MINOR_CARD(minor);
  132 + if (snd_cards[card] == NULL)
  133 + snd_request_card(card);
  134 + } else if (dev == SNDRV_MINOR_GLOBAL) {
  135 + /* /dev/aloadSEQ */
  136 + snd_request_other(minor);
  137 + }
  138 + mutex_lock(&sound_mutex); /* reacuire lock */
  139 + return snd_minors[minor];
  140 +}
  141 +#else /* !CONFIG_MODULES */
  142 +#define autoload_device(minor) NULL
  143 +#endif /* CONFIG_MODULES */
  144 +
  145 +static int snd_open(struct inode *inode, struct file *file)
  146 +{
125 147 unsigned int minor = iminor(inode);
126 148 struct snd_minor *mptr = NULL;
127 149 const struct file_operations *old_fops;
128 150  
129 151  
130 152  
131 153  
132 154  
133 155  
... ... @@ -129,53 +151,34 @@
129 151  
130 152 if (minor >= ARRAY_SIZE(snd_minors))
131 153 return -ENODEV;
  154 + mutex_lock(&sound_mutex);
132 155 mptr = snd_minors[minor];
133 156 if (mptr == NULL) {
134   -#ifdef CONFIG_MODULES
135   - int dev = SNDRV_MINOR_DEVICE(minor);
136   - if (dev == SNDRV_MINOR_CONTROL) {
137   - /* /dev/aloadC? */
138   - int card = SNDRV_MINOR_CARD(minor);
139   - if (snd_cards[card] == NULL)
140   - snd_request_card(card);
141   - } else if (dev == SNDRV_MINOR_GLOBAL) {
142   - /* /dev/aloadSEQ */
143   - snd_request_other(minor);
144   - }
145   -#ifndef CONFIG_SND_DYNAMIC_MINORS
146   - /* /dev/snd/{controlC?,seq} */
147   - mptr = snd_minors[minor];
148   - if (mptr == NULL)
149   -#endif
150   -#endif
  157 + mptr = autoload_device(minor);
  158 + if (!mptr) {
  159 + mutex_unlock(&sound_mutex);
151 160 return -ENODEV;
  161 + }
152 162 }
153 163 old_fops = file->f_op;
154 164 file->f_op = fops_get(mptr->f_ops);
155 165 if (file->f_op == NULL) {
156 166 file->f_op = old_fops;
157   - return -ENODEV;
  167 + err = -ENODEV;
158 168 }
159   - if (file->f_op->open)
  169 + mutex_unlock(&sound_mutex);
  170 + if (err < 0)
  171 + return err;
  172 +
  173 + if (file->f_op->open) {
160 174 err = file->f_op->open(inode, file);
161   - if (err) {
162   - fops_put(file->f_op);
163   - file->f_op = fops_get(old_fops);
  175 + if (err) {
  176 + fops_put(file->f_op);
  177 + file->f_op = fops_get(old_fops);
  178 + }
164 179 }
165 180 fops_put(old_fops);
166 181 return err;
167   -}
168   -
169   -
170   -/* BKL pushdown: nasty #ifdef avoidance wrapper */
171   -static int snd_open(struct inode *inode, struct file *file)
172   -{
173   - int ret;
174   -
175   - lock_kernel();
176   - ret = __snd_open(inode, file);
177   - unlock_kernel();
178   - return ret;
179 182 }
180 183  
181 184 static const struct file_operations snd_fops =