.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* Management of Tx window, Tx resend, ACKs and out-of-sequence reception |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
47 | 43 | * propose an ACK be sent |
---|
48 | 44 | */ |
---|
49 | 45 | static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
---|
50 | | - u16 skew, u32 serial, bool immediate, |
---|
51 | | - bool background, |
---|
| 46 | + u32 serial, bool immediate, bool background, |
---|
52 | 47 | enum rxrpc_propose_ack_trace why) |
---|
53 | 48 | { |
---|
54 | 49 | enum rxrpc_propose_ack_outcome outcome = rxrpc_propose_ack_use; |
---|
.. | .. |
---|
73 | 68 | if (RXRPC_ACK_UPDATEABLE & (1 << ack_reason)) { |
---|
74 | 69 | outcome = rxrpc_propose_ack_update; |
---|
75 | 70 | call->ackr_serial = serial; |
---|
76 | | - call->ackr_skew = skew; |
---|
77 | 71 | } |
---|
78 | 72 | if (!immediate) |
---|
79 | 73 | goto trace; |
---|
80 | 74 | } else if (prior > rxrpc_ack_priority[call->ackr_reason]) { |
---|
81 | 75 | call->ackr_reason = ack_reason; |
---|
82 | 76 | call->ackr_serial = serial; |
---|
83 | | - call->ackr_skew = skew; |
---|
84 | 77 | } else { |
---|
85 | 78 | outcome = rxrpc_propose_ack_subsume; |
---|
86 | 79 | } |
---|
.. | .. |
---|
118 | 111 | } else { |
---|
119 | 112 | unsigned long now = jiffies, ack_at; |
---|
120 | 113 | |
---|
121 | | - if (call->peer->rtt_usage > 0) |
---|
122 | | - ack_at = nsecs_to_jiffies(call->peer->rtt); |
---|
| 114 | + if (call->peer->srtt_us != 0) |
---|
| 115 | + ack_at = usecs_to_jiffies(call->peer->srtt_us >> 3); |
---|
123 | 116 | else |
---|
124 | 117 | ack_at = expiry; |
---|
125 | 118 | |
---|
.. | .. |
---|
141 | 134 | * propose an ACK be sent, locking the call structure |
---|
142 | 135 | */ |
---|
143 | 136 | void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
---|
144 | | - u16 skew, u32 serial, bool immediate, bool background, |
---|
| 137 | + u32 serial, bool immediate, bool background, |
---|
145 | 138 | enum rxrpc_propose_ack_trace why) |
---|
146 | 139 | { |
---|
147 | 140 | spin_lock_bh(&call->lock); |
---|
148 | | - __rxrpc_propose_ACK(call, ack_reason, skew, serial, |
---|
| 141 | + __rxrpc_propose_ACK(call, ack_reason, serial, |
---|
149 | 142 | immediate, background, why); |
---|
150 | 143 | spin_unlock_bh(&call->lock); |
---|
151 | 144 | } |
---|
.. | .. |
---|
166 | 159 | struct sk_buff *skb; |
---|
167 | 160 | unsigned long resend_at; |
---|
168 | 161 | rxrpc_seq_t cursor, seq, top; |
---|
169 | | - ktime_t now, max_age, oldest, ack_ts, timeout, min_timeo; |
---|
| 162 | + ktime_t now, max_age, oldest, ack_ts; |
---|
170 | 163 | int ix; |
---|
171 | 164 | u8 annotation, anno_type, retrans = 0, unacked = 0; |
---|
172 | 165 | |
---|
173 | 166 | _enter("{%d,%d}", call->tx_hard_ack, call->tx_top); |
---|
174 | 167 | |
---|
175 | | - if (call->peer->rtt_usage > 1) |
---|
176 | | - timeout = ns_to_ktime(call->peer->rtt * 3 / 2); |
---|
177 | | - else |
---|
178 | | - timeout = ms_to_ktime(rxrpc_resend_timeout); |
---|
179 | | - min_timeo = ns_to_ktime((1000000000 / HZ) * 4); |
---|
180 | | - if (ktime_before(timeout, min_timeo)) |
---|
181 | | - timeout = min_timeo; |
---|
182 | | - |
---|
183 | 168 | now = ktime_get_real(); |
---|
184 | | - max_age = ktime_sub(now, timeout); |
---|
| 169 | + max_age = ktime_sub_us(now, jiffies_to_usecs(call->peer->rto_j)); |
---|
185 | 170 | |
---|
186 | 171 | spin_lock_bh(&call->lock); |
---|
187 | 172 | |
---|
.. | .. |
---|
206 | 191 | continue; |
---|
207 | 192 | |
---|
208 | 193 | skb = call->rxtx_buffer[ix]; |
---|
209 | | - rxrpc_see_skb(skb, rxrpc_skb_tx_seen); |
---|
| 194 | + rxrpc_see_skb(skb, rxrpc_skb_seen); |
---|
210 | 195 | |
---|
211 | 196 | if (anno_type == RXRPC_TX_ANNO_UNACK) { |
---|
212 | 197 | if (ktime_after(skb->tstamp, max_age)) { |
---|
.. | .. |
---|
226 | 211 | } |
---|
227 | 212 | |
---|
228 | 213 | resend_at = nsecs_to_jiffies(ktime_to_ns(ktime_sub(now, oldest))); |
---|
229 | | - resend_at += jiffies + rxrpc_resend_timeout; |
---|
| 214 | + resend_at += jiffies + rxrpc_get_rto_backoff(call->peer, retrans); |
---|
230 | 215 | WRITE_ONCE(call->resend_at, resend_at); |
---|
231 | 216 | |
---|
232 | 217 | if (unacked) |
---|
.. | .. |
---|
241 | 226 | rxrpc_timer_set_for_resend); |
---|
242 | 227 | spin_unlock_bh(&call->lock); |
---|
243 | 228 | ack_ts = ktime_sub(now, call->acks_latest_ts); |
---|
244 | | - if (ktime_to_ns(ack_ts) < call->peer->rtt) |
---|
| 229 | + if (ktime_to_us(ack_ts) < (call->peer->srtt_us >> 3)) |
---|
245 | 230 | goto out; |
---|
246 | | - rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, |
---|
| 231 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, |
---|
247 | 232 | rxrpc_propose_ack_ping_for_lost_ack); |
---|
248 | 233 | rxrpc_send_ack_packet(call, true, NULL); |
---|
249 | 234 | goto out; |
---|
.. | .. |
---|
261 | 246 | if (anno_type != RXRPC_TX_ANNO_RETRANS) |
---|
262 | 247 | continue; |
---|
263 | 248 | |
---|
| 249 | + /* We need to reset the retransmission state, but we need to do |
---|
| 250 | + * so before we drop the lock as a new ACK/NAK may come in and |
---|
| 251 | + * confuse things |
---|
| 252 | + */ |
---|
| 253 | + annotation &= ~RXRPC_TX_ANNO_MASK; |
---|
| 254 | + annotation |= RXRPC_TX_ANNO_UNACK | RXRPC_TX_ANNO_RESENT; |
---|
| 255 | + call->rxtx_annotations[ix] = annotation; |
---|
| 256 | + |
---|
264 | 257 | skb = call->rxtx_buffer[ix]; |
---|
265 | | - rxrpc_get_skb(skb, rxrpc_skb_tx_got); |
---|
| 258 | + if (!skb) |
---|
| 259 | + continue; |
---|
| 260 | + |
---|
| 261 | + rxrpc_get_skb(skb, rxrpc_skb_got); |
---|
266 | 262 | spin_unlock_bh(&call->lock); |
---|
267 | 263 | |
---|
268 | 264 | if (rxrpc_send_data_packet(call, skb, true) < 0) { |
---|
269 | | - rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
---|
| 265 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
---|
270 | 266 | return; |
---|
271 | 267 | } |
---|
272 | 268 | |
---|
273 | 269 | if (rxrpc_is_client_call(call)) |
---|
274 | 270 | rxrpc_expose_client_call(call); |
---|
275 | 271 | |
---|
276 | | - rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
---|
| 272 | + rxrpc_free_skb(skb, rxrpc_skb_freed); |
---|
277 | 273 | spin_lock_bh(&call->lock); |
---|
278 | | - |
---|
279 | | - /* We need to clear the retransmit state, but there are two |
---|
280 | | - * things we need to be aware of: A new ACK/NAK might have been |
---|
281 | | - * received and the packet might have been hard-ACK'd (in which |
---|
282 | | - * case it will no longer be in the buffer). |
---|
283 | | - */ |
---|
284 | | - if (after(seq, call->tx_hard_ack)) { |
---|
285 | | - annotation = call->rxtx_annotations[ix]; |
---|
286 | | - anno_type = annotation & RXRPC_TX_ANNO_MASK; |
---|
287 | | - if (anno_type == RXRPC_TX_ANNO_RETRANS || |
---|
288 | | - anno_type == RXRPC_TX_ANNO_NAK) { |
---|
289 | | - annotation &= ~RXRPC_TX_ANNO_MASK; |
---|
290 | | - annotation |= RXRPC_TX_ANNO_UNACK; |
---|
291 | | - } |
---|
292 | | - annotation |= RXRPC_TX_ANNO_RESENT; |
---|
293 | | - call->rxtx_annotations[ix] = annotation; |
---|
294 | | - } |
---|
295 | | - |
---|
296 | 274 | if (after(call->tx_hard_ack, seq)) |
---|
297 | 275 | seq = call->tx_hard_ack; |
---|
298 | 276 | } |
---|
.. | .. |
---|
332 | 310 | } |
---|
333 | 311 | |
---|
334 | 312 | if (call->state == RXRPC_CALL_COMPLETE) { |
---|
335 | | - del_timer_sync(&call->timer); |
---|
336 | | - rxrpc_notify_socket(call); |
---|
| 313 | + rxrpc_delete_call_timer(call); |
---|
337 | 314 | goto out_put; |
---|
338 | 315 | } |
---|
339 | 316 | |
---|
.. | .. |
---|
376 | 353 | if (time_after_eq(now, t)) { |
---|
377 | 354 | trace_rxrpc_timer(call, rxrpc_timer_exp_keepalive, now); |
---|
378 | 355 | cmpxchg(&call->keepalive_at, t, now + MAX_JIFFY_OFFSET); |
---|
379 | | - rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, true, |
---|
| 356 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, true, |
---|
380 | 357 | rxrpc_propose_ack_ping_for_keepalive); |
---|
381 | 358 | set_bit(RXRPC_CALL_EV_PING, &call->events); |
---|
382 | 359 | } |
---|
.. | .. |
---|
400 | 377 | if (test_bit(RXRPC_CALL_RX_HEARD, &call->flags) && |
---|
401 | 378 | (int)call->conn->hi_serial - (int)call->rx_serial > 0) { |
---|
402 | 379 | trace_rxrpc_call_reset(call); |
---|
403 | | - rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ECONNRESET); |
---|
| 380 | + rxrpc_abort_call("EXP", call, 0, RX_CALL_DEAD, -ECONNRESET); |
---|
404 | 381 | } else { |
---|
405 | | - rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME); |
---|
| 382 | + rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME); |
---|
406 | 383 | } |
---|
407 | 384 | set_bit(RXRPC_CALL_EV_ABORT, &call->events); |
---|
408 | 385 | goto recheck_state; |
---|
.. | .. |
---|
411 | 388 | send_ack = NULL; |
---|
412 | 389 | if (test_and_clear_bit(RXRPC_CALL_EV_ACK_LOST, &call->events)) { |
---|
413 | 390 | call->acks_lost_top = call->tx_top; |
---|
414 | | - rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, |
---|
| 391 | + rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, |
---|
415 | 392 | rxrpc_propose_ack_ping_for_lost_ack); |
---|
416 | 393 | send_ack = &call->acks_lost_ping; |
---|
417 | 394 | } |
---|
.. | .. |
---|
429 | 406 | goto recheck_state; |
---|
430 | 407 | } |
---|
431 | 408 | |
---|
432 | | - if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events)) { |
---|
| 409 | + if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events) && |
---|
| 410 | + call->state != RXRPC_CALL_CLIENT_RECV_REPLY) { |
---|
433 | 411 | rxrpc_resend(call, now); |
---|
434 | 412 | goto recheck_state; |
---|
435 | 413 | } |
---|