diff options
author | David Laight <David.Laight@ACULAB.COM> | 2014-07-22 04:59:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-22 16:32:10 -0400 |
commit | 723189faca78f2b70fcf9088f056a2440986cc45 (patch) | |
tree | 47b1dc85680d2e48e9a1a13c4bc2bad85c774d08 /net/sctp | |
parent | 8fd90bb889635fa1e7f80a3950948cc2e74c1446 (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.c | 69 |
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: | |||
633 | static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | 633 | static 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 | ||
711 | finish: | 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 */ |