Commit 90dc763fef4c869e60b2a7ad92e1a7dab68575ea

Authored by Arnd Bergmann
Committed by Takashi Iwai
1 parent 395c61d196

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.
... ... @@ -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  
... ... @@ -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);