All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Duncan Sands <baldrick@wanadoo.fr>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: 2.5.50: sleeping function called from illegal context
Date: Tue, 03 Dec 2002 15:56:19 +0100	[thread overview]
Message-ID: <s5hhedv9mng.wl@alsa2.suse.de> (raw)
In-Reply-To: <200212030657.45283.baldrick@wanadoo.fr>

[-- Attachment #1: Type: text/plain, Size: 2620 bytes --]

At Tue, 3 Dec 2002 06:57:45 +0100,
Duncan Sands wrote:
> 
> On Tuesday 03 December 2002 14:56, Takashi Iwai wrote:
> > At Tue, 3 Dec 2002 04:55:15 +0100,
> >
> > Duncan Sands wrote:
> > > On Tuesday 03 December 2002 13:01, Takashi Iwai wrote:
> > > > At Tue, 3 Dec 2002 04:07:52 +0100,
> > > >
> > > > Duncan Sands wrote:
> > > > > Got this with today 2.5 BK tree:
> > > > >
> > > > > Debug: sleeping function called from illegal context at
> > > > > include/asm/semaphore.h:119 Call Trace:
> > > > >  [<c0113f1a>] __might_sleep+0x52/0x58
> > > > >  [<c024291a>] snd_cs46xx_iec958_put+0x36/0xf8
> > > > >  [<c0217f28>] snd_ctl_elem_write+0xe0/0x1a4
> > > > >  [<c0218360>] snd_ctl_ioctl+0x184/0x2c8
> > > > >  [<c01462e6>] sys_ioctl+0x1fa/0x244
> > > > >  [<c01088f7>] syscall_call+0x7/0xb
> > > >
> > > > ouch, we are using rwlock in the control ioctls.
> > > >
> > > > mutex is necessary for many controls, so we cannot suppress the use of
> > > > mutex in control callbacks.
> > > > but temporary unlocking looks ad-hoc, too...
> > >
> > > If I understand right, the problem is that snd_ctl_elem_write
> > > acquires control_rwlock, which is a rw spinlock.  It then calls
> > > snd_cs46xx_iec958_put which acquires chip->spos_mutex,
> > > which is a semaphore.  Thus the message.  Now I deduce
> > > from the fact that  you don't use read_lock_irqsave that the
> > > data structure is not read from interrupt context.  That means
> > > you are only protecting against other CPUs.  So why not use
> > > a semaphore instead of a spinlock?
> >
> > hmm, there are some places calling with irq lock.
> > for example, snd_ctl_notify() can be called from the interrupt handler
> > for some interrupts like h/w volume change.
> 
> Uh oh!
> 
> > however, it seems that a single rwlock is used for the management of
> > two different lists.  and snd_ctl_elem_write() uses card->controls
> > only, whereas snd_ctl_notify() uses card->ctl_files only.
> > hence, we can merge two locks, rwsem for card->controls and rwlock for
> > card->ctl_files.  i'll give a try.
> 
> I guess another way of dealing with this kind of problem is to use a
> semaphore rather than a spinlock, and a workqueue: when the interrupt
> comes in, the call to snd_ctl_notify is put on the queue, where it will later
> be run in process context, and can safely take the semaphore.

yes, basically what snd_ctl_notify() does is the same.
it queues an event and wakes up the sleepers.
thus, it's ok to separate the stuff from the semaphore.

the attached is a patch to rewrite the locks with rwsem.
please check whether it works for you.


thanks,

Takashi

[-- Attachment #2: control-lock-fix.dif --]
[-- Type: application/octet-stream, Size: 20990 bytes --]

Index: alsa-kernel/include/core.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/core.h,v
retrieving revision 1.26
diff -u -r1.26 core.h
--- alsa-kernel/include/core.h	2 Dec 2002 09:25:18 -0000	1.26
+++ alsa-kernel/include/core.h	3 Dec 2002 14:29:58 -0000
@@ -24,6 +24,7 @@
 
 #include <linux/sched.h>		/* wake_up() */
 #include <asm/semaphore.h>		/* struct semaphore */
+#include <linux/rwsem.h>		/* struct rw_semaphore */
 
 /* Typedef's */
 typedef struct timeval snd_timestamp_t;
@@ -141,8 +142,8 @@
 	struct list_head devices;	/* devices */
 
 	unsigned int last_numid;	/* last used numeric ID */
-	rwlock_t control_rwlock;	/* control list lock */
-	rwlock_t control_owner_lock;	/* control list lock */
+	struct rw_semaphore controls_rwsem;	/* controls list lock */
+	rwlock_t ctl_files_rwlock;	/* ctl_files list lock */
 	int controls_count;		/* count of all controls */
 	struct list_head controls;	/* all controls for this card */
 	struct list_head ctl_files;	/* active control files */
Index: alsa-kernel/core/control.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/control.c,v
retrieving revision 1.17
diff -u -r1.17 control.c
--- alsa-kernel/core/control.c	2 Dec 2002 09:25:17 -0000	1.17
+++ alsa-kernel/core/control.c	3 Dec 2002 14:45:15 -0000
@@ -37,7 +37,7 @@
 
 #define snd_kctl_ioctl(n) list_entry(n, snd_kctl_ioctl_t, list)
 
-static rwlock_t snd_ioctl_rwlock = RW_LOCK_UNLOCKED;
+static DECLARE_RWSEM(snd_ioctl_rwsem);
 static LIST_HEAD(snd_control_ioctls);
 
 static inline void dec_mod_count(struct module *module)
@@ -82,9 +82,9 @@
 	ctl->card = card;
 	ctl->pid = current->pid;
 	file->private_data = ctl;
-	write_lock_irqsave(&card->control_rwlock, flags);
+	write_lock_irqsave(&card->ctl_files_rwlock, flags);
 	list_add_tail(&ctl->list, &card->ctl_files);
-	write_unlock_irqrestore(&card->control_rwlock, flags);
+	write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
 	return 0;
 
       __error:
@@ -123,16 +123,16 @@
 	fasync_helper(-1, file, 0, &ctl->fasync);
 	file->private_data = NULL;
 	card = ctl->card;
-	write_lock_irqsave(&card->control_rwlock, flags);
+	write_lock_irqsave(&card->ctl_files_rwlock, flags);
 	list_del(&ctl->list);
-	write_lock(&card->control_owner_lock);
+	write_unlock_irqrestore(&card->ctl_files_rwlock, flags);
+	down_write(&card->controls_rwsem);
 	list_for_each(list, &card->controls) {
 		control = snd_kcontrol(list);
 		if (control->owner == ctl)
 			control->owner = NULL;
 	}
-	write_unlock(&card->control_owner_lock);
-	write_unlock_irqrestore(&card->control_rwlock, flags);
+	up_write(&card->controls_rwsem);
 	snd_ctl_empty_read_queue(ctl);
 	snd_magic_kfree(ctl);
 	dec_mod_count(card->module);
@@ -151,7 +151,7 @@
 	snd_kctl_event_t *ev;
 	
 	snd_runtime_check(card != NULL && id != NULL, return);
-	read_lock_irqsave(&card->control_rwlock, flags);
+	read_lock(&card->ctl_files_rwlock);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	card->mixer_oss_change_count++;
 #endif
@@ -160,7 +160,7 @@
 		ctl = snd_ctl_file(flist);
 		if (!ctl->subscribed)
 			continue;
-		spin_lock(&ctl->read_lock);
+		spin_lock_irqsave(&ctl->read_lock, flags);
 		list_for_each(elist, &ctl->events) {
 			ev = snd_kctl_event(elist);
 			if (ev->id.numid == id->numid) {
@@ -179,9 +179,9 @@
 	_found:
 		wake_up(&ctl->change_sleep);
 		kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
-		spin_unlock(&ctl->read_lock);
+		spin_unlock_irqrestore(&ctl->read_lock, flags);
 	}
-	read_unlock_irqrestore(&card->control_rwlock, flags);
+	read_unlock(&card->ctl_files_rwlock);
 }
 
 snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control)
@@ -233,11 +233,11 @@
 	snd_assert(kcontrol->info != NULL, return -EINVAL);
 	snd_assert(!(kcontrol->access & SNDRV_CTL_ELEM_ACCESS_READ) || kcontrol->get != NULL, return -EINVAL);
 	snd_assert(!(kcontrol->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kcontrol->put != NULL, return -EINVAL);
-	write_lock(&card->control_rwlock);
+	down_write(&card->controls_rwsem);
 	list_add_tail(&kcontrol->list, &card->controls);
 	card->controls_count++;
 	kcontrol->id.numid = ++card->last_numid;
-	write_unlock(&card->control_rwlock);
+	up_write(&card->controls_rwsem);
 	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &kcontrol->id);
 	return 0;
 }
@@ -245,10 +245,10 @@
 int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
 {
 	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
-	write_lock(&card->control_rwlock);
+	down_write(&card->controls_rwsem);
 	list_del(&kcontrol->list);
 	card->controls_count--;
-	write_unlock(&card->control_rwlock);
+	up_write(&card->controls_rwsem);
 	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &kcontrol->id);
 	snd_ctl_free_one(kcontrol);
 	return 0;
@@ -264,47 +264,46 @@
 	return snd_ctl_remove(card, kctl);
 }
 
+static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */
+
 int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id)
 {
 	snd_kcontrol_t *kctl;
 
-	kctl = snd_ctl_find_id(card, src_id);
-	if (kctl == NULL)
+	down_write(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, src_id);
+	if (kctl == NULL) {
+		up_write(&card->controls_rwsem);
 		return -ENOENT;
-	write_lock(&card->control_rwlock);
+	}
 	kctl->id = *dst_id;
 	kctl->id.numid = ++card->last_numid;
-	write_unlock(&card->control_rwlock);
+	up_write(&card->controls_rwsem);
 	return 0;
 }
 
-snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
+static snd_kcontrol_t *_ctl_find_numid(snd_card_t * card, unsigned int numid)
 {
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
 	snd_runtime_check(card != NULL && numid != 0, return NULL);
-	read_lock(&card->control_rwlock);
 	list_for_each(list, &card->controls) {
 		kctl = snd_kcontrol(list);
-		if (kctl->id.numid == numid) {
-			read_unlock(&card->control_rwlock);
+		if (kctl->id.numid == numid)
 			return kctl;
-		}
 	}
-	read_unlock(&card->control_rwlock);
 	return NULL;
 }
 
-snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
+static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
 {
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
 	snd_runtime_check(card != NULL && id != NULL, return NULL);
 	if (id->numid != 0)
-		return snd_ctl_find_numid(card, id->numid);
-	read_lock(&card->control_rwlock);
+		return _ctl_find_numid(card, id->numid);
 	list_for_each(list, &card->controls) {
 		kctl = snd_kcontrol(list);
 		if (kctl->id.iface != id->iface)
@@ -317,20 +316,38 @@
 			continue;
 		if (kctl->id.index != id->index)
 			continue;
-		read_unlock(&card->control_rwlock);
 		return kctl;
 	}
-	read_unlock(&card->control_rwlock);
 	return NULL;
 }
 
+/* exported: with read lock */
+snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
+{
+	snd_kcontrol_t *kctl;
+	down_read(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, id);
+	up_read(&card->controls_rwsem);
+	return kctl;
+}
+
+/* exported: with read lock */
+snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
+{
+	snd_kcontrol_t *kctl;
+	down_read(&card->controls_rwsem);
+	kctl = _ctl_find_numid(card, numid);
+	up_read(&card->controls_rwsem);
+	return kctl;
+}
+
 static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
 			     unsigned int cmd, unsigned long arg)
 {
 	snd_ctl_card_info_t info;
 
 	memset(&info, 0, sizeof(info));
-	read_lock(&snd_ioctl_rwlock);
+	down_read(&snd_ioctl_rwsem);
 	info.card = card->number;
 	strncpy(info.id, card->id, sizeof(info.id) - 1);
 	strncpy(info.driver, card->driver, sizeof(info.driver) - 1);
@@ -338,7 +355,7 @@
 	strncpy(info.longname, card->longname, sizeof(info.longname) - 1);
 	strncpy(info.mixername, card->mixername, sizeof(info.mixername) - 1);
 	strncpy(info.components, card->components, sizeof(info.components) - 1);
-	read_unlock(&snd_ioctl_rwlock);
+	up_read(&snd_ioctl_rwsem);
 	if (copy_to_user((void *) arg, &info, sizeof(snd_ctl_card_info_t)))
 		return -EFAULT;
 	return 0;
@@ -364,7 +381,7 @@
 		dst = vmalloc(space * sizeof(snd_ctl_elem_id_t));
 		if (dst == NULL)
 			return -ENOMEM;
-		read_lock(&card->control_rwlock);
+		down_read(&card->controls_rwsem);
 		list.count = card->controls_count;
 		plist = card->controls.next;
 		while (offset-- > 0 && plist != &card->controls)
@@ -379,14 +396,14 @@
 			space--;
 			list.used++;
 		}
-		read_unlock(&card->control_rwlock);
+		up_read(&card->controls_rwsem);
 		if (list.used > 0 && copy_to_user(list.pids, dst, list.used * sizeof(snd_ctl_elem_id_t)))
 			return -EFAULT;
 		vfree(dst);
 	} else {
-		read_lock(&card->control_rwlock);
+		down_read(&card->controls_rwsem);
 		list.count = card->controls_count;
-		read_unlock(&card->control_rwlock);
+		up_read(&card->controls_rwsem);
 	}
 	if (copy_to_user(_list, &list, sizeof(list)))
 		return -EFAULT;
@@ -402,10 +419,10 @@
 	
 	if (copy_from_user(&info, _info, sizeof(info)))
 		return -EFAULT;
-	read_lock(&card->control_rwlock);
-	kctl = snd_ctl_find_id(card, &info.id);
+	down_read(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, &info.id);
 	if (kctl == NULL) {
-		read_unlock(&card->control_rwlock);
+		up_read(&card->controls_rwsem);
 		return -ENOENT;
 	}
 #ifdef CONFIG_SND_DEBUG
@@ -425,7 +442,7 @@
 			info.owner = -1;
 		}
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	if (result >= 0)
 		if (copy_to_user(_info, &info, sizeof(info)))
 			return -EFAULT;
@@ -443,8 +460,8 @@
 		return -ENOMEM;	
 	if (copy_from_user(control, _control, sizeof(*control)))
 		return -EFAULT;
-	read_lock(&card->control_rwlock);
-	kctl = snd_ctl_find_id(card, &control->id);
+	down_read(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, &control->id);
 	if (kctl == NULL) {
 		result = -ENOENT;
 	} else {
@@ -460,7 +477,7 @@
 				result = -EPERM;
 		}
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	if (result >= 0)
 		if (copy_to_user(_control, control, sizeof(*control)))
 			return -EFAULT;
@@ -480,8 +497,8 @@
 		return -ENOMEM;	
 	if (copy_from_user(control, _control, sizeof(*control)))
 		return -EFAULT;
-	read_lock(&card->control_rwlock);
-	kctl = snd_ctl_find_id(card, &control->id);
+	down_read(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, &control->id);
 	if (kctl == NULL) {
 		result = -ENOENT;
 	} else {
@@ -489,7 +506,6 @@
 		if (control->indirect != indirect) {
 			result = -EACCES;
 		} else {
-			read_lock(&card->control_owner_lock);
 			if (!(kctl->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
 			    kctl->put == NULL ||
 			    (kctl->owner != NULL && kctl->owner != file)) {
@@ -499,16 +515,15 @@
 				if (result >= 0)
 					control->id = kctl->id;
 			}
-			read_unlock(&card->control_owner_lock);
 			if (result > 0) {
-				read_unlock(&card->control_rwlock);
+				up_read(&card->controls_rwsem);
 				snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
 				result = 0;
 				goto __unlocked;
 			}
 		}
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
       __unlocked:
 	if (result >= 0)
 		if (copy_to_user(_control, control, sizeof(*control)))
@@ -526,12 +541,11 @@
 	
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
-	read_lock(&card->control_rwlock);
-	kctl = snd_ctl_find_id(card, &id);
+	down_write(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, &id);
 	if (kctl == NULL) {
 		result = -ENOENT;
 	} else {
-		write_lock(&card->control_owner_lock);
 		if (kctl->owner != NULL)
 			result = -EBUSY;
 		else {
@@ -539,9 +553,8 @@
 			kctl->owner_pid = current->pid;
 			result = 0;
 		}
-		write_unlock(&card->control_owner_lock);
 	}
-	read_unlock(&card->control_rwlock);
+	up_write(&card->controls_rwsem);
 	return result;
 }
 
@@ -554,12 +567,11 @@
 	
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
-	read_lock(&card->control_rwlock);
-	kctl = snd_ctl_find_id(card, &id);
+	down_write(&card->controls_rwsem);
+	kctl = _ctl_find_id(card, &id);
 	if (kctl == NULL) {
 		result = -ENOENT;
 	} else {
-		write_lock(&card->control_owner_lock);
 		if (kctl->owner == NULL)
 			result = -EINVAL;
 		else if (kctl->owner != file)
@@ -569,9 +581,8 @@
 			kctl->owner_pid = 0;
 			result = 0;
 		}
-		write_unlock(&card->control_owner_lock);
 	}
-	read_unlock(&card->control_rwlock);
+	up_write(&card->controls_rwsem);
 	return result;
 }
 
@@ -646,16 +657,16 @@
 		return put_user(SNDRV_CTL_POWER_D0, (int *)arg) ? -EFAULT : 0;
 #endif
 	}
-	read_lock(&snd_ioctl_rwlock);
+	down_read(&snd_ioctl_rwsem);
 	list_for_each(list, &snd_control_ioctls) {
 		p = list_entry(list, snd_kctl_ioctl_t, list);
 		err = p->fioctl(card, ctl, cmd, arg);
 		if (err != -ENOIOCTLCMD) {
-			read_unlock(&snd_ioctl_rwlock);
+			up_read(&snd_ioctl_rwsem);
 			return err;
 		}
 	}
-	read_unlock(&snd_ioctl_rwlock);
+	up_read(&snd_ioctl_rwsem);
 	snd_printd("unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
 }
@@ -740,9 +751,9 @@
 	if (pn == NULL)
 		return -ENOMEM;
 	pn->fioctl = fcn;
-	write_lock(&snd_ioctl_rwlock);
+	down_write(&snd_ioctl_rwsem);
 	list_add_tail(&pn->list, &snd_control_ioctls);
-	write_unlock(&snd_ioctl_rwlock);
+	up_write(&snd_ioctl_rwsem);
 	return 0;
 }
 
@@ -752,17 +763,17 @@
 	snd_kctl_ioctl_t *p;
 
 	snd_runtime_check(fcn != NULL, return -EINVAL);
-	write_lock(&snd_ioctl_rwlock);
+	down_write(&snd_ioctl_rwsem);
 	list_for_each(list, &snd_control_ioctls) {
 		p = list_entry(list, snd_kctl_ioctl_t, list);
 		if (p->fioctl == fcn) {
 			list_del(&p->list);
-			write_unlock(&snd_ioctl_rwlock);
+			up_write(&snd_ioctl_rwsem);
 			kfree(p);
 			return 0;
 		}
 	}
-	write_unlock(&snd_ioctl_rwlock);
+	up_write(&snd_ioctl_rwsem);
 	snd_BUG();
 	return -EINVAL;
 }
@@ -821,13 +832,13 @@
 	struct list_head *flist;
 	snd_ctl_file_t *ctl;
 
-	read_lock_irq(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	list_for_each(flist, &card->ctl_files) {
 		ctl = snd_ctl_file(flist);
 		wake_up(&ctl->change_sleep);
 		kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
 	}
-	read_unlock_irq(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	return 0;
 }
 
Index: alsa-kernel/core/init.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/init.c,v
retrieving revision 1.17
diff -u -r1.17 init.c
--- alsa-kernel/core/init.c	3 Dec 2002 11:02:36 -0000	1.17
+++ alsa-kernel/core/init.c	3 Dec 2002 14:30:16 -0000
@@ -99,8 +99,8 @@
 	card->number = idx;
 	card->module = module;
 	INIT_LIST_HEAD(&card->devices);
-	rwlock_init(&card->control_rwlock);
-	rwlock_init(&card->control_owner_lock);
+	init_rwsem(&card->controls_rwsem);
+	rwlock_init(&card->ctl_files_rwlock);
 	INIT_LIST_HEAD(&card->controls);
 	INIT_LIST_HEAD(&card->ctl_files);
 	spin_lock_init(&card->files_lock);
Index: alsa-kernel/core/pcm.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm.c,v
retrieving revision 1.19
diff -u -r1.19 pcm.c
--- alsa-kernel/core/pcm.c	2 Dec 2002 09:25:17 -0000	1.19
+++ alsa-kernel/core/pcm.c	3 Dec 2002 14:28:54 -0000
@@ -698,7 +698,7 @@
 		return -ENODEV;
 
 	card = pcm->card;
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	list_for_each(list, &card->ctl_files) {
 		kctl = snd_ctl_file(list);
 		if (kctl->pid == current->pid) {
@@ -706,7 +706,7 @@
 			break;
 		}
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 
 	if (pstr->substream_count == 0)
 		return -ENODEV;
Index: alsa-kernel/core/rawmidi.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/rawmidi.c,v
retrieving revision 1.22
diff -u -r1.22 rawmidi.c
--- alsa-kernel/core/rawmidi.c	2 Dec 2002 09:25:18 -0000	1.22
+++ alsa-kernel/core/rawmidi.c	3 Dec 2002 14:31:09 -0000
@@ -412,7 +412,7 @@
 	add_wait_queue(&rmidi->open_wait, &wait);
 	while (1) {
 		subdevice = -1;
-		read_lock(&card->control_rwlock);
+		down_read(&card->controls_rwsem);
 		list_for_each(list, &card->ctl_files) {
 			kctl = snd_ctl_file(list);
 			if (kctl->pid == current->pid) {
@@ -420,7 +420,7 @@
 				break;
 			}
 		}
-		read_unlock(&card->control_rwlock);
+		up_read(&card->controls_rwsem);
 		err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file);
 		if (err >= 0)
 			break;
Index: alsa-kernel/core/oss/mixer_oss.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/oss/mixer_oss.c,v
retrieving revision 1.14
diff -u -r1.14 mixer_oss.c
--- alsa-kernel/core/oss/mixer_oss.c	2 Dec 2002 09:25:18 -0000	1.14
+++ alsa-kernel/core/oss/mixer_oss.c	3 Dec 2002 14:36:03 -0000
@@ -562,7 +562,7 @@
 	struct slot *slot = (struct slot *)pslot->private_data;
 	
 	*left = *right = 100;
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
 		snd_mixer_oss_get_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
 	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
@@ -579,7 +579,7 @@
 	} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
 		snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	return 0;
 }
 
@@ -655,7 +655,7 @@
 	snd_card_t *card = fmixer->card;
 	struct slot *slot = (struct slot *)pslot->private_data;
 	
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
 		snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
 		if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
@@ -685,7 +685,7 @@
 			snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
 		}
 	}
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	return 0;
 }
 
@@ -698,9 +698,9 @@
 	int left, right;
 	
 	left = right = 1;
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], &left, &right, 0);
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	*active = (left || right) ? 1 : 0;
 	return 0;
 }
@@ -714,9 +714,9 @@
 	int left, right;
 	
 	left = right = 1;
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	snd_mixer_oss_get_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], &left, &right, 1);
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	*active = (left || right) ? 1 : 0;
 	return 0;
 }
@@ -728,9 +728,9 @@
 	snd_card_t *card = fmixer->card;
 	struct slot *slot = (struct slot *)pslot->private_data;
 	
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	return 0;
 }
 
@@ -741,9 +741,9 @@
 	snd_card_t *card = fmixer->card;
 	struct slot *slot = (struct slot *)pslot->private_data;
 	
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->kcontrol[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	return 0;
 }
 
@@ -764,12 +764,11 @@
 		err = -ENOMEM;
 		goto __unlock;
 	}
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
 	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
 	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
 	snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
-	read_unlock(&card->control_rwlock);
 	for (idx = 0; idx < 32; idx++) {
 		if (!(mixer->mask_recsrc & (1 << idx)))
 			continue;
@@ -785,10 +784,8 @@
 		}
 	}
 	err = 0;
-	goto __unalloc;
       __unlock:
-      	read_unlock(&card->control_rwlock);
-      __unalloc:
+     	up_read(&card->controls_rwsem);
       	if (uctl)
       		kfree(uctl);
       	if (uinfo)
@@ -813,7 +810,7 @@
 		err = -ENOMEM;
 		goto __unlock;
 	}
-	read_lock(&card->control_rwlock);
+	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
 	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
 	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
@@ -838,7 +835,7 @@
 		snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
 	err = 0;
       __unlock:
-	read_unlock(&card->control_rwlock);
+	up_read(&card->controls_rwsem);
 	if (uctl)
 		kfree(uctl);
 	if (uinfo)

  reply	other threads:[~2002-12-03 14:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-12-03  3:07 2.5.50: sleeping function called from illegal context Duncan Sands
2002-12-03 12:01 ` Takashi Iwai
2002-12-03  3:55   ` Duncan Sands
2002-12-03 13:56     ` Takashi Iwai
2002-12-03  5:57       ` Duncan Sands
2002-12-03 14:56         ` Takashi Iwai [this message]
2002-12-03  6:39           ` Duncan Sands
2002-12-06 13:13           ` Duncan Sands
2002-12-03 18:34         ` Paul Davis
     [not found] <3DE3F32200B4A5E8@mel-rti20.wanadoo.fr>
2002-12-03 12:21 ` Duncan Sands
2002-12-04 15:41   ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5hhedv9mng.wl@alsa2.suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@lists.sourceforge.net \
    --cc=baldrick@wanadoo.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.