dahdi: Remove bigzaplock by converting chan_lock to spinlock_t.
The bigzaplock was used to prevent changes to all the channels during masterspan processing while conference parameters were changing. The master span processing also took a global lock out on the chan_lock to prevent new channels from being registered or unregistered during processing. Instead of grabbing both those locks, just changing the semantics of chan_lock to those of bigzaplock seems to fit the bill and removes another lock from the driver (and saves ~10 ns on a 2.40 GHz Xeon in prcocess_masterspan) chan_lock is a candidate for conversion to RCU but usage in conferencing (bigzaplock type usage) needs to be audited carefully before conversion. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Kinsey Moore <kmoore@digium.com> Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> Review: https://reviewboard.asterisk.org/r/940/ git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9414 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
c3ae5634d7
commit
1c462653e7
@ -376,7 +376,6 @@ struct dahdi_timer {
|
||||
static LIST_HEAD(dahdi_timers);
|
||||
|
||||
static DEFINE_SPINLOCK(dahdi_timer_lock);
|
||||
static DEFINE_SPINLOCK(bigzaplock);
|
||||
|
||||
struct dahdi_zone {
|
||||
atomic_t refcount;
|
||||
@ -398,12 +397,12 @@ struct dahdi_zone {
|
||||
|
||||
#ifdef DEFINE_RWLOCK
|
||||
static DEFINE_RWLOCK(zone_lock);
|
||||
static DEFINE_RWLOCK(chan_lock);
|
||||
#else
|
||||
static rwlock_t zone_lock = RW_LOCK_UNLOCKED;
|
||||
static rwlock_t chan_lock = RW_LOCK_UNLOCKED;
|
||||
#endif
|
||||
|
||||
static DEFINE_SPINLOCK(chan_lock);
|
||||
|
||||
struct pseudo_chan {
|
||||
struct dahdi_chan chan;
|
||||
struct list_head node;
|
||||
@ -1655,7 +1654,7 @@ static int dahdi_chan_reg(struct dahdi_chan *chan)
|
||||
dahdi_set_law(chan, DAHDI_LAW_DEFAULT);
|
||||
close_channel(chan);
|
||||
|
||||
write_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
|
||||
if (chans[x])
|
||||
continue;
|
||||
@ -1669,7 +1668,7 @@ static int dahdi_chan_reg(struct dahdi_chan *chan)
|
||||
set_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags);
|
||||
break;
|
||||
}
|
||||
write_unlock_irqrestore(&chan_lock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
if (DAHDI_MAX_CHANNELS == x) {
|
||||
module_printk(KERN_ERR, "No more channels available\n");
|
||||
return -ENOMEM;
|
||||
@ -2075,7 +2074,7 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
|
||||
chan->hdlcnetdev = NULL;
|
||||
}
|
||||
#endif
|
||||
write_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags)) {
|
||||
chans[chan->channo] = NULL;
|
||||
clear_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags);
|
||||
@ -2113,7 +2112,7 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
|
||||
}
|
||||
}
|
||||
chan->channo = -1;
|
||||
write_unlock_irqrestore(&chan_lock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
}
|
||||
|
||||
static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf,
|
||||
@ -2914,9 +2913,9 @@ static struct dahdi_chan *dahdi_alloc_pseudo(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
write_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
list_add_tail(&pseudo->node, &pseudo_chans);
|
||||
write_unlock_irqrestore(&chan_lock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
|
||||
snprintf(pseudo->chan.name, sizeof(pseudo->chan.name)-1,
|
||||
"Pseudo/%d", pseudo->chan.channo);
|
||||
@ -2934,9 +2933,9 @@ static void dahdi_free_pseudo(struct dahdi_chan *chan)
|
||||
|
||||
pseudo = chan_to_pseudo(chan);
|
||||
|
||||
write_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
list_del(&pseudo->node);
|
||||
write_unlock_irqrestore(&chan_lock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
|
||||
dahdi_chan_unreg(chan);
|
||||
kfree(pseudo);
|
||||
@ -4864,14 +4863,14 @@ static int dahdi_ioctl_setconf(struct file *file, unsigned long data)
|
||||
if ((!conf.confmode) && conf.confno)
|
||||
return -EINVAL;
|
||||
conf.chan = chan->channo; /* return with real channel # */
|
||||
spin_lock_irqsave(&bigzaplock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock(&chan->lock);
|
||||
if (conf.confno == -1)
|
||||
conf.confno = dahdi_first_empty_conference();
|
||||
if ((conf.confno < 1) && (conf.confmode)) {
|
||||
/* No more empty conferences */
|
||||
spin_unlock(&chan->lock);
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
/* if changing confs, clear last added info */
|
||||
@ -4922,7 +4921,7 @@ static int dahdi_ioctl_setconf(struct file *file, unsigned long data)
|
||||
}
|
||||
|
||||
spin_unlock(&chan->lock);
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
if (copy_to_user((void __user *)data, &conf, sizeof(conf)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -4952,7 +4951,7 @@ static int dahdi_ioctl_conflink(struct file *file, unsigned long data)
|
||||
if (conf.chan && (conf.chan == conf.confno))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&bigzaplock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
spin_lock(&chan->lock);
|
||||
|
||||
/* if to clear all links */
|
||||
@ -4961,7 +4960,7 @@ static int dahdi_ioctl_conflink(struct file *file, unsigned long data)
|
||||
memset(conf_links, 0, sizeof(conf_links));
|
||||
recalc_maxlinks();
|
||||
spin_unlock(&chan->lock);
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
/* look for already existant specified combination */
|
||||
@ -5000,7 +4999,7 @@ static int dahdi_ioctl_conflink(struct file *file, unsigned long data)
|
||||
}
|
||||
recalc_maxlinks();
|
||||
spin_unlock(&chan->lock);
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -5289,9 +5288,9 @@ dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd,
|
||||
case DAHDI_CONFMUTE: /* set confmute flag */
|
||||
get_user(j, (int __user *)data); /* get conf # */
|
||||
if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
|
||||
spin_lock_irqsave(&bigzaplock, flags);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
chan->confmute = j;
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
break;
|
||||
case DAHDI_GETCONFMUTE: /* get confmute flag */
|
||||
if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL);
|
||||
@ -8455,10 +8454,10 @@ static void process_masterspan(void)
|
||||
* to be called (1000 / (DAHDI_CHUNKSIZE / 8)) times per second. */
|
||||
atomic_inc(&core_timer.count);
|
||||
#endif
|
||||
/* Hold the big zap lock for the duration of major
|
||||
/* Hold the chan_lock for the duration of major
|
||||
activities which touch all sorts of channels */
|
||||
spin_lock_irqsave(&bigzaplock, flags);
|
||||
read_lock(&chan_lock);
|
||||
spin_lock_irqsave(&chan_lock, flags);
|
||||
|
||||
/* Process any timers */
|
||||
process_timers();
|
||||
/* If we have dynamic stuff, call the ioctl with 0,0 parameters to
|
||||
@ -8542,8 +8541,7 @@ static void process_masterspan(void)
|
||||
s->ops->sync_tick(s, s == master);
|
||||
#endif
|
||||
}
|
||||
read_unlock(&chan_lock);
|
||||
spin_unlock_irqrestore(&bigzaplock, flags);
|
||||
spin_unlock_irqrestore(&chan_lock, flags);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DAHDI_CORE_TIMER
|
||||
|
Loading…
Reference in New Issue
Block a user