dahdi_dynamic: Do not depend on BKL for serialization of dspan creation.

Also makes it safe to unregister a dynamic driver when there aren't any
open channels on the dynamic spans.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Kinsey Moore <kmoore@digium.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9580 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
Shaun Ruffell 2011-01-03 18:26:04 +00:00
parent 593787e3b3
commit 28f559e2ac

View File

@ -90,6 +90,7 @@ static struct tasklet_struct dahdi_dynamic_tlet;
static void dahdi_dynamic_tasklet(unsigned long data);
#endif
static DEFINE_MUTEX(dspan_mutex);
static DEFINE_SPINLOCK(dspan_lock);
static DEFINE_SPINLOCK(driver_lock);
@ -456,7 +457,7 @@ static struct dahdi_dynamic_driver *find_driver(const char *name)
return found;
}
static int destroy_dynamic(struct dahdi_dynamic_span *dds)
static int _destroy_dynamic(struct dahdi_dynamic_span *dds)
{
unsigned long flags;
struct dahdi_dynamic *d;
@ -486,6 +487,15 @@ static int destroy_dynamic(struct dahdi_dynamic_span *dds)
return 0;
}
static int destroy_dynamic(struct dahdi_dynamic_span *dds)
{
int ret;
mutex_lock(&dspan_mutex);
ret = _destroy_dynamic(dds);
mutex_unlock(&dspan_mutex);
return ret;
}
static int dahdi_dynamic_rbsbits(struct dahdi_chan *chan, int bits)
{
/* Don't have to do anything */
@ -541,7 +551,7 @@ static const struct dahdi_span_ops dynamic_ops = {
.sync_tick = dahdi_dynamic_sync_tick,
};
static int create_dynamic(struct dahdi_dynamic_span *dds)
static int _create_dynamic(struct dahdi_dynamic_span *dds)
{
int res = 0;
struct dahdi_dynamic *d;
@ -673,6 +683,15 @@ static int create_dynamic(struct dahdi_dynamic_span *dds)
return x;
}
static int create_dynamic(struct dahdi_dynamic_span *dds)
{
int ret;
mutex_lock(&dspan_mutex);
ret = _create_dynamic(dds);
mutex_unlock(&dspan_mutex);
return ret;
}
#ifdef ENABLE_TASKLETS
static void dahdi_dynamic_tasklet(unsigned long data)
{
@ -740,6 +759,8 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
struct dahdi_dynamic *d, *n;
unsigned long flags;
mutex_lock(&dspan_mutex);
list_for_each_entry_safe(d, n, &dspan_list, list) {
if (d->driver == dri) {
if (d->pvt) {
@ -764,6 +785,8 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
list_del_rcu(&dri->list);
spin_unlock_irqrestore(&driver_lock, flags);
synchronize_rcu();
mutex_unlock(&dspan_mutex);
}
EXPORT_SYMBOL(dahdi_dynamic_unregister_driver);