dahdi_dynamic: Use a tasklet for flushing dynamic drivers.
Signed-off-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
committed by
Russ Meyerriecks
parent
d889fb39d3
commit
f44b252472
@@ -88,6 +88,8 @@ static int txerrors;
|
||||
static struct tasklet_struct dahdi_dynamic_tlet;
|
||||
|
||||
static void dahdi_dynamic_tasklet(unsigned long data);
|
||||
#else
|
||||
static struct tasklet_struct dahdi_dynamic_flush_tlet;
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(dspan_mutex);
|
||||
@@ -208,12 +210,25 @@ static void __dahdi_dynamic_run(void)
|
||||
dahdi_dynamic_sendmessage(d);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TASKLETS
|
||||
/* If tasklets are not enabled, the above section will be called in
|
||||
* interrupt context and the flushing of each driver will be called in a
|
||||
* separate tasklet that only handles that. This is necessary since some
|
||||
* of the dynamic spans need to call functions that require interrupts
|
||||
* to be enabled but dahdi_transmit / ...sendmessage needs to be called
|
||||
* each time the masterspan is processed which happens with interrupts
|
||||
* disabled.
|
||||
*
|
||||
*/
|
||||
tasklet_hi_schedule(&dahdi_dynamic_flush_tlet);
|
||||
#else
|
||||
list_for_each_entry_rcu(drv, &driver_list, list) {
|
||||
/* Flush any traffic still pending in the driver */
|
||||
if (drv->flush) {
|
||||
drv->flush();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -708,6 +723,20 @@ static void dahdi_dynamic_tasklet(unsigned long data)
|
||||
}
|
||||
taskletpending = 0;
|
||||
}
|
||||
#else
|
||||
static void dahdi_dynamic_flush_tasklet(unsigned long data)
|
||||
{
|
||||
struct dahdi_dynamic_driver *drv;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(drv, &driver_list, list) {
|
||||
/* Flush any traffic still pending in the driver */
|
||||
if (drv->flush) {
|
||||
drv->flush();
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int dahdi_dynamic_ioctl(unsigned int cmd, unsigned long data)
|
||||
@@ -840,6 +869,8 @@ static int dahdi_dynamic_init(void)
|
||||
mod_timer(&alarmcheck, jiffies + 1 * HZ);
|
||||
#ifdef ENABLE_TASKLETS
|
||||
tasklet_init(&dahdi_dynamic_tlet, dahdi_dynamic_tasklet, 0);
|
||||
#else
|
||||
tasklet_init(&dahdi_dynamic_flush_tlet, dahdi_dynamic_flush_tasklet, 0);
|
||||
#endif
|
||||
dahdi_set_dynamic_ops(&dahdi_dynamic_ops);
|
||||
|
||||
@@ -856,6 +887,9 @@ static void dahdi_dynamic_cleanup(void)
|
||||
tasklet_disable(&dahdi_dynamic_tlet);
|
||||
tasklet_kill(&dahdi_dynamic_tlet);
|
||||
}
|
||||
#else
|
||||
tasklet_disable(&dahdi_dynamic_flush_tlet);
|
||||
tasklet_kill(&dahdi_dynamic_flush_tlet);
|
||||
#endif
|
||||
del_timer_sync(&alarmcheck);
|
||||
/* Must call again in case it was running before and rescheduled
|
||||
|
||||
Reference in New Issue
Block a user