[svn-commits] sruffell: linux/trunk r9621 - /linux/trunk/drivers/dahdi/dahdi-base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jan 6 21:34:14 UTC 2011


Author: sruffell
Date: Thu Jan  6 15:34:10 2011
New Revision: 9621

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9621
Log:
dahdi: Do not call dahdi_check_conf under lock.

dahdi_check_conf() acqurires the locks as needed when scanning the
channels and should not be called under any spinlocks.

Fixes a regression that Tzafrir reported in #asterisk-dev that he could
trigger via "asterisk -rx 'channel originate Local/600 at demo
Application Meetme 3000,d'"

Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9621&r1=9620&r2=9621
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Thu Jan  6 15:34:10 2011
@@ -1493,8 +1493,6 @@
 		chan->dacs_chan = NULL;
 
 	chan->confmute = 0;
-	/* release conference resource, if any to release */
-	if (oldconf) dahdi_check_conf(oldconf);
 	chan->gotgs = 0;
 	reset_conf(chan);
 	chan->dacs_chan = NULL;
@@ -1522,6 +1520,10 @@
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
+
+	/* release conference resource, if any to release */
+	if (oldconf)
+		dahdi_check_conf(oldconf);
 
 	if (rxgain)
 		kfree(rxgain);
@@ -5141,7 +5143,7 @@
 	struct dahdi_chan *conf_chan = NULL;
 	unsigned long flags;
 	unsigned int confmode;
-	int j;
+	int oldconf;
 
 	if (copy_from_user(&conf, (void __user *)data, sizeof(conf)))
 		return -EFAULT;
@@ -5173,6 +5175,7 @@
 	/* likewise if 0 mode must have no conf */
 	if ((!conf.confmode) && conf.confno)
 		return -EINVAL;
+	dahdi_check_conf(conf.confno);
 	conf.chan = chan->channo;  /* return with real channel # */
 	spin_lock_irqsave(&chan_lock, flags);
 	spin_lock(&chan->lock);
@@ -5190,13 +5193,11 @@
 		memset(chan->conflast1, 0, DAHDI_MAX_CHUNKSIZE);
 		memset(chan->conflast2, 0, DAHDI_MAX_CHUNKSIZE);
 	}
-	j = chan->confna;  /* save old conference number */
+	oldconf = chan->confna;  /* save old conference number */
 	chan->confna = conf.confno;   /* set conference number */
 	chan->conf_chan = conf_chan;
 	chan->confmode = conf.confmode;  /* set conference mode */
 	chan->_confn = 0;		     /* Clear confn */
-	dahdi_check_conf(j);
-	dahdi_check_conf(conf.confno);
 	if (chan->span && chan->span->ops->dacs) {
 		if ((confmode == DAHDI_CONF_DIGITALMON) &&
 		    (chan->txgain == defgain) &&
@@ -5234,6 +5235,7 @@
 
 	spin_unlock(&chan->lock);
 	spin_unlock_irqrestore(&chan_lock, flags);
+	dahdi_check_conf(oldconf);
 	if (copy_to_user((void __user *)data, &conf, sizeof(conf)))
 		return -EFAULT;
 	return 0;




More information about the svn-commits mailing list