Commit 96e0418e authored by Marcelo Ricardo Leitner's avatar Marcelo Ricardo Leitner Committed by David S. Miller

sctp: move outq data rtx code out of sctp_outq_flush

This patch renames current sctp_outq_flush_rtx to __sctp_outq_flush_rtx
and create a new sctp_outq_flush_rtx, with the code that was on
sctp_outq_flush. Again, the idea is to have functions with small and
defined objectives.

Yes, there is an open-coded path selection in the now sctp_outq_flush_rtx.
That is kept as is for now because it may be very different when we
implement retransmission path selection algorithms for CMT-SCTP.
Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7a0b9df6
...@@ -601,13 +601,13 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport, ...@@ -601,13 +601,13 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
/* /*
* Transmit DATA chunks on the retransmit queue. Upon return from * Transmit DATA chunks on the retransmit queue. Upon return from
* sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which * __sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which
* need to be transmitted by the caller. * need to be transmitted by the caller.
* We assume that pkt->transport has already been set. * We assume that pkt->transport has already been set.
* *
* The return value is a normal kernel error return value. * The return value is a normal kernel error return value.
*/ */
static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, static int __sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
int rtx_timeout, int *start_timer) int rtx_timeout, int *start_timer)
{ {
struct sctp_transport *transport = pkt->transport; struct sctp_transport *transport = pkt->transport;
...@@ -987,6 +987,57 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q, ...@@ -987,6 +987,57 @@ static void sctp_outq_flush_ctrl(struct sctp_outq *q,
} }
} }
/* Returns false if new data shouldn't be sent */
static bool sctp_outq_flush_rtx(struct sctp_outq *q,
struct sctp_transport **_transport,
struct list_head *transport_list,
int rtx_timeout)
{
struct sctp_transport *transport = *_transport;
struct sctp_packet *packet = transport ? &transport->packet : NULL;
struct sctp_association *asoc = q->asoc;
int error, start_timer = 0;
if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED)
return false;
if (transport != asoc->peer.retran_path) {
/* Switch transports & prepare the packet. */
transport = asoc->peer.retran_path;
*_transport = transport;
if (list_empty(&transport->send_ready))
list_add_tail(&transport->send_ready,
transport_list);
packet = &transport->packet;
sctp_packet_config(packet, asoc->peer.i.init_tag,
asoc->peer.ecn_capable);
}
error = __sctp_outq_flush_rtx(q, packet, rtx_timeout, &start_timer);
if (error < 0)
asoc->base.sk->sk_err = -error;
if (start_timer) {
sctp_transport_reset_t3_rtx(transport);
transport->last_time_sent = jiffies;
}
/* This can happen on COOKIE-ECHO resend. Only
* one chunk can get bundled with a COOKIE-ECHO.
*/
if (packet->has_cookie_echo)
return false;
/* Don't send new data if there is still data
* waiting to retransmit.
*/
if (!list_empty(&q->retransmit))
return false;
return true;
}
/* /*
* Try to flush an outqueue. * Try to flush an outqueue.
* *
...@@ -1000,12 +1051,10 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) ...@@ -1000,12 +1051,10 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
{ {
struct sctp_packet *packet; struct sctp_packet *packet;
struct sctp_association *asoc = q->asoc; struct sctp_association *asoc = q->asoc;
__u32 vtag = asoc->peer.i.init_tag;
struct sctp_transport *transport = NULL; struct sctp_transport *transport = NULL;
struct sctp_chunk *chunk; struct sctp_chunk *chunk;
enum sctp_xmit status; enum sctp_xmit status;
int error = 0; int error = 0;
int start_timer = 0;
/* These transports have chunks to send. */ /* These transports have chunks to send. */
struct list_head transport_list; struct list_head transport_list;
...@@ -1053,45 +1102,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) ...@@ -1053,45 +1102,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
* current cwnd). * current cwnd).
*/ */
if (!list_empty(&q->retransmit)) { if (!list_empty(&q->retransmit)) {
if (asoc->peer.retran_path->state == SCTP_UNCONFIRMED) if (!sctp_outq_flush_rtx(q, &transport, &transport_list,
goto sctp_flush_out; rtx_timeout))
if (transport == asoc->peer.retran_path) break;
goto retran; /* We may have switched current transport */
/* Switch transports & prepare the packet. */
transport = asoc->peer.retran_path;
if (list_empty(&transport->send_ready)) {
list_add_tail(&transport->send_ready,
&transport_list);
}
packet = &transport->packet; packet = &transport->packet;
sctp_packet_config(packet, vtag,
asoc->peer.ecn_capable);
retran:
error = sctp_outq_flush_rtx(q, packet,
rtx_timeout, &start_timer);
if (error < 0)
asoc->base.sk->sk_err = -error;
if (start_timer) {
sctp_transport_reset_t3_rtx(transport);
transport->last_time_sent = jiffies;
}
/* This can happen on COOKIE-ECHO resend. Only
* one chunk can get bundled with a COOKIE-ECHO.
*/
if (packet->has_cookie_echo)
goto sctp_flush_out;
/* Don't send new data if there is still data
* waiting to retransmit.
*/
if (!list_empty(&q->retransmit))
goto sctp_flush_out;
} }
/* Apply Max.Burst limitation to the current transport in /* Apply Max.Burst limitation to the current transport in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment