Commit 90dc763fef4c869e60b2a7ad92e1a7dab68575ea
Committed by
Takashi Iwai
1 parent
395c61d196
Exists in
master
and in
4 other branches
sound: push BKL into open functions
This moves the lock_kernel() call from soundcore_open to the individual OSS device drivers, where we can deal with it one driver at a time if needed, or just kill off the drivers. All core components in ALSA already provide adequate locking in their open()-functions and do not require the big kernel lock, so there is no need to add the BKL there. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Showing 9 changed files with 95 additions and 35 deletions Side-by-side Diff
arch/um/drivers/hostaudio_kern.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include "linux/slab.h" |
9 | 9 | #include "linux/sound.h" |
10 | 10 | #include "linux/soundcard.h" |
11 | +#include "linux/smp_lock.h" | |
11 | 12 | #include "asm/uaccess.h" |
12 | 13 | #include "init.h" |
13 | 14 | #include "os.h" |
14 | 15 | |
... | ... | @@ -198,7 +199,10 @@ |
198 | 199 | if (file->f_mode & FMODE_WRITE) |
199 | 200 | w = 1; |
200 | 201 | |
202 | + lock_kernel(); | |
201 | 203 | ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); |
204 | + unlock_kernel(); | |
205 | + | |
202 | 206 | if (ret < 0) { |
203 | 207 | kfree(state); |
204 | 208 | return ret; |
205 | 209 | |
... | ... | @@ -254,7 +258,9 @@ |
254 | 258 | if (file->f_mode & FMODE_WRITE) |
255 | 259 | w = 1; |
256 | 260 | |
261 | + lock_kernel(); | |
257 | 262 | ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); |
263 | + unlock_kernel(); | |
258 | 264 | |
259 | 265 | if (ret < 0) { |
260 | 266 | printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " |
sound/oss/au1550_ac97.c
... | ... | @@ -43,6 +43,7 @@ |
43 | 43 | #include <linux/sound.h> |
44 | 44 | #include <linux/slab.h> |
45 | 45 | #include <linux/soundcard.h> |
46 | +#include <linux/smp_lock.h> | |
46 | 47 | #include <linux/init.h> |
47 | 48 | #include <linux/interrupt.h> |
48 | 49 | #include <linux/kernel.h> |
49 | 50 | |
... | ... | @@ -807,7 +808,9 @@ |
807 | 808 | static int |
808 | 809 | au1550_open_mixdev(struct inode *inode, struct file *file) |
809 | 810 | { |
811 | + lock_kernel(); | |
810 | 812 | file->private_data = &au1550_state; |
813 | + unlock_kernel(); | |
811 | 814 | return 0; |
812 | 815 | } |
813 | 816 | |
814 | 817 | |
815 | 818 | |
816 | 819 | |
... | ... | @@ -1797,21 +1800,22 @@ |
1797 | 1800 | #endif |
1798 | 1801 | |
1799 | 1802 | file->private_data = s; |
1803 | + lock_kernel(); | |
1800 | 1804 | /* wait for device to become free */ |
1801 | 1805 | mutex_lock(&s->open_mutex); |
1802 | 1806 | while (s->open_mode & file->f_mode) { |
1803 | - if (file->f_flags & O_NONBLOCK) { | |
1804 | - mutex_unlock(&s->open_mutex); | |
1805 | - return -EBUSY; | |
1806 | - } | |
1807 | + ret = -EBUSY; | |
1808 | + if (file->f_flags & O_NONBLOCK) | |
1809 | + goto out; | |
1807 | 1810 | add_wait_queue(&s->open_wait, &wait); |
1808 | 1811 | __set_current_state(TASK_INTERRUPTIBLE); |
1809 | 1812 | mutex_unlock(&s->open_mutex); |
1810 | 1813 | schedule(); |
1811 | 1814 | remove_wait_queue(&s->open_wait, &wait); |
1812 | 1815 | set_current_state(TASK_RUNNING); |
1816 | + ret = -ERESTARTSYS; | |
1813 | 1817 | if (signal_pending(current)) |
1814 | - return -ERESTARTSYS; | |
1818 | + goto out2; | |
1815 | 1819 | mutex_lock(&s->open_mutex); |
1816 | 1820 | } |
1817 | 1821 | |
1818 | 1822 | |
1819 | 1823 | |
1820 | 1824 | |
... | ... | @@ -1840,17 +1844,21 @@ |
1840 | 1844 | |
1841 | 1845 | if (file->f_mode & FMODE_READ) { |
1842 | 1846 | if ((ret = prog_dmabuf_adc(s))) |
1843 | - return ret; | |
1847 | + goto out; | |
1844 | 1848 | } |
1845 | 1849 | if (file->f_mode & FMODE_WRITE) { |
1846 | 1850 | if ((ret = prog_dmabuf_dac(s))) |
1847 | - return ret; | |
1851 | + goto out; | |
1848 | 1852 | } |
1849 | 1853 | |
1850 | 1854 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); |
1851 | - mutex_unlock(&s->open_mutex); | |
1852 | 1855 | mutex_init(&s->sem); |
1853 | - return 0; | |
1856 | + ret = 0; | |
1857 | +out: | |
1858 | + mutex_unlock(&s->open_mutex); | |
1859 | +out2: | |
1860 | + unlock_kernel(); | |
1861 | + return ret; | |
1854 | 1862 | } |
1855 | 1863 | |
1856 | 1864 | static int |
sound/oss/dmasound/dmasound_core.c
... | ... | @@ -323,9 +323,13 @@ |
323 | 323 | |
324 | 324 | static int mixer_open(struct inode *inode, struct file *file) |
325 | 325 | { |
326 | - if (!try_module_get(dmasound.mach.owner)) | |
326 | + lock_kernel(); | |
327 | + if (!try_module_get(dmasound.mach.owner)) { | |
328 | + unlock_kernel(); | |
327 | 329 | return -ENODEV; |
330 | + } | |
328 | 331 | mixer.busy = 1; |
332 | + unlock_kernel(); | |
329 | 333 | return 0; |
330 | 334 | } |
331 | 335 | |
332 | 336 | |
... | ... | @@ -737,8 +741,11 @@ |
737 | 741 | { |
738 | 742 | int rc; |
739 | 743 | |
740 | - if (!try_module_get(dmasound.mach.owner)) | |
744 | + lock_kernel(); | |
745 | + if (!try_module_get(dmasound.mach.owner)) { | |
746 | + unlock_kernel(); | |
741 | 747 | return -ENODEV; |
748 | + } | |
742 | 749 | |
743 | 750 | rc = write_sq_open(file); /* checks the f_mode */ |
744 | 751 | if (rc) |
745 | 752 | |
... | ... | @@ -781,10 +788,11 @@ |
781 | 788 | sound_set_format(AFMT_MU_LAW); |
782 | 789 | } |
783 | 790 | #endif |
784 | - | |
791 | + unlock_kernel(); | |
785 | 792 | return 0; |
786 | 793 | out: |
787 | 794 | module_put(dmasound.mach.owner); |
795 | + unlock_kernel(); | |
788 | 796 | return rc; |
789 | 797 | } |
790 | 798 | |
791 | 799 | |
792 | 800 | |
793 | 801 | |
794 | 802 | |
... | ... | @@ -1226,12 +1234,17 @@ |
1226 | 1234 | { |
1227 | 1235 | char *buffer = state.buf; |
1228 | 1236 | int len = 0; |
1237 | + int ret; | |
1229 | 1238 | |
1239 | + lock_kernel(); | |
1240 | + ret = -EBUSY; | |
1230 | 1241 | if (state.busy) |
1231 | - return -EBUSY; | |
1242 | + goto out; | |
1232 | 1243 | |
1244 | + ret = -ENODEV; | |
1233 | 1245 | if (!try_module_get(dmasound.mach.owner)) |
1234 | - return -ENODEV; | |
1246 | + goto out; | |
1247 | + | |
1235 | 1248 | state.ptr = 0; |
1236 | 1249 | state.busy = 1; |
1237 | 1250 | |
... | ... | @@ -1293,7 +1306,10 @@ |
1293 | 1306 | printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n"); |
1294 | 1307 | |
1295 | 1308 | state.len = len; |
1296 | - return 0; | |
1309 | + ret = 0; | |
1310 | +out: | |
1311 | + unlock_kernel(); | |
1312 | + return ret; | |
1297 | 1313 | } |
1298 | 1314 | |
1299 | 1315 | static int state_release(struct inode *inode, struct file *file) |
sound/oss/msnd_pinnacle.c
... | ... | @@ -756,12 +756,15 @@ |
756 | 756 | int minor = iminor(inode); |
757 | 757 | int err = 0; |
758 | 758 | |
759 | + lock_kernel(); | |
759 | 760 | if (minor == dev.dsp_minor) { |
760 | 761 | if ((file->f_mode & FMODE_WRITE && |
761 | 762 | test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || |
762 | 763 | (file->f_mode & FMODE_READ && |
763 | - test_bit(F_AUDIO_READ_INUSE, &dev.flags))) | |
764 | - return -EBUSY; | |
764 | + test_bit(F_AUDIO_READ_INUSE, &dev.flags))) { | |
765 | + err = -EBUSY; | |
766 | + goto out; | |
767 | + } | |
765 | 768 | |
766 | 769 | if ((err = dsp_open(file)) >= 0) { |
767 | 770 | dev.nresets = 0; |
... | ... | @@ -782,7 +785,8 @@ |
782 | 785 | /* nothing */ |
783 | 786 | } else |
784 | 787 | err = -EINVAL; |
785 | - | |
788 | +out: | |
789 | + unlock_kernel(); | |
786 | 790 | return err; |
787 | 791 | } |
788 | 792 |
sound/oss/sh_dac_audio.c
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | #include <linux/slab.h> |
17 | 17 | #include <linux/fs.h> |
18 | 18 | #include <linux/sound.h> |
19 | +#include <linux/smp_lock.h> | |
19 | 20 | #include <linux/soundcard.h> |
20 | 21 | #include <linux/interrupt.h> |
21 | 22 | #include <linux/hrtimer.h> |
22 | 23 | |
23 | 24 | |
... | ... | @@ -216,13 +217,17 @@ |
216 | 217 | { |
217 | 218 | if (file->f_mode & FMODE_READ) |
218 | 219 | return -ENODEV; |
219 | - if (in_use) | |
220 | + | |
221 | + lock_kernel(); | |
222 | + if (in_use) { | |
223 | + unlock_kernel(); | |
220 | 224 | return -EBUSY; |
225 | + } | |
221 | 226 | |
222 | 227 | in_use = 1; |
223 | 228 | |
224 | 229 | dac_audio_start(); |
225 | - | |
230 | + unlock_kernel(); | |
226 | 231 | return 0; |
227 | 232 | } |
228 | 233 |
sound/oss/soundcard.c
... | ... | @@ -210,42 +210,44 @@ |
210 | 210 | printk(KERN_ERR "Invalid minor device %d\n", dev); |
211 | 211 | return -ENXIO; |
212 | 212 | } |
213 | + lock_kernel(); | |
213 | 214 | switch (dev & 0x0f) { |
214 | 215 | case SND_DEV_CTL: |
215 | 216 | dev >>= 4; |
216 | 217 | if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) { |
217 | 218 | request_module("mixer%d", dev); |
218 | 219 | } |
220 | + retval = -ENXIO; | |
219 | 221 | if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL)) |
220 | - return -ENXIO; | |
222 | + break; | |
221 | 223 | |
222 | 224 | if (!try_module_get(mixer_devs[dev]->owner)) |
223 | - return -ENXIO; | |
225 | + break; | |
226 | + | |
227 | + retval = 0; | |
224 | 228 | break; |
225 | 229 | |
226 | 230 | case SND_DEV_SEQ: |
227 | 231 | case SND_DEV_SEQ2: |
228 | - if ((retval = sequencer_open(dev, file)) < 0) | |
229 | - return retval; | |
232 | + retval = sequencer_open(dev, file); | |
230 | 233 | break; |
231 | 234 | |
232 | 235 | case SND_DEV_MIDIN: |
233 | - if ((retval = MIDIbuf_open(dev, file)) < 0) | |
234 | - return retval; | |
236 | + retval = MIDIbuf_open(dev, file); | |
235 | 237 | break; |
236 | 238 | |
237 | 239 | case SND_DEV_DSP: |
238 | 240 | case SND_DEV_DSP16: |
239 | 241 | case SND_DEV_AUDIO: |
240 | - if ((retval = audio_open(dev, file)) < 0) | |
241 | - return retval; | |
242 | + retval = audio_open(dev, file); | |
242 | 243 | break; |
243 | 244 | |
244 | 245 | default: |
245 | 246 | printk(KERN_ERR "Invalid minor device %d\n", dev); |
246 | - return -ENXIO; | |
247 | + retval = -ENXIO; | |
247 | 248 | } |
248 | 249 | |
250 | + unlock_kernel(); | |
249 | 251 | return 0; |
250 | 252 | } |
251 | 253 |
sound/oss/swarm_cs4297a.c
... | ... | @@ -68,6 +68,7 @@ |
68 | 68 | #include <linux/delay.h> |
69 | 69 | #include <linux/sound.h> |
70 | 70 | #include <linux/slab.h> |
71 | +#include <linux/smp_lock.h> | |
71 | 72 | #include <linux/soundcard.h> |
72 | 73 | #include <linux/ac97_codec.h> |
73 | 74 | #include <linux/pci.h> |
... | ... | @@ -1534,6 +1535,7 @@ |
1534 | 1535 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, |
1535 | 1536 | printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n")); |
1536 | 1537 | |
1538 | + lock_kernel(); | |
1537 | 1539 | list_for_each(entry, &cs4297a_devs) |
1538 | 1540 | { |
1539 | 1541 | s = list_entry(entry, struct cs4297a_state, list); |
... | ... | @@ -1544,6 +1546,8 @@ |
1544 | 1546 | { |
1545 | 1547 | CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, |
1546 | 1548 | printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n")); |
1549 | + | |
1550 | + unlock_kernel(); | |
1547 | 1551 | return -ENODEV; |
1548 | 1552 | } |
1549 | 1553 | VALIDATE_STATE(s); |
... | ... | @@ -1551,6 +1555,7 @@ |
1551 | 1555 | |
1552 | 1556 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, |
1553 | 1557 | printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n")); |
1558 | + unlock_kernel(); | |
1554 | 1559 | |
1555 | 1560 | return nonseekable_open(inode, file); |
1556 | 1561 | } |
... | ... | @@ -2369,7 +2374,7 @@ |
2369 | 2374 | return 0; |
2370 | 2375 | } |
2371 | 2376 | |
2372 | -static int cs4297a_open(struct inode *inode, struct file *file) | |
2377 | +static int cs4297a_locked_open(struct inode *inode, struct file *file) | |
2373 | 2378 | { |
2374 | 2379 | int minor = iminor(inode); |
2375 | 2380 | struct cs4297a_state *s=NULL; |
... | ... | @@ -2486,6 +2491,16 @@ |
2486 | 2491 | return nonseekable_open(inode, file); |
2487 | 2492 | } |
2488 | 2493 | |
2494 | +static int cs4297a_open(struct inode *inode, struct file *file) | |
2495 | +{ | |
2496 | + int ret; | |
2497 | + | |
2498 | + lock_kernel(); | |
2499 | + ret = cs4297a_open(inode, file); | |
2500 | + unlock_kernel(); | |
2501 | + | |
2502 | + return ret; | |
2503 | +} | |
2489 | 2504 | |
2490 | 2505 | // ****************************************************************************************** |
2491 | 2506 | // Wave (audio) file operations struct. |
sound/oss/vwsnd.c
... | ... | @@ -2921,6 +2921,7 @@ |
2921 | 2921 | |
2922 | 2922 | DBGE("(inode=0x%p, file=0x%p)\n", inode, file); |
2923 | 2923 | |
2924 | + lock_kernel(); | |
2924 | 2925 | INC_USE_COUNT; |
2925 | 2926 | for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) |
2926 | 2927 | if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) |
... | ... | @@ -2928,6 +2929,7 @@ |
2928 | 2929 | |
2929 | 2930 | if (devc == NULL) { |
2930 | 2931 | DEC_USE_COUNT; |
2932 | + unlock_kernel(); | |
2931 | 2933 | return -ENODEV; |
2932 | 2934 | } |
2933 | 2935 | |
2934 | 2936 | |
... | ... | @@ -2936,11 +2938,13 @@ |
2936 | 2938 | mutex_unlock(&devc->open_mutex); |
2937 | 2939 | if (file->f_flags & O_NONBLOCK) { |
2938 | 2940 | DEC_USE_COUNT; |
2941 | + unlock_kernel(); | |
2939 | 2942 | return -EBUSY; |
2940 | 2943 | } |
2941 | 2944 | interruptible_sleep_on(&devc->open_wait); |
2942 | 2945 | if (signal_pending(current)) { |
2943 | 2946 | DEC_USE_COUNT; |
2947 | + unlock_kernel(); | |
2944 | 2948 | return -ERESTARTSYS; |
2945 | 2949 | } |
2946 | 2950 | mutex_lock(&devc->open_mutex); |
... | ... | @@ -2993,6 +2997,7 @@ |
2993 | 2997 | |
2994 | 2998 | file->private_data = devc; |
2995 | 2999 | DBGRV(); |
3000 | + unlock_kernel(); | |
2996 | 3001 | return 0; |
2997 | 3002 | } |
2998 | 3003 | |
2999 | 3004 | |
3000 | 3005 | |
... | ... | @@ -3062,15 +3067,18 @@ |
3062 | 3067 | DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); |
3063 | 3068 | |
3064 | 3069 | INC_USE_COUNT; |
3070 | + lock_kernel(); | |
3065 | 3071 | for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) |
3066 | 3072 | if (devc->mixer_minor == iminor(inode)) |
3067 | 3073 | break; |
3068 | 3074 | |
3069 | 3075 | if (devc == NULL) { |
3070 | 3076 | DEC_USE_COUNT; |
3077 | + unlock_kernel(); | |
3071 | 3078 | return -ENODEV; |
3072 | 3079 | } |
3073 | 3080 | file->private_data = devc; |
3081 | + unlock_kernel(); | |
3074 | 3082 | return 0; |
3075 | 3083 | } |
3076 | 3084 |
sound/sound_core.c
... | ... | @@ -629,12 +629,8 @@ |
629 | 629 | file->f_op = new_fops; |
630 | 630 | spin_unlock(&sound_loader_lock); |
631 | 631 | |
632 | - if (file->f_op->open) { | |
633 | - /* TODO: push down BKL into indivial open functions */ | |
634 | - lock_kernel(); | |
632 | + if (file->f_op->open) | |
635 | 633 | err = file->f_op->open(inode,file); |
636 | - unlock_kernel(); | |
637 | - } | |
638 | 634 | |
639 | 635 | if (err) { |
640 | 636 | fops_put(file->f_op); |