aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccids/ccid3.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index bdd13de4f422..89ef1183e48c 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -785,12 +785,12 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
785{ 785{
786 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 786 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
787 struct dccp_rx_hist_entry *entry, *next, *tail = NULL; 787 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
788 u32 rtt, delta, x_recv, fval, p, tmp2; 788 u32 rtt, delta, x_recv, p;
789 struct timeval tstamp = { 0, }; 789 struct timeval tstamp = { 0, };
790 int interval = 0; 790 int interval = 0;
791 int win_count = 0; 791 int win_count = 0;
792 int step = 0; 792 int step = 0;
793 u64 tmp1; 793 u64 fval;
794 794
795 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 795 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
796 dccphrx_node) { 796 dccphrx_node) {
@@ -834,30 +834,35 @@ found:
834 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", 834 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
835 dccp_role(sk), sk, rtt); 835 dccp_role(sk), sk, rtt);
836 836
837 if (rtt == 0) { 837 /*
838 DCCP_WARN("RTT==0, setting to 1\n"); 838 * Determine the length of the first loss interval via inverse lookup.
839 rtt = 1; 839 * Assume that X_recv can be computed by the throughput equation
840 * s
841 * X_recv = --------
842 * R * fval
843 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
844 */
845 if (rtt == 0) { /* would result in divide-by-zero */
846 DCCP_WARN("RTT==0, returning 1/p = 1\n");
847 return 1000000;
840 } 848 }
841 849
842 dccp_timestamp(sk, &tstamp); 850 dccp_timestamp(sk, &tstamp);
843 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback); 851 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
844 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta); 852 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
845 853
846 if (x_recv == 0) 854 if (x_recv == 0) { /* would also trigger divide-by-zero */
847 x_recv = hcrx->ccid3hcrx_x_recv; 855 DCCP_WARN("X_recv==0\n");
848 856 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
849 tmp1 = (u64)x_recv * (u64)rtt; 857 DCCP_BUG("stored value of X_recv is zero");
850 do_div(tmp1,10000000); 858 return 1000000;
851 tmp2 = (u32)tmp1; 859 }
852
853 if (!tmp2) {
854 DCCP_CRIT("tmp2 = 0, x_recv = %u, rtt =%u\n", x_recv, rtt);
855 return ~0;
856 } 860 }
857 861
858 fval = (hcrx->ccid3hcrx_s * 100000) / tmp2; 862 fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
859 /* do not alter order above or you will get overflow on 32 bit */ 863 fval = scaled_div32(fval, x_recv);
860 p = tfrc_calc_x_reverse_lookup(fval); 864 p = tfrc_calc_x_reverse_lookup(fval);
865
861 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied " 866 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
862 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p); 867 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
863 868