summaryrefslogtreecommitdiff
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
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
-rw-r--r--drivers/dahdi/voicebus/GpakCust.c34
-rw-r--r--drivers/dahdi/voicebus/GpakCust.h6
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c5
-rw-r--r--drivers/dahdi/wcte12xp/base.c2
4 files changed, 39 insertions, 8 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);
diff --git a/drivers/dahdi/voicebus/GpakCust.h b/drivers/dahdi/voicebus/GpakCust.h
index 72cfdd4..bdb9cfb 100644
--- a/drivers/dahdi/voicebus/GpakCust.h
+++ b/drivers/dahdi/voicebus/GpakCust.h
@@ -107,6 +107,7 @@ struct vpmadt032 {
void *context;
const struct dahdi_span *span;
struct work_struct work;
+ struct workqueue_struct *wq;
int dspid;
struct semaphore sem;
unsigned long control;
@@ -124,6 +125,8 @@ struct vpmadt032 {
unsigned char curtone[MAX_CHANNELS_PER_SPAN];
struct vpmadt032_options options;
void (*setchanconfig_from_state)(struct vpmadt032 *vpm, int channel, struct GpakChannelConfig *chanconfig);
+ /* This must be last */
+ char wq_name[0];
};
struct voicebus;
@@ -134,7 +137,8 @@ struct dahdi_echocan_state;
char vpmadt032tone_to_zaptone(GpakToneCodes_t tone);
int vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb);
-struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options);
+struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options,
+ const char *board_name);
void vpmadt032_free(struct vpmadt032 *vpm);
int vpmadt032_echocan_create(struct vpmadt032 *vpm, int channo,
struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p);
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 4893023..abe800c 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -3597,9 +3597,10 @@ retry:
options.vpmnlpthresh = vpmnlpthresh;
options.vpmnlpmaxsupp = vpmnlpmaxsupp;
- if (!(wc->vpmadt032=vpmadt032_alloc(&options))) {
+ wc->vpmadt032 = vpmadt032_alloc(&options, wc->board_name);
+ if (!wc->vpmadt032)
return -ENOMEM;
- }
+
wc->vpmadt032->setchanconfig_from_state = setchanconfig_from_state;
wc->vpmadt032->context = wc;
wc->vpmadt032->span = &wc->span;
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 7ef378b..ec1d7ec 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -1385,7 +1385,7 @@ static int t1_hardware_post_init(struct t1 *wc)
options.vpmnlpthresh = vpmnlpthresh;
options.vpmnlpmaxsupp = vpmnlpmaxsupp;
- wc->vpmadt032 = vpmadt032_alloc(&options);
+ wc->vpmadt032 = vpmadt032_alloc(&options, wc->name);
if (!wc->vpmadt032)
return -ENOMEM;