diff options
Diffstat (limited to 'net/ipv4/tcp_dctcp.c')
-rw-r--r-- | net/ipv4/tcp_dctcp.c | 45 |
1 files changed, 17 insertions, 28 deletions
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c index 359da68d7c06..477cb4aa456c 100644 --- a/net/ipv4/tcp_dctcp.c +++ b/net/ipv4/tcp_dctcp.c | |||
@@ -49,9 +49,8 @@ | |||
49 | #define DCTCP_MAX_ALPHA 1024U | 49 | #define DCTCP_MAX_ALPHA 1024U |
50 | 50 | ||
51 | struct dctcp { | 51 | struct dctcp { |
52 | u32 acked_bytes_ecn; | 52 | u32 old_delivered; |
53 | u32 acked_bytes_total; | 53 | u32 old_delivered_ce; |
54 | u32 prior_snd_una; | ||
55 | u32 prior_rcv_nxt; | 54 | u32 prior_rcv_nxt; |
56 | u32 dctcp_alpha; | 55 | u32 dctcp_alpha; |
57 | u32 next_seq; | 56 | u32 next_seq; |
@@ -73,8 +72,8 @@ static void dctcp_reset(const struct tcp_sock *tp, struct dctcp *ca) | |||
73 | { | 72 | { |
74 | ca->next_seq = tp->snd_nxt; | 73 | ca->next_seq = tp->snd_nxt; |
75 | 74 | ||
76 | ca->acked_bytes_ecn = 0; | 75 | ca->old_delivered = tp->delivered; |
77 | ca->acked_bytes_total = 0; | 76 | ca->old_delivered_ce = tp->delivered_ce; |
78 | } | 77 | } |
79 | 78 | ||
80 | static void dctcp_init(struct sock *sk) | 79 | static void dctcp_init(struct sock *sk) |
@@ -86,7 +85,6 @@ static void dctcp_init(struct sock *sk) | |||
86 | sk->sk_state == TCP_CLOSE)) { | 85 | sk->sk_state == TCP_CLOSE)) { |
87 | struct dctcp *ca = inet_csk_ca(sk); | 86 | struct dctcp *ca = inet_csk_ca(sk); |
88 | 87 | ||
89 | ca->prior_snd_una = tp->snd_una; | ||
90 | ca->prior_rcv_nxt = tp->rcv_nxt; | 88 | ca->prior_rcv_nxt = tp->rcv_nxt; |
91 | 89 | ||
92 | ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA); | 90 | ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA); |
@@ -118,37 +116,25 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags) | |||
118 | { | 116 | { |
119 | const struct tcp_sock *tp = tcp_sk(sk); | 117 | const struct tcp_sock *tp = tcp_sk(sk); |
120 | struct dctcp *ca = inet_csk_ca(sk); | 118 | struct dctcp *ca = inet_csk_ca(sk); |
121 | u32 acked_bytes = tp->snd_una - ca->prior_snd_una; | ||
122 | |||
123 | /* If ack did not advance snd_una, count dupack as MSS size. | ||
124 | * If ack did update window, do not count it at all. | ||
125 | */ | ||
126 | if (acked_bytes == 0 && !(flags & CA_ACK_WIN_UPDATE)) | ||
127 | acked_bytes = inet_csk(sk)->icsk_ack.rcv_mss; | ||
128 | if (acked_bytes) { | ||
129 | ca->acked_bytes_total += acked_bytes; | ||
130 | ca->prior_snd_una = tp->snd_una; | ||
131 | |||
132 | if (flags & CA_ACK_ECE) | ||
133 | ca->acked_bytes_ecn += acked_bytes; | ||
134 | } | ||
135 | 119 | ||
136 | /* Expired RTT */ | 120 | /* Expired RTT */ |
137 | if (!before(tp->snd_una, ca->next_seq)) { | 121 | if (!before(tp->snd_una, ca->next_seq)) { |
138 | u64 bytes_ecn = ca->acked_bytes_ecn; | 122 | u32 delivered_ce = tp->delivered_ce - ca->old_delivered_ce; |
139 | u32 alpha = ca->dctcp_alpha; | 123 | u32 alpha = ca->dctcp_alpha; |
140 | 124 | ||
141 | /* alpha = (1 - g) * alpha + g * F */ | 125 | /* alpha = (1 - g) * alpha + g * F */ |
142 | 126 | ||
143 | alpha -= min_not_zero(alpha, alpha >> dctcp_shift_g); | 127 | alpha -= min_not_zero(alpha, alpha >> dctcp_shift_g); |
144 | if (bytes_ecn) { | 128 | if (delivered_ce) { |
129 | u32 delivered = tp->delivered - ca->old_delivered; | ||
130 | |||
145 | /* If dctcp_shift_g == 1, a 32bit value would overflow | 131 | /* If dctcp_shift_g == 1, a 32bit value would overflow |
146 | * after 8 Mbytes. | 132 | * after 8 M packets. |
147 | */ | 133 | */ |
148 | bytes_ecn <<= (10 - dctcp_shift_g); | 134 | delivered_ce <<= (10 - dctcp_shift_g); |
149 | do_div(bytes_ecn, max(1U, ca->acked_bytes_total)); | 135 | delivered_ce /= max(1U, delivered); |
150 | 136 | ||
151 | alpha = min(alpha + (u32)bytes_ecn, DCTCP_MAX_ALPHA); | 137 | alpha = min(alpha + delivered_ce, DCTCP_MAX_ALPHA); |
152 | } | 138 | } |
153 | /* dctcp_alpha can be read from dctcp_get_info() without | 139 | /* dctcp_alpha can be read from dctcp_get_info() without |
154 | * synchro, so we ask compiler to not use dctcp_alpha | 140 | * synchro, so we ask compiler to not use dctcp_alpha |
@@ -200,6 +186,7 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, | |||
200 | union tcp_cc_info *info) | 186 | union tcp_cc_info *info) |
201 | { | 187 | { |
202 | const struct dctcp *ca = inet_csk_ca(sk); | 188 | const struct dctcp *ca = inet_csk_ca(sk); |
189 | const struct tcp_sock *tp = tcp_sk(sk); | ||
203 | 190 | ||
204 | /* Fill it also in case of VEGASINFO due to req struct limits. | 191 | /* Fill it also in case of VEGASINFO due to req struct limits. |
205 | * We can still correctly retrieve it later. | 192 | * We can still correctly retrieve it later. |
@@ -211,8 +198,10 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, | |||
211 | info->dctcp.dctcp_enabled = 1; | 198 | info->dctcp.dctcp_enabled = 1; |
212 | info->dctcp.dctcp_ce_state = (u16) ca->ce_state; | 199 | info->dctcp.dctcp_ce_state = (u16) ca->ce_state; |
213 | info->dctcp.dctcp_alpha = ca->dctcp_alpha; | 200 | info->dctcp.dctcp_alpha = ca->dctcp_alpha; |
214 | info->dctcp.dctcp_ab_ecn = ca->acked_bytes_ecn; | 201 | info->dctcp.dctcp_ab_ecn = tp->mss_cache * |
215 | info->dctcp.dctcp_ab_tot = ca->acked_bytes_total; | 202 | (tp->delivered_ce - ca->old_delivered_ce); |
203 | info->dctcp.dctcp_ab_tot = tp->mss_cache * | ||
204 | (tp->delivered - ca->old_delivered); | ||
216 | } | 205 | } |
217 | 206 | ||
218 | *attr = INET_DIAG_DCTCPINFO; | 207 | *attr = INET_DIAG_DCTCPINFO; |