diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-08-27 19:11:28 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 19:12:03 -0400 |
commit | 6b5e633ab1525b4def3f36b53903b00586e9966d (patch) | |
tree | 3ba04b849920289a8ee6d6beae0fa72dc80b0e24 /net/dccp | |
parent | b6ee3d4ada4e85d9b9b9164c1327ef0850c79d5e (diff) |
[CCID3]: Introduce usecs_div
To avoid open coding this all over the place.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 109 |
1 files changed, 39 insertions, 70 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 60e3a5f9fcb4..ff41977f1edc 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -40,6 +40,15 @@ | |||
40 | #include "../packet_history.h" | 40 | #include "../packet_history.h" |
41 | #include "ccid3.h" | 41 | #include "ccid3.h" |
42 | 42 | ||
43 | /* | ||
44 | * Reason for maths with 10 here is to avoid 32 bit overflow when a is big. | ||
45 | */ | ||
46 | static inline u32 usecs_div(const u32 a, const u32 b) | ||
47 | { | ||
48 | const u32 tmp = a * (USEC_PER_SEC / 10); | ||
49 | return b > 20 ? tmp / (b / 10) : tmp; | ||
50 | } | ||
51 | |||
43 | #ifdef CCID3_DEBUG | 52 | #ifdef CCID3_DEBUG |
44 | extern int ccid3_debug; | 53 | extern int ccid3_debug; |
45 | 54 | ||
@@ -748,20 +757,13 @@ static u32 ccid3_calc_x(u16 s, u32 R, u32 p) | |||
748 | /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ | 757 | /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ |
749 | static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) | 758 | static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) |
750 | { | 759 | { |
751 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) | 760 | /* |
752 | return; | 761 | * If no feedback spec says t_ipi is 1 second (set elsewhere and then |
753 | /* if no feedback spec says t_ipi is 1 second (set elsewhere and then | 762 | * doubles after every no feedback timer (separate function) |
754 | * doubles after every no feedback timer (separate function) */ | 763 | */ |
755 | 764 | if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK) | |
756 | if (hctx->ccid3hctx_x < 10) { | 765 | hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s, |
757 | ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n"); | 766 | hctx->ccid3hctx_x); |
758 | hctx->ccid3hctx_x = 10; | ||
759 | } | ||
760 | hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000) | ||
761 | / (hctx->ccid3hctx_x / 10); | ||
762 | /* reason for above maths with 10 in there is to avoid 32 bit | ||
763 | * overflow for jumbo packets */ | ||
764 | |||
765 | } | 767 | } |
766 | 768 | ||
767 | /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ | 769 | /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ |
@@ -769,7 +771,6 @@ static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx) | |||
769 | { | 771 | { |
770 | hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, | 772 | hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, |
771 | TFRC_OPSYS_HALF_TIME_GRAN); | 773 | TFRC_OPSYS_HALF_TIME_GRAN); |
772 | |||
773 | } | 774 | } |
774 | 775 | ||
775 | /* | 776 | /* |
@@ -802,22 +803,13 @@ static void ccid3_hc_tx_update_x(struct sock *sk) | |||
802 | do_gettimeofday(&now); | 803 | do_gettimeofday(&now); |
803 | if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= | 804 | if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= |
804 | hctx->ccid3hctx_rtt) { | 805 | hctx->ccid3hctx_rtt) { |
805 | /* Avoid divide by zero below */ | 806 | hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, |
806 | const u32 rtt = max_t(u32, hctx->ccid3hctx_rtt, 10); | 807 | hctx->ccid3hctx_x) * 2, |
807 | 808 | usecs_div(hctx->ccid3hctx_s, | |
808 | hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, | 809 | hctx->ccid3hctx_rtt)); |
809 | 2 * hctx->ccid3hctx_x), | ||
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; | 810 | hctx->ccid3hctx_t_ld = now; |
814 | } | 811 | } |
815 | } | 812 | } |
816 | |||
817 | if (hctx->ccid3hctx_x == 0) { | ||
818 | ccid3_pr_debug("ccid3hctx_x = 0!\n"); | ||
819 | hctx->ccid3hctx_x = 1; | ||
820 | } | ||
821 | } | 813 | } |
822 | 814 | ||
823 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | 815 | static void ccid3_hc_tx_no_feedback_timer(unsigned long data) |
@@ -826,7 +818,6 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
826 | struct dccp_sock *dp = dccp_sk(sk); | 818 | struct dccp_sock *dp = dccp_sk(sk); |
827 | unsigned long next_tmout = 0; | 819 | unsigned long next_tmout = 0; |
828 | struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; | 820 | struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private; |
829 | u32 rtt; | ||
830 | 821 | ||
831 | bh_lock_sock(sk); | 822 | bh_lock_sock(sk); |
832 | if (sock_owned_by_user(sk)) { | 823 | if (sock_owned_by_user(sk)) { |
@@ -840,19 +831,14 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
840 | ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, | 831 | ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, |
841 | ccid3_tx_state_name(hctx->ccid3hctx_state)); | 832 | ccid3_tx_state_name(hctx->ccid3hctx_state)); |
842 | 833 | ||
843 | if (hctx->ccid3hctx_x < 10) { | ||
844 | ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n"); | ||
845 | hctx->ccid3hctx_x = 10; | ||
846 | } | ||
847 | |||
848 | switch (hctx->ccid3hctx_state) { | 834 | switch (hctx->ccid3hctx_state) { |
849 | case TFRC_SSTATE_TERM: | 835 | case TFRC_SSTATE_TERM: |
850 | goto out; | 836 | goto out; |
851 | case TFRC_SSTATE_NO_FBACK: | 837 | case TFRC_SSTATE_NO_FBACK: |
852 | /* Halve send rate */ | 838 | /* Halve send rate */ |
853 | hctx->ccid3hctx_x /= 2; | 839 | hctx->ccid3hctx_x /= 2; |
854 | if (hctx->ccid3hctx_x < | 840 | if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / |
855 | (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME)) | 841 | TFRC_MAX_BACK_OFF_TIME)) |
856 | hctx->ccid3hctx_x = (hctx->ccid3hctx_s / | 842 | hctx->ccid3hctx_x = (hctx->ccid3hctx_s / |
857 | TFRC_MAX_BACK_OFF_TIME); | 843 | TFRC_MAX_BACK_OFF_TIME); |
858 | 844 | ||
@@ -861,9 +847,9 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
861 | dccp_role(sk), sk, | 847 | dccp_role(sk), sk, |
862 | ccid3_tx_state_name(hctx->ccid3hctx_state), | 848 | ccid3_tx_state_name(hctx->ccid3hctx_state), |
863 | hctx->ccid3hctx_x); | 849 | hctx->ccid3hctx_x); |
864 | next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10), | 850 | next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s, |
851 | hctx->ccid3hctx_x), | ||
865 | TFRC_INITIAL_TIMEOUT); | 852 | TFRC_INITIAL_TIMEOUT); |
866 | /* do above maths with 100000 and 10 to prevent overflow on 32 bit */ | ||
867 | /* | 853 | /* |
868 | * FIXME - not sure above calculation is correct. See section | 854 | * FIXME - not sure above calculation is correct. See section |
869 | * 5 of CCID3 11 should adjust tx_t_ipi and double that to | 855 | * 5 of CCID3 11 should adjust tx_t_ipi and double that to |
@@ -875,12 +861,9 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
875 | * Check if IDLE since last timeout and recv rate is less than | 861 | * Check if IDLE since last timeout and recv rate is less than |
876 | * 4 packets per RTT | 862 | * 4 packets per RTT |
877 | */ | 863 | */ |
878 | rtt = hctx->ccid3hctx_rtt; | ||
879 | if (rtt < 10) | ||
880 | rtt = 10; | ||
881 | /* stop divide by zero below */ | ||
882 | if (!hctx->ccid3hctx_idle || | 864 | if (!hctx->ccid3hctx_idle || |
883 | (hctx->ccid3hctx_x_recv >= 4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) { | 865 | (hctx->ccid3hctx_x_recv >= |
866 | 4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) { | ||
884 | ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", | 867 | ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", |
885 | dccp_role(sk), sk, | 868 | dccp_role(sk), sk, |
886 | ccid3_tx_state_name(hctx->ccid3hctx_state)); | 869 | ccid3_tx_state_name(hctx->ccid3hctx_state)); |
@@ -905,13 +888,13 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) | |||
905 | /* Update sending rate */ | 888 | /* Update sending rate */ |
906 | ccid3_hc_tx_update_x(sk); | 889 | ccid3_hc_tx_update_x(sk); |
907 | } | 890 | } |
908 | if (hctx->ccid3hctx_x == 0) { | 891 | /* |
909 | ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n"); | 892 | * Schedule no feedback timer to expire in |
910 | hctx->ccid3hctx_x = 10; | 893 | * max(4 * R, 2 * s / X) |
911 | } | 894 | */ |
912 | /* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */ | ||
913 | next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, | 895 | next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, |
914 | 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10)); | 896 | 2 * usecs_div(hctx->ccid3hctx_s, |
897 | hctx->ccid3hctx_x)); | ||
915 | break; | 898 | break; |
916 | default: | 899 | default: |
917 | printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", | 900 | printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", |
@@ -1053,8 +1036,10 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) | |||
1053 | * Algorithm in "8.1. Window Counter Valuer" in | 1036 | * Algorithm in "8.1. Window Counter Valuer" in |
1054 | * draft-ietf-dccp-ccid3-11.txt | 1037 | * draft-ietf-dccp-ccid3-11.txt |
1055 | */ | 1038 | */ |
1056 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count) / | 1039 | quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); |
1057 | (hctx->ccid3hctx_rtt / 4); | 1040 | if (likely(hctx->ccid3hctx_rtt > 8)) |
1041 | quarter_rtt /= hctx->ccid3hctx_rtt / 4; | ||
1042 | |||
1058 | if (quarter_rtt > 0) { | 1043 | if (quarter_rtt > 0) { |
1059 | hctx->ccid3hctx_t_last_win_count = now; | 1044 | hctx->ccid3hctx_t_last_win_count = now; |
1060 | hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count + | 1045 | hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count + |
@@ -1171,13 +1156,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1171 | hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + | 1156 | hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + |
1172 | r_sample / 10; | 1157 | r_sample / 10; |
1173 | 1158 | ||
1174 | /* | ||
1175 | * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent | ||
1176 | * implemention of the new window count. | ||
1177 | */ | ||
1178 | if (hctx->ccid3hctx_rtt < 4) | ||
1179 | hctx->ccid3hctx_rtt = 4; | ||
1180 | |||
1181 | ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " | 1159 | ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " |
1182 | "r_sample=%us\n", dccp_role(sk), sk, | 1160 | "r_sample=%us\n", dccp_role(sk), sk, |
1183 | hctx->ccid3hctx_rtt, r_sample); | 1161 | hctx->ccid3hctx_rtt, r_sample); |
@@ -1220,21 +1198,14 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
1220 | dccp_tx_hist_purge_older(ccid3_tx_hist, | 1198 | dccp_tx_hist_purge_older(ccid3_tx_hist, |
1221 | &hctx->ccid3hctx_hist, packet); | 1199 | &hctx->ccid3hctx_hist, packet); |
1222 | 1200 | ||
1223 | if (hctx->ccid3hctx_x < 10) { | ||
1224 | ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx_x < 10\n"); | ||
1225 | hctx->ccid3hctx_x = 10; | ||
1226 | } | ||
1227 | /* to prevent divide by zero below */ | ||
1228 | |||
1229 | /* | 1201 | /* |
1230 | * Schedule no feedback timer to expire in | 1202 | * Schedule no feedback timer to expire in |
1231 | * max(4 * R, 2 * s / X) | 1203 | * max(4 * R, 2 * s / X) |
1232 | */ | 1204 | */ |
1233 | next_tmout = max(hctx->ccid3hctx_t_rto, | 1205 | next_tmout = max(hctx->ccid3hctx_t_rto, |
1234 | (2 * (hctx->ccid3hctx_s * 100000) / | 1206 | 2 * usecs_div(hctx->ccid3hctx_s, |
1235 | (hctx->ccid3hctx_x / 10))); | 1207 | hctx->ccid3hctx_x)); |
1236 | /* maths with 100000 and 10 is to prevent overflow with 32 bit */ | 1208 | |
1237 | |||
1238 | ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to " | 1209 | ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to " |
1239 | "expire in %lu jiffies (%luus)\n", | 1210 | "expire in %lu jiffies (%luus)\n", |
1240 | dccp_role(sk), sk, | 1211 | dccp_role(sk), sk, |
@@ -1350,8 +1321,6 @@ static int ccid3_hc_tx_init(struct sock *sk) | |||
1350 | 1321 | ||
1351 | /* Set transmission rate to 1 packet per second */ | 1322 | /* Set transmission rate to 1 packet per second */ |
1352 | hctx->ccid3hctx_x = hctx->ccid3hctx_s; | 1323 | hctx->ccid3hctx_x = hctx->ccid3hctx_s; |
1353 | /* See ccid3_hc_tx_packet_sent win_count calculatation */ | ||
1354 | hctx->ccid3hctx_rtt = 4; | ||
1355 | hctx->ccid3hctx_t_rto = USEC_PER_SEC; | 1324 | hctx->ccid3hctx_t_rto = USEC_PER_SEC; |
1356 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; | 1325 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; |
1357 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); | 1326 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); |