aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_dctcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_dctcp.c')
-rw-r--r--net/ipv4/tcp_dctcp.c45
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
51struct dctcp { 51struct 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
80static void dctcp_init(struct sock *sk) 79static 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;