Commit 4cf19b848f92641eeb2585949a09eedec57fb53a
1 parent
5b5cd553e3
Exists in
master
and in
7 other branches
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
sound/core/sound.c
... | ... | @@ -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 = |