summaryrefslogtreecommitdiff
path: root/drivers/dahdi/voicebus/GpakCust.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2009-05-07 19:42:00 +0000
committerShaun Ruffell <sruffell@digium.com>2009-05-07 19:42:00 +0000
commita6ebb39e2f623929944d953bb80ae77862732b1c (patch)
tree36dca124131d143ec53896bfabd092dbeb47573d /drivers/dahdi/voicebus/GpakCust.c
parent86856e80af24bcfaa4829d8d8d90c937a86e6c3f (diff)
voicebus: Create workqueue for each vpmadt032 instance.
Depending on the system latency, the deferred work for the vpmadt032 can take up to 200ms. This change allows each vpmadt032 to use its own workqueue, and not the global system workqueue. This prevents vpm operations from blocking the main system workqueue for extended periods. This restores the behavior to the way it was before the common vpmadt032 code was moved out of the wctdm24xxp and wcte12xp drivers. DAHDI-260 voicebus-squash: Adding the wq name. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6572 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/voicebus/GpakCust.c')
-rw-r--r--drivers/dahdi/voicebus/GpakCust.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/dahdi/voicebus/GpakCust.c b/drivers/dahdi/voicebus/GpakCust.c
index 76a9b41..d5bbadd 100644
--- a/drivers/dahdi/voicebus/GpakCust.c
+++ b/drivers/dahdi/voicebus/GpakCust.c
@@ -340,7 +340,7 @@ static void vpmadt032_check_and_schedule_update(struct vpmadt032 *vpm, int chann
* parameters to a work queue so the caller can continue to
* proceed with setting up the call.
*/
- schedule_work(&vpm->work);
+ queue_work(vpm->wq, &vpm->work);
}
}
int vpmadt032_echocan_create(struct vpmadt032 *vpm, int channo,
@@ -381,15 +381,26 @@ void vpmadt032_echocan_free(struct vpmadt032 *vpm, struct dahdi_chan *chan,
}
EXPORT_SYMBOL(vpmadt032_echocan_free);
-struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options)
+struct vpmadt032 *
+vpmadt032_alloc(struct vpmadt032_options *options, const char *board_name)
{
struct vpmadt032 *vpm;
int i;
+ const char *suffix = "-vpm";
+ size_t length;
+
might_sleep();
- vpm = kzalloc(sizeof(*vpm), GFP_KERNEL);
- if (!vpm)
+ length = strlen(board_name) + strlen(suffix) + 1;
+
+ /* Add a little extra to store the wq_name. */
+ vpm = kzalloc(sizeof(*vpm) + length, GFP_KERNEL);
+ if (!vpm) {
return NULL;
+ }
+
+ strcpy(vpm->wq_name, board_name);
+ strcat(vpm->wq_name, suffix);
/* Init our vpmadt032 struct */
memcpy(&vpm->options, options, sizeof(*options));
@@ -401,6 +412,16 @@ struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options)
vpm->curpage = 0x80;
vpm->dspid = -1;
+ /* Do not use the global workqueue for processing these events. Some of
+ * the operations can take 100s of ms, most of that time spent sleeping.
+ * On single CPU systems, this unduly serializes operations accross
+ * multiple vpmadt032 instances. */
+ vpm->wq = create_singlethread_workqueue(vpm->wq_name);
+ if (!vpm->wq) {
+ kfree(vpm);
+ return NULL;
+ }
+
/* Place this structure in the ifaces array so that the DspId from the
* Gpak Library can be used to locate it. */
write_lock(&ifacelock);
@@ -434,6 +455,8 @@ vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
gpakPingDspStat_t pingstatus;
BUG_ON(!vpm->setchanconfig_from_state);
+ BUG_ON(!vpm->wq);
+
might_sleep();
if (vpm->options.debug & DEBUG_ECHOCAN)
@@ -530,6 +553,9 @@ void vpmadt032_free(struct vpmadt032 *vpm)
LIST_HEAD(local_list);
BUG_ON(!vpm);
+ BUG_ON(!vpm->wq);
+
+ destroy_workqueue(vpm->wq);
/* Move all the commands onto the local list protected by the locks */
spin_lock_irqsave(&vpm->list_lock, flags);