diff options
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 127 |
1 files changed, 55 insertions, 72 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 225c53013172..60e3a5f9fcb4 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -156,26 +156,6 @@ static inline void ccid3_hc_tx_set_state(struct sock *sk, | |||
156 | hctx->ccid3hctx_state = state; | 156 | hctx->ccid3hctx_state = state; |
157 | } | 157 | } |
158 | 158 | ||
159 | static void timeval_sub(struct timeval large, struct timeval small, | ||
160 | struct timeval *result) | ||
161 | { | ||
162 | result->tv_sec = large.tv_sec-small.tv_sec; | ||
163 | if (large.tv_usec < small.tv_usec) { | ||
164 | (result->tv_sec)--; | ||
165 | result->tv_usec = USEC_PER_SEC + | ||
166 | large.tv_usec - small.tv_usec; | ||
167 | } else | ||
168 | result->tv_usec = large.tv_usec-small.tv_usec; | ||
169 | } | ||
170 | |||
171 | static inline void timeval_fix(struct timeval *tv) | ||
172 | { | ||
173 | if (tv->tv_usec >= USEC_PER_SEC) { | ||
174 | tv->tv_sec++; | ||
175 | tv->tv_usec -= USEC_PER_SEC; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | #define CALCX_ARRSIZE 500 | 159 | #define CALCX_ARRSIZE 500 |
180 | 160 | ||
181 | #define CALCX_SPLIT 50000 | 161 | #define CALCX_SPLIT 50000 |
@@ -816,18 +796,22 @@ static void ccid3_hc_tx_update_x(struct sock *sk) | |||
816 | 2 * hctx->ccid3hctx_x_recv), | 796 | 2 * hctx->ccid3hctx_x_recv), |
817 | (hctx->ccid3hctx_s / | 797 | (hctx->ccid3hctx_s / |
818 | TFRC_MAX_BACK_OFF_TIME)); | 798 | TFRC_MAX_BACK_OFF_TIME)); |
819 | } else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) { | 799 | } else { |
820 | u32 rtt = hctx->ccid3hctx_rtt; | 800 | struct timeval now; |
821 | if (rtt < 10) { | 801 | |
822 | rtt = 10; | 802 | do_gettimeofday(&now); |
823 | } /* avoid divide by zero below */ | 803 | if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= |
824 | 804 | hctx->ccid3hctx_rtt) { | |
825 | hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, | 805 | /* Avoid divide by zero below */ |
826 | 2 * hctx->ccid3hctx_x), | 806 | const u32 rtt = max_t(u32, hctx->ccid3hctx_rtt, 10); |
827 | ((hctx->ccid3hctx_s * 100000) / | 807 | |
828 | (rtt / 10))); | 808 | hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, |
829 | /* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */ | 809 | 2 * hctx->ccid3hctx_x), |
830 | do_gettimeofday(&hctx->ccid3hctx_t_ld); | 810 | ((hctx->ccid3hctx_s * 100000) / |
811 | (rtt / 10))); | ||
812 | /* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */ | ||
813 | hctx->ccid3hctx_t_ld = now; | ||
814 | } | ||
831 | } | 815 | } |
832 | 816 | ||
833 | if (hctx->ccid3hctx_x == 0) { | 817 | if (hctx->ccid3hctx_x == 0) { |
@@ -999,14 +983,15 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, | |||
999 | 983 | ||
1000 | /* Set nominal send time for initial packet */ | 984 | /* Set nominal send time for initial packet */ |
1001 | hctx->ccid3hctx_t_nom = now; | 985 | hctx->ccid3hctx_t_nom = now; |
1002 | (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; | 986 | timeval_add_usecs(&hctx->ccid3hctx_t_nom, |
1003 | timeval_fix(&(hctx->ccid3hctx_t_nom)); | 987 | hctx->ccid3hctx_t_ipi); |
1004 | ccid3_calc_new_delta(hctx); | 988 | ccid3_calc_new_delta(hctx); |
1005 | rc = 0; | 989 | rc = 0; |
1006 | break; | 990 | break; |
1007 | case TFRC_SSTATE_NO_FBACK: | 991 | case TFRC_SSTATE_NO_FBACK: |
1008 | case TFRC_SSTATE_FBACK: | 992 | case TFRC_SSTATE_FBACK: |
1009 | delay = now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta; | 993 | delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) - |
994 | hctx->ccid3hctx_delta); | ||
1010 | ccid3_pr_debug("send_packet delay=%ld\n", delay); | 995 | ccid3_pr_debug("send_packet delay=%ld\n", delay); |
1011 | delay /= -1000; | 996 | delay /= -1000; |
1012 | /* divide by -1000 is to convert to ms and get sign right */ | 997 | /* divide by -1000 is to convert to ms and get sign right */ |
@@ -1068,7 +1053,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
1068 | * Algorithm in "8.1. Window Counter Valuer" in | 1053 | * Algorithm in "8.1. Window Counter Valuer" in |
1069 | * draft-ietf-dccp-ccid3-11.txt | 1054 | * draft-ietf-dccp-ccid3-11.txt |
1070 | */ | 1055 | */ |
1071 | quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / | 1056 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count) / |
1072 | (hctx->ccid3hctx_rtt / 4); | 1057 | (hctx->ccid3hctx_rtt / 4); |
1073 | if (quarter_rtt > 0) { | 1058 | if (quarter_rtt > 0) { |
1074 | hctx->ccid3hctx_t_last_win_count = now; | 1059 | hctx->ccid3hctx_t_last_win_count = now; |
@@ -1102,8 +1087,8 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
1102 | hctx->ccid3hctx_t_nom = now; | 1087 | hctx->ccid3hctx_t_nom = now; |
1103 | ccid3_calc_new_t_ipi(hctx); | 1088 | ccid3_calc_new_t_ipi(hctx); |
1104 | ccid3_calc_new_delta(hctx); | 1089 | ccid3_calc_new_delta(hctx); |
1105 | (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; | 1090 | timeval_add_usecs(&hctx->ccid3hctx_t_nom, |
1106 | timeval_fix(&(hctx->ccid3hctx_t_nom)); | 1091 | hctx->ccid3hctx_t_ipi); |
1107 | } | 1092 | } |
1108 | break; | 1093 | break; |
1109 | default: | 1094 | default: |
@@ -1167,7 +1152,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1167 | } | 1152 | } |
1168 | 1153 | ||
1169 | /* Update RTT */ | 1154 | /* Update RTT */ |
1170 | r_sample = now_delta(packet->dccphtx_tstamp); | 1155 | r_sample = timeval_now_delta(&packet->dccphtx_tstamp); |
1171 | /* FIXME: */ | 1156 | /* FIXME: */ |
1172 | // r_sample -= usecs_to_jiffies(t_elapsed * 10); | 1157 | // r_sample -= usecs_to_jiffies(t_elapsed * 10); |
1173 | 1158 | ||
@@ -1224,15 +1209,11 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1224 | ccid3_hc_tx_update_x(sk); | 1209 | ccid3_hc_tx_update_x(sk); |
1225 | 1210 | ||
1226 | /* Update next send time */ | 1211 | /* Update next send time */ |
1227 | if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) { | 1212 | timeval_sub_usecs(&hctx->ccid3hctx_t_nom, |
1228 | hctx->ccid3hctx_t_nom.tv_usec += USEC_PER_SEC; | 1213 | hctx->ccid3hctx_t_ipi); |
1229 | (hctx->ccid3hctx_t_nom).tv_sec--; | ||
1230 | } | ||
1231 | /* FIXME - if no feedback then t_ipi can go > 1 second */ | ||
1232 | (hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi; | ||
1233 | ccid3_calc_new_t_ipi(hctx); | 1214 | ccid3_calc_new_t_ipi(hctx); |
1234 | (hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi; | 1215 | timeval_add_usecs(&hctx->ccid3hctx_t_nom, |
1235 | timeval_fix(&(hctx->ccid3hctx_t_nom)); | 1216 | hctx->ccid3hctx_t_ipi); |
1236 | ccid3_calc_new_delta(hctx); | 1217 | ccid3_calc_new_delta(hctx); |
1237 | 1218 | ||
1238 | /* remove all packets older than the one acked from history */ | 1219 | /* remove all packets older than the one acked from history */ |
@@ -1559,20 +1540,24 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk) | |||
1559 | struct dccp_sock *dp = dccp_sk(sk); | 1540 | struct dccp_sock *dp = dccp_sk(sk); |
1560 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; | 1541 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; |
1561 | struct dccp_rx_hist_entry *packet; | 1542 | struct dccp_rx_hist_entry *packet; |
1543 | struct timeval now; | ||
1562 | 1544 | ||
1563 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); | 1545 | ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); |
1564 | 1546 | ||
1547 | do_gettimeofday(&now); | ||
1548 | |||
1565 | switch (hcrx->ccid3hcrx_state) { | 1549 | switch (hcrx->ccid3hcrx_state) { |
1566 | case TFRC_RSTATE_NO_DATA: | 1550 | case TFRC_RSTATE_NO_DATA: |
1567 | hcrx->ccid3hcrx_x_recv = 0; | 1551 | hcrx->ccid3hcrx_x_recv = 0; |
1568 | break; | 1552 | break; |
1569 | case TFRC_RSTATE_DATA: { | 1553 | case TFRC_RSTATE_DATA: { |
1570 | u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback); | 1554 | const u32 delta = timeval_delta(&now, |
1555 | &hcrx->ccid3hcrx_tstamp_last_feedback); | ||
1571 | 1556 | ||
1572 | if (delta == 0) | ||
1573 | delta = 1; /* to prevent divide by zero */ | ||
1574 | hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv * | 1557 | hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv * |
1575 | USEC_PER_SEC) / delta; | 1558 | USEC_PER_SEC); |
1559 | if (likely(delta > 1)) | ||
1560 | hcrx->ccid3hcrx_x_recv /= delta; | ||
1576 | } | 1561 | } |
1577 | break; | 1562 | break; |
1578 | default: | 1563 | default: |
@@ -1590,13 +1575,14 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk) | |||
1590 | return; | 1575 | return; |
1591 | } | 1576 | } |
1592 | 1577 | ||
1593 | do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback)); | 1578 | hcrx->ccid3hcrx_tstamp_last_feedback = now; |
1594 | hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval; | 1579 | hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval; |
1595 | hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno; | 1580 | hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno; |
1596 | hcrx->ccid3hcrx_bytes_recv = 0; | 1581 | hcrx->ccid3hcrx_bytes_recv = 0; |
1597 | 1582 | ||
1598 | /* Convert to multiples of 10us */ | 1583 | /* Convert to multiples of 10us */ |
1599 | hcrx->ccid3hcrx_elapsed_time = now_delta(packet->dccphrx_tstamp) / 10; | 1584 | hcrx->ccid3hcrx_elapsed_time = |
1585 | timeval_delta(&now, &packet->dccphrx_tstamp) / 10; | ||
1600 | if (hcrx->ccid3hcrx_p == 0) | 1586 | if (hcrx->ccid3hcrx_p == 0) |
1601 | hcrx->ccid3hcrx_pinv = ~0; | 1587 | hcrx->ccid3hcrx_pinv = ~0; |
1602 | else | 1588 | else |
@@ -1676,7 +1662,7 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) | |||
1676 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; | 1662 | struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private; |
1677 | struct dccp_rx_hist_entry *entry, *next, *tail = NULL; | 1663 | struct dccp_rx_hist_entry *entry, *next, *tail = NULL; |
1678 | u32 rtt, delta, x_recv, fval, p, tmp2; | 1664 | u32 rtt, delta, x_recv, fval, p, tmp2; |
1679 | struct timeval tstamp = { 0 }, tmp_tv; | 1665 | struct timeval tstamp = { 0, }; |
1680 | int interval = 0; | 1666 | int interval = 0; |
1681 | int win_count = 0; | 1667 | int win_count = 0; |
1682 | int step = 0; | 1668 | int step = 0; |
@@ -1718,18 +1704,16 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk) | |||
1718 | interval = 1; | 1704 | interval = 1; |
1719 | } | 1705 | } |
1720 | found: | 1706 | found: |
1721 | timeval_sub(tstamp,tail->dccphrx_tstamp,&tmp_tv); | 1707 | rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval; |
1722 | rtt = (tmp_tv.tv_sec * USEC_PER_SEC + tmp_tv.tv_usec) * 4 / interval; | ||
1723 | ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", | 1708 | ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n", |
1724 | dccp_role(sk), sk, rtt); | 1709 | dccp_role(sk), sk, rtt); |
1725 | if (rtt == 0) | 1710 | if (rtt == 0) |
1726 | rtt = 1; | 1711 | rtt = 1; |
1727 | 1712 | ||
1728 | delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback); | 1713 | delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback); |
1729 | if (delta == 0) | 1714 | x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC; |
1730 | delta = 1; | 1715 | if (likely(delta > 1)) |
1731 | 1716 | x_recv /= delta; | |
1732 | x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC) / delta; | ||
1733 | 1717 | ||
1734 | tmp1 = (u64)x_recv * (u64)rtt; | 1718 | tmp1 = (u64)x_recv * (u64)rtt; |
1735 | do_div(tmp1,10000000); | 1719 | do_div(tmp1,10000000); |
@@ -1926,7 +1910,6 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1926 | const struct dccp_options_received *opt_recv; | 1910 | const struct dccp_options_received *opt_recv; |
1927 | struct dccp_rx_hist_entry *packet; | 1911 | struct dccp_rx_hist_entry *packet; |
1928 | struct timeval now; | 1912 | struct timeval now; |
1929 | u32 now_usecs; | ||
1930 | u8 win_count; | 1913 | u8 win_count; |
1931 | u32 p_prev; | 1914 | u32 p_prev; |
1932 | int ins; | 1915 | int ins; |
@@ -1948,8 +1931,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1948 | break; | 1931 | break; |
1949 | p_prev = hcrx->ccid3hcrx_rtt; | 1932 | p_prev = hcrx->ccid3hcrx_rtt; |
1950 | do_gettimeofday(&now); | 1933 | do_gettimeofday(&now); |
1951 | now_usecs = now.tv_sec * USEC_PER_SEC + now.tv_usec; | 1934 | hcrx->ccid3hcrx_rtt = timeval_usecs(&now) - |
1952 | hcrx->ccid3hcrx_rtt = now_usecs - | ||
1953 | (opt_recv->dccpor_timestamp_echo - | 1935 | (opt_recv->dccpor_timestamp_echo - |
1954 | opt_recv->dccpor_elapsed_time) * 10; | 1936 | opt_recv->dccpor_elapsed_time) * 10; |
1955 | if (p_prev != hcrx->ccid3hcrx_rtt) | 1937 | if (p_prev != hcrx->ccid3hcrx_rtt) |
@@ -1994,15 +1976,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1994 | case TFRC_RSTATE_DATA: | 1976 | case TFRC_RSTATE_DATA: |
1995 | hcrx->ccid3hcrx_bytes_recv += skb->len - | 1977 | hcrx->ccid3hcrx_bytes_recv += skb->len - |
1996 | dccp_hdr(skb)->dccph_doff * 4; | 1978 | dccp_hdr(skb)->dccph_doff * 4; |
1997 | if (ins == 0) { | 1979 | if (ins != 0) |
1998 | if (now_delta(hcrx->ccid3hcrx_tstamp_last_ack) >= | 1980 | break; |
1999 | hcrx->ccid3hcrx_rtt) { | 1981 | |
2000 | do_gettimeofday(&hcrx->ccid3hcrx_tstamp_last_ack); | 1982 | do_gettimeofday(&now); |
2001 | ccid3_hc_rx_send_feedback(sk); | 1983 | if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >= |
2002 | } | 1984 | hcrx->ccid3hcrx_rtt) { |
2003 | return; | 1985 | hcrx->ccid3hcrx_tstamp_last_ack = now; |
1986 | ccid3_hc_rx_send_feedback(sk); | ||
2004 | } | 1987 | } |
2005 | break; | 1988 | return; |
2006 | default: | 1989 | default: |
2007 | printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", | 1990 | printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", |
2008 | __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); | 1991 | __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state); |