Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142762941
D10894.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D10894.diff
View Options
Index: sys/netinet/cc/cc_cubic.c
===================================================================
--- sys/netinet/cc/cc_cubic.c
+++ sys/netinet/cc/cc_cubic.c
@@ -96,8 +96,58 @@
int epoch_ack_count;
/* Time of last congestion event in ticks. */
int t_last_cong;
+
+ /* Hybrid Slow Start values */
+
+ /* Minimum observed rtt in ms. */
+ int min_rtt_ms;
+ /* number of samples taken since start of packet train */
+ uint8_t sample_count;
+ /* an early exit condition for hybrid slow start has been found */
+ uint8_t exit_found;
+ /* start of hybrid slow start packet train */
+ uint32_t train_start;
+ /* value of snd_nxt at reset - used to determine ack value of next reset */
+ uint32_t end_seq;
+ /* millisecond granularity value of timestamp at the prior ack */
+ uint32_t last_ack;
+ /* the smallest measured RTT within the first HYSTART_MIN_SAMPLES (8) */
+ uint32_t curr_rtt;
+
+ /* assume hz == 1000 for first pass */
+ #define min_rtt_ms min_rtt_ticks
};
+#define USEC_PER_MSEC 1000
+
+#define HYSTART_ACK_TRAIN 0x1
+#define HYSTART_DELAY 0x2
+
+#define HYSTART_MIN_SAMPLES 8
+#define HYSTART_DELAY_MIN (4U<<3)
+#define HYSTART_DELAY_MAX (16U<<3)
+
+static inline int
+clamp(int x, int min, int max) {
+
+ if (x < min)
+ return min;
+ if (x > max)
+ return max;
+ return x;
+}
+
+#define HYSTART_DELAY_THRESH(x) clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX)
+
+
+SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, cubic, CTLFLAG_RW, NULL,
+ "cubic congestion control related settings");
+
+//static int hystart = 1;
+static int hystart_detect = HYSTART_ACK_TRAIN | HYSTART_DELAY;
+static int hystart_low_window = 16;
+static int hystart_ack_delta = 2;
+
static MALLOC_DEFINE(M_CUBIC, "cubic data",
"Per connection data required for the CUBIC congestion control algorithm");
@@ -201,11 +251,11 @@
static int
cubic_cb_init(struct cc_var *ccv)
{
- struct cubic *cubic_data;
-
- cubic_data = malloc(sizeof(struct cubic), M_CUBIC, M_NOWAIT|M_ZERO);
+ struct cubic *cubic_data = ccv->cc_data;
if (cubic_data == NULL)
+ cubic_data = malloc(sizeof(struct cubic), M_CUBIC, M_NOWAIT|M_ZERO);
+ if (cubic_data == NULL)
return (ENOMEM);
/* Init some key variables with sensible defaults. */
@@ -218,6 +268,67 @@
return (0);
}
+static inline uint32_t
+cubic_clock(void)
+{
+ if (hz == 1000)
+ return (ticks);
+
+ return (((ticks + hz) * 1000)/hz);
+}
+
+static void
+cubic_hystart_init(struct cc_var *ccv)
+{
+ struct cubic *cd;
+
+ cd = ccv->cc_data;
+ cd->train_start = cd->last_ack = cubic_clock();
+ cd->end_seq = CCV(ccv, snd_nxt);
+ cd->curr_rtt = 0;
+ cd->sample_count = cd->exit_found = 0;
+}
+
+static void
+cubic_hystart_update(struct cc_var *ccv, uint32_t delay)
+{
+ struct cubic *cd;
+ uint32_t now;
+
+ cd = ccv->cc_data;
+
+ if (cd->exit_found & hystart_detect)
+ return;
+
+ if (CCV(ccv, snd_cwnd) < hystart_low_window)
+ return;
+
+ if (hystart_detect & HYSTART_ACK_TRAIN) {
+ now = cubic_clock();
+ if ((int32_t)(now - cd->last_ack) <= hystart_ack_delta) {
+ cd->last_ack = now;
+ if ((int32_t)(now - cd->train_start) > cd->min_rtt_ms >> 4) {
+ cd->exit_found |= HYSTART_ACK_TRAIN;
+ CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd);
+
+ }
+ }
+ }
+
+ if (hystart_detect & HYSTART_DELAY) {
+ if (cd->sample_count < HYSTART_MIN_SAMPLES) {
+ if (cd->curr_rtt == 0 || cd->curr_rtt > delay)
+ cd->curr_rtt = delay;
+ cd->sample_count++;
+ } else {
+ if (cd->curr_rtt > cd->min_rtt_ms + HYSTART_DELAY_THRESH(cd->min_rtt_ms >> 3)) {
+ cd->exit_found |= HYSTART_DELAY;
+ CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd);
+ }
+ }
+ }
+}
+
/*
* Perform any necessary tasks before we enter congestion recovery.
*/
@@ -360,10 +471,20 @@
{
struct cubic *cubic_data;
int t_srtt_ticks;
+ int rtt_us, rtt_s3_ms;
+
+ cubic_data = ccv->cc_data;
+ if (ccv->sample_rtt_us >= 0) {
+ rtt_us = ccv->sample_rtt_us;
+ rtt_s3_ms = (rtt_us << 3)/USEC_PER_MSEC;
+ if (SEQ_GT(ccv->curack, cubic_data->end_seq))
+ cubic_hystart_init(ccv);
+
+ cubic_hystart_update(ccv, rtt_s3_ms);
+ }
/* Ignore srtt until a min number of samples have been taken. */
if (CCV(ccv, t_rttupdated) >= CUBIC_MIN_RTT_SAMPLES) {
- cubic_data = ccv->cc_data;
t_srtt_ticks = CCV(ccv, t_srtt) / TCP_RTT_SCALE;
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 24, 7:28 AM (5 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27891559
Default Alt Text
D10894.diff (4 KB)
Attached To
Mode
D10894: First cut implementation of hybrid slow start
Attached
Detach File
Event Timeline
Log In to Comment