Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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