tcp_highspeed.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Sally Floyd's High Speed TCP (RFC 3649) congestion control
  3. *
  4. * See http://www.icir.org/floyd/hstcp.html
  5. *
  6. * John Heffner <jheffner@psc.edu>
  7. */
  8. #include <linux/module.h>
  9. #include <net/tcp.h>
  10. /* From AIMD tables from RFC 3649 appendix B,
  11. * with fixed-point MD scaled <<8.
  12. */
  13. static const struct hstcp_aimd_val {
  14. unsigned int cwnd;
  15. unsigned int md;
  16. } hstcp_aimd_vals[] = {
  17. { 38, 128, /* 0.50 */ },
  18. { 118, 112, /* 0.44 */ },
  19. { 221, 104, /* 0.41 */ },
  20. { 347, 98, /* 0.38 */ },
  21. { 495, 93, /* 0.37 */ },
  22. { 663, 89, /* 0.35 */ },
  23. { 851, 86, /* 0.34 */ },
  24. { 1058, 83, /* 0.33 */ },
  25. { 1284, 81, /* 0.32 */ },
  26. { 1529, 78, /* 0.31 */ },
  27. { 1793, 76, /* 0.30 */ },
  28. { 2076, 74, /* 0.29 */ },
  29. { 2378, 72, /* 0.28 */ },
  30. { 2699, 71, /* 0.28 */ },
  31. { 3039, 69, /* 0.27 */ },
  32. { 3399, 68, /* 0.27 */ },
  33. { 3778, 66, /* 0.26 */ },
  34. { 4177, 65, /* 0.26 */ },
  35. { 4596, 64, /* 0.25 */ },
  36. { 5036, 62, /* 0.25 */ },
  37. { 5497, 61, /* 0.24 */ },
  38. { 5979, 60, /* 0.24 */ },
  39. { 6483, 59, /* 0.23 */ },
  40. { 7009, 58, /* 0.23 */ },
  41. { 7558, 57, /* 0.22 */ },
  42. { 8130, 56, /* 0.22 */ },
  43. { 8726, 55, /* 0.22 */ },
  44. { 9346, 54, /* 0.21 */ },
  45. { 9991, 53, /* 0.21 */ },
  46. { 10661, 52, /* 0.21 */ },
  47. { 11358, 52, /* 0.20 */ },
  48. { 12082, 51, /* 0.20 */ },
  49. { 12834, 50, /* 0.20 */ },
  50. { 13614, 49, /* 0.19 */ },
  51. { 14424, 48, /* 0.19 */ },
  52. { 15265, 48, /* 0.19 */ },
  53. { 16137, 47, /* 0.19 */ },
  54. { 17042, 46, /* 0.18 */ },
  55. { 17981, 45, /* 0.18 */ },
  56. { 18955, 45, /* 0.18 */ },
  57. { 19965, 44, /* 0.17 */ },
  58. { 21013, 43, /* 0.17 */ },
  59. { 22101, 43, /* 0.17 */ },
  60. { 23230, 42, /* 0.17 */ },
  61. { 24402, 41, /* 0.16 */ },
  62. { 25618, 41, /* 0.16 */ },
  63. { 26881, 40, /* 0.16 */ },
  64. { 28193, 39, /* 0.16 */ },
  65. { 29557, 39, /* 0.15 */ },
  66. { 30975, 38, /* 0.15 */ },
  67. { 32450, 38, /* 0.15 */ },
  68. { 33986, 37, /* 0.15 */ },
  69. { 35586, 36, /* 0.14 */ },
  70. { 37253, 36, /* 0.14 */ },
  71. { 38992, 35, /* 0.14 */ },
  72. { 40808, 35, /* 0.14 */ },
  73. { 42707, 34, /* 0.13 */ },
  74. { 44694, 33, /* 0.13 */ },
  75. { 46776, 33, /* 0.13 */ },
  76. { 48961, 32, /* 0.13 */ },
  77. { 51258, 32, /* 0.13 */ },
  78. { 53677, 31, /* 0.12 */ },
  79. { 56230, 30, /* 0.12 */ },
  80. { 58932, 30, /* 0.12 */ },
  81. { 61799, 29, /* 0.12 */ },
  82. { 64851, 28, /* 0.11 */ },
  83. { 68113, 28, /* 0.11 */ },
  84. { 71617, 27, /* 0.11 */ },
  85. { 75401, 26, /* 0.10 */ },
  86. { 79517, 26, /* 0.10 */ },
  87. { 84035, 25, /* 0.10 */ },
  88. { 89053, 24, /* 0.10 */ },
  89. };
  90. #define HSTCP_AIMD_MAX ARRAY_SIZE(hstcp_aimd_vals)
  91. struct hstcp {
  92. u32 ai;
  93. };
  94. static void hstcp_init(struct sock *sk)
  95. {
  96. struct tcp_sock *tp = tcp_sk(sk);
  97. struct hstcp *ca = inet_csk_ca(sk);
  98. ca->ai = 0;
  99. /* Ensure the MD arithmetic works. This is somewhat pedantic,
  100. * since I don't think we will see a cwnd this large. :) */
  101. tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
  102. }
  103. static void hstcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
  104. {
  105. struct tcp_sock *tp = tcp_sk(sk);
  106. struct hstcp *ca = inet_csk_ca(sk);
  107. if (!tcp_is_cwnd_limited(sk))
  108. return;
  109. if (tcp_in_slow_start(tp))
  110. tcp_slow_start(tp, acked);
  111. else {
  112. /* Update AIMD parameters.
  113. *
  114. * We want to guarantee that:
  115. * hstcp_aimd_vals[ca->ai-1].cwnd <
  116. * snd_cwnd <=
  117. * hstcp_aimd_vals[ca->ai].cwnd
  118. */
  119. if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
  120. while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
  121. ca->ai < HSTCP_AIMD_MAX - 1)
  122. ca->ai++;
  123. } else if (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd) {
  124. while (ca->ai && tp->snd_cwnd <= hstcp_aimd_vals[ca->ai-1].cwnd)
  125. ca->ai--;
  126. }
  127. /* Do additive increase */
  128. if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
  129. /* cwnd = cwnd + a(w) / cwnd */
  130. tp->snd_cwnd_cnt += ca->ai + 1;
  131. if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
  132. tp->snd_cwnd_cnt -= tp->snd_cwnd;
  133. tp->snd_cwnd++;
  134. }
  135. }
  136. }
  137. }
  138. static u32 hstcp_ssthresh(struct sock *sk)
  139. {
  140. const struct tcp_sock *tp = tcp_sk(sk);
  141. const struct hstcp *ca = inet_csk_ca(sk);
  142. /* Do multiplicative decrease */
  143. return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U);
  144. }
  145. static struct tcp_congestion_ops tcp_highspeed __read_mostly = {
  146. .init = hstcp_init,
  147. .ssthresh = hstcp_ssthresh,
  148. .cong_avoid = hstcp_cong_avoid,
  149. .owner = THIS_MODULE,
  150. .name = "highspeed"
  151. };
  152. static int __init hstcp_register(void)
  153. {
  154. BUILD_BUG_ON(sizeof(struct hstcp) > ICSK_CA_PRIV_SIZE);
  155. return tcp_register_congestion_control(&tcp_highspeed);
  156. }
  157. static void __exit hstcp_unregister(void)
  158. {
  159. tcp_unregister_congestion_control(&tcp_highspeed);
  160. }
  161. module_init(hstcp_register);
  162. module_exit(hstcp_unregister);
  163. MODULE_AUTHOR("John Heffner");
  164. MODULE_LICENSE("GPL");
  165. MODULE_DESCRIPTION("High Speed TCP");