aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorDavid Laight <David.Laight@ACULAB.COM>2014-07-22 04:59:08 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-22 16:32:10 -0400
commit723189faca78f2b70fcf9088f056a2440986cc45 (patch)
tree47b1dc85680d2e48e9a1a13c4bc2bad85c774d08 /net/sctp
parent8fd90bb889635fa1e7f80a3950948cc2e74c1446 (diff)
net: sctp: Open out the check for Nagle
The check for Nagle contains 6 separate checks all of which must be true before a data packet is delayed. Separate out each into its own 'if (test) return SCTP_XMIT_OK' so that the reasons can be individually described. Also return directly with SCTP_XMIT_RWND_FULL. Delete the now-unused 'retval' variable and 'finish' label from sctp_packet_can_append_data(). Signed-off-by: David Laight <david.laight@aculab.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/output.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 01ab8e0723f0..f3bf0ae244df 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -633,7 +633,6 @@ nomem:
633static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, 633static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
634 struct sctp_chunk *chunk) 634 struct sctp_chunk *chunk)
635{ 635{
636 sctp_xmit_t retval = SCTP_XMIT_OK;
637 size_t datasize, rwnd, inflight, flight_size; 636 size_t datasize, rwnd, inflight, flight_size;
638 struct sctp_transport *transport = packet->transport; 637 struct sctp_transport *transport = packet->transport;
639 struct sctp_association *asoc = transport->asoc; 638 struct sctp_association *asoc = transport->asoc;
@@ -658,15 +657,11 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
658 657
659 datasize = sctp_data_size(chunk); 658 datasize = sctp_data_size(chunk);
660 659
661 if (datasize > rwnd) { 660 if (datasize > rwnd && inflight > 0)
662 if (inflight > 0) { 661 /* We have (at least) one data chunk in flight,
663 /* We have (at least) one data chunk in flight, 662 * so we can't fall back to rule 6.1 B).
664 * so we can't fall back to rule 6.1 B). 663 */
665 */ 664 return SCTP_XMIT_RWND_FULL;
666 retval = SCTP_XMIT_RWND_FULL;
667 goto finish;
668 }
669 }
670 665
671 /* RFC 2960 6.1 Transmission of DATA Chunks 666 /* RFC 2960 6.1 Transmission of DATA Chunks
672 * 667 *
@@ -680,36 +675,44 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
680 * When a Fast Retransmit is being performed the sender SHOULD 675 * When a Fast Retransmit is being performed the sender SHOULD
681 * ignore the value of cwnd and SHOULD NOT delay retransmission. 676 * ignore the value of cwnd and SHOULD NOT delay retransmission.
682 */ 677 */
683 if (chunk->fast_retransmit != SCTP_NEED_FRTX) 678 if (chunk->fast_retransmit != SCTP_NEED_FRTX &&
684 if (flight_size >= transport->cwnd) { 679 flight_size >= transport->cwnd)
685 retval = SCTP_XMIT_RWND_FULL; 680 return SCTP_XMIT_RWND_FULL;
686 goto finish;
687 }
688 681
689 /* Nagle's algorithm to solve small-packet problem: 682 /* Nagle's algorithm to solve small-packet problem:
690 * Inhibit the sending of new chunks when new outgoing data arrives 683 * Inhibit the sending of new chunks when new outgoing data arrives
691 * if any previously transmitted data on the connection remains 684 * if any previously transmitted data on the connection remains
692 * unacknowledged. 685 * unacknowledged.
693 */ 686 */
694 if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) &&
695 inflight && sctp_state(asoc, ESTABLISHED)) {
696 unsigned int max = transport->pathmtu - packet->overhead;
697 unsigned int len = chunk->skb->len + q->out_qlen;
698
699 /* Check whether this chunk and all the rest of pending
700 * data will fit or delay in hopes of bundling a full
701 * sized packet.
702 * Don't delay large message writes that may have been
703 * fragmeneted into small peices.
704 */
705 if ((len < max) && chunk->msg->can_delay) {
706 retval = SCTP_XMIT_NAGLE_DELAY;
707 goto finish;
708 }
709 }
710 687
711finish: 688 if (sctp_sk(asoc->base.sk)->nodelay)
712 return retval; 689 /* Nagle disabled */
690 return SCTP_XMIT_OK;
691
692 if (!sctp_packet_empty(packet))
693 /* Append to packet */
694 return SCTP_XMIT_OK;
695
696 if (inflight == 0)
697 /* Nothing unacked */
698 return SCTP_XMIT_OK;
699
700 if (!sctp_state(asoc, ESTABLISHED))
701 return SCTP_XMIT_OK;
702
703 /* Check whether this chunk and all the rest of pending data will fit
704 * or delay in hopes of bundling a full sized packet.
705 */
706 if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead)
707 /* Enough data queued to fill a packet */
708 return SCTP_XMIT_OK;
709
710 /* Don't delay large message writes that may have been fragmented */
711 if (!chunk->msg->can_delay)
712 return SCTP_XMIT_OK;
713
714 /* Defer until all data acked or packet full */
715 return SCTP_XMIT_NAGLE_DELAY;
713} 716}
714 717
715/* This private function does management things when adding DATA chunk */ 718/* This private function does management things when adding DATA chunk */