Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 : /* QUIC kernel implementation 3 : * (C) Copyright Red Hat Corp. 2023 4 : * 5 : * This file is part of the QUIC kernel implementation 6 : * 7 : * Written or modified by: 8 : * Xin Long <lucien.xin@gmail.com> 9 : */ 10 : 11 : #define QUIC_KPERSISTENT_CONGESTION_THRESHOLD 3 12 : #define QUIC_KPACKET_THRESHOLD 3 13 : #define QUIC_KTIME_THRESHOLD(rtt) ((rtt) * 9 / 8) 14 : #define QUIC_KGRANULARITY 1000U 15 : 16 : #define QUIC_RTT_INIT 333000U 17 : #define QUIC_RTT_MAX 2000000U 18 : #define QUIC_RTT_MIN QUIC_KGRANULARITY 19 : 20 : /* rfc9002#section-7.3: Congestion Control States 21 : * 22 : * New path or +------------+ 23 : * persistent congestion | Slow | 24 : * (O)---------------------->| Start | 25 : * +------------+ 26 : * | 27 : * Loss or | 28 : * ECN-CE increase | 29 : * v 30 : * +------------+ Loss or +------------+ 31 : * | Congestion | ECN-CE increase | Recovery | 32 : * | Avoidance |------------------>| Period | 33 : * +------------+ +------------+ 34 : * ^ | 35 : * | | 36 : * +----------------------------+ 37 : * Acknowledgment of packet 38 : * sent during recovery 39 : */ 40 : enum quic_cong_state { 41 : QUIC_CONG_SLOW_START, 42 : QUIC_CONG_RECOVERY_PERIOD, 43 : QUIC_CONG_CONGESTION_AVOIDANCE, 44 : }; 45 : 46 : struct quic_cong { 47 : /* RTT tracking */ 48 : u32 smoothed_rtt; /* Smoothed RTT */ 49 : u32 latest_rtt; /* Latest RTT sample */ 50 : u32 min_rtt; /* Lowest observed RTT */ 51 : u32 rttvar; /* RTT variation */ 52 : u32 loss_delay; /* Time before marking loss */ 53 : u32 pto; /* Probe timeout */ 54 : 55 : /* Timing & pacing */ 56 : u32 max_ack_delay; /* max_ack_delay from rfc9000#section-18.2 */ 57 : u32 recovery_time; /* Recovery period start */ 58 : u32 pacing_rate; /* Packet sending speed Bytes/sec */ 59 : u64 pacing_time; /* Next send time */ 60 : u32 time; /* Cached time */ 61 : 62 : /* Congestion window */ 63 : u32 max_window; /* Max growth cap */ 64 : u32 min_window; /* Min window limit */ 65 : u32 ssthresh; /* Slow start threshold */ 66 : u32 window; /* Bytes in flight allowed */ 67 : u32 mss; /* QUIC MSS (excl. UDP) */ 68 : 69 : /* Algorithm-specific */ 70 : struct quic_cong_ops *ops; 71 : u64 priv[8]; /* Algo private data */ 72 : 73 : /* Flags & state */ 74 : u8 min_rtt_valid; /* min_rtt initialized */ 75 : u8 is_rtt_set; /* RTT samples exist */ 76 : u8 state; /* State machine in rfc9002#section-7.3 */ 77 : }; 78 : 79 : /* Hooks for congestion control algorithms */ 80 : struct quic_cong_ops { 81 : void (*on_packet_acked)(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 82 : void (*on_packet_lost)(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 83 : void (*on_process_ecn)(struct quic_cong *cong); 84 : void (*on_init)(struct quic_cong *cong); 85 : 86 : /* Optional callbacks */ 87 : void (*on_packet_sent)(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 88 : void (*on_ack_recv)(struct quic_cong *cong, u32 bytes, u32 max_rate); 89 : void (*on_rtt_update)(struct quic_cong *cong); 90 : }; 91 : 92 2916 : static inline void quic_cong_set_mss(struct quic_cong *cong, u32 mss) 93 : { 94 2916 : if (cong->mss == mss) 95 : return; 96 : 97 : /* rfc9002#section-7.2: Initial and Minimum Congestion Window */ 98 1107 : cong->mss = mss; 99 1107 : cong->min_window = max(min(mss * 10, 14720U), mss * 2); 100 : 101 1107 : if (cong->window < cong->min_window) 102 1003 : cong->window = cong->min_window; 103 : } 104 : 105 : static inline void *quic_cong_priv(struct quic_cong *cong) 106 : { 107 9440298 : return (void *)cong->priv; 108 : } 109 : 110 : void quic_cong_on_packet_acked(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 111 : void quic_cong_on_packet_lost(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 112 : void quic_cong_on_process_ecn(struct quic_cong *cong); 113 : 114 : void quic_cong_on_packet_sent(struct quic_cong *cong, u32 time, u32 bytes, s64 number); 115 : void quic_cong_on_ack_recv(struct quic_cong *cong, u32 bytes, u32 max_rate); 116 : void quic_cong_rtt_update(struct quic_cong *cong, u32 time, u32 ack_delay); 117 : 118 : void quic_cong_set_srtt(struct quic_cong *cong, u32 srtt); 119 : void quic_cong_set_algo(struct quic_cong *cong, u8 algo); 120 : void quic_cong_init(struct quic_cong *cong);