wctc4xxp: Cleanup RTP for unopened channels.

When we start the shutdown sequence for a channel, there is no need to submit
any RTP packets that are queued on the command list. Under extreme load with
many backed up RTP packets it was possible to have RTP packets submitted after
the channel shutdown process started.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
This commit is contained in:
Shaun Ruffell 2014-05-08 13:46:18 -05:00 committed by Russ Meyerriecks
parent 6341783cc8
commit b5ac763f29
2 changed files with 25 additions and 7 deletions

View File

@ -168,8 +168,9 @@ static void dtc_release(struct dahdi_transcoder_channel *chan)
BUG_ON(!chan);
if (chan->parent && chan->parent->release) {
chan->parent->release(chan);
} else {
dahdi_tc_clear_busy(chan);
}
dahdi_tc_clear_busy(chan);
}
static int dahdi_tc_release(struct inode *inode, struct file *file)

View File

@ -1421,7 +1421,7 @@ static struct tcb *
wctc4xxp_create_rtp_cmd(struct wcdte *wc, struct dahdi_transcoder_channel *dtc,
size_t inbytes)
{
const struct channel_pvt *cpvt = dtc->pvt;
struct channel_pvt *cpvt = dtc->pvt;
struct rtp_packet *packet;
struct tcb *cmd;
@ -1429,6 +1429,7 @@ wctc4xxp_create_rtp_cmd(struct wcdte *wc, struct dahdi_transcoder_channel *dtc,
if (!cmd)
return NULL;
cmd->cpvt = cpvt;
packet = cmd->data;
BUG_ON(cmd->data_len < sizeof(*packet));
@ -1698,6 +1699,16 @@ wctc4xxp_cleanup_channel_private(struct wcdte *wc,
unsigned long flags;
LIST_HEAD(local_list);
/* Once we cleanup this channel, we do not want any queued packets
* waiting to be transmitted. Anything on the hardware descriptor ring
* will be flushed by the csm_encaps command to shutdown the channel. */
spin_lock_irqsave(&wc->cmd_list_lock, flags);
list_for_each_entry_safe(cmd, temp, &wc->cmd_list, node) {
if (cmd->cpvt == cpvt)
list_move(&cmd->node, &local_list);
}
spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
spin_lock_irqsave(&cpvt->lock, flags);
list_splice_init(&cpvt->rx_queue, &local_list);
dahdi_tc_clear_data_waiting(dtc);
@ -1913,7 +1924,9 @@ wctc4xxp_operation_release(struct dahdi_transcoder_channel *dtc)
packets_sent, packets_received);
}
/* Remove any packets that are waiting on the outbound queue. */
dahdi_tc_clear_busy(dtc);
wctc4xxp_cleanup_channel_private(wc, dtc);
index = cpvt->timeslot_in_num/2;
BUG_ON(index >= wc->numchannels);
@ -2480,11 +2493,15 @@ queue_rtp_packet(struct wcdte *wc, struct tcb *cmd)
}
cpvt = dtc->pvt;
spin_lock_irqsave(&cpvt->lock, flags);
list_add_tail(&cmd->node, &cpvt->rx_queue);
dahdi_tc_set_data_waiting(dtc);
spin_unlock_irqrestore(&cpvt->lock, flags);
dahdi_transcoder_alert(dtc);
if (dahdi_tc_is_busy(dtc)) {
spin_lock_irqsave(&cpvt->lock, flags);
list_add_tail(&cmd->node, &cpvt->rx_queue);
dahdi_tc_set_data_waiting(dtc);
spin_unlock_irqrestore(&cpvt->lock, flags);
dahdi_transcoder_alert(dtc);
} else {
free_cmd(cmd);
}
return;
}