Commit | Line | Data |
---|---|---|
17926a79 DH |
1 | /* Management of Tx window, Tx resend, ACKs and out-of-sequence reception |
2 | * | |
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | |
4 | * 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 | */ | |
11 | ||
9b6d5398 JP |
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
13 | ||
17926a79 DH |
14 | #include <linux/module.h> |
15 | #include <linux/circ_buf.h> | |
16 | #include <linux/net.h> | |
17 | #include <linux/skbuff.h> | |
5a0e3ad6 | 18 | #include <linux/slab.h> |
17926a79 DH |
19 | #include <linux/udp.h> |
20 | #include <net/sock.h> | |
21 | #include <net/af_rxrpc.h> | |
22 | #include "ar-internal.h" | |
23 | ||
17926a79 | 24 | /* |
248f219c | 25 | * Set the timer |
17926a79 | 26 | */ |
248f219c | 27 | static void rxrpc_set_timer(struct rxrpc_call *call) |
17926a79 | 28 | { |
248f219c | 29 | unsigned long t, now = jiffies; |
17926a79 | 30 | |
248f219c DH |
31 | _enter("{%ld,%ld,%ld:%ld}", |
32 | call->ack_at - now, call->resend_at - now, call->expire_at - now, | |
33 | call->timer.expires - now); | |
34 | ||
35 | read_lock_bh(&call->state_lock); | |
17926a79 | 36 | |
248f219c DH |
37 | if (call->state < RXRPC_CALL_COMPLETE) { |
38 | t = call->ack_at; | |
39 | if (time_before(call->resend_at, t)) | |
40 | t = call->resend_at; | |
41 | if (time_before(call->expire_at, t)) | |
42 | t = call->expire_at; | |
43 | if (!timer_pending(&call->timer) || | |
44 | time_before(t, call->timer.expires)) { | |
45 | _debug("set timer %ld", t - now); | |
46 | mod_timer(&call->timer, t); | |
17926a79 | 47 | } |
17926a79 | 48 | } |
17926a79 DH |
49 | read_unlock_bh(&call->state_lock); |
50 | } | |
51 | ||
52 | /* | |
248f219c | 53 | * propose an ACK be sent |
17926a79 | 54 | */ |
248f219c DH |
55 | static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
56 | u16 skew, u32 serial, bool immediate, | |
57 | bool background) | |
17926a79 | 58 | { |
248f219c | 59 | unsigned long now, ack_at, expiry = rxrpc_soft_ack_delay; |
17926a79 DH |
60 | s8 prior = rxrpc_ack_priority[ack_reason]; |
61 | ||
248f219c DH |
62 | _enter("{%d},%s,%%%x,%u", |
63 | call->debug_id, rxrpc_acks(ack_reason), serial, immediate); | |
17926a79 | 64 | |
248f219c DH |
65 | /* Update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial |
66 | * numbers, but we don't alter the timeout. | |
67 | */ | |
68 | _debug("prior %u %u vs %u %u", | |
69 | ack_reason, prior, | |
70 | call->ackr_reason, rxrpc_ack_priority[call->ackr_reason]); | |
71 | if (ack_reason == call->ackr_reason) { | |
72 | if (RXRPC_ACK_UPDATEABLE & (1 << ack_reason)) { | |
73 | call->ackr_serial = serial; | |
74 | call->ackr_skew = skew; | |
17926a79 | 75 | } |
248f219c DH |
76 | if (!immediate) |
77 | return; | |
78 | } else if (prior > rxrpc_ack_priority[call->ackr_reason]) { | |
79 | call->ackr_reason = ack_reason; | |
80 | call->ackr_serial = serial; | |
81 | call->ackr_skew = skew; | |
17926a79 DH |
82 | } |
83 | ||
248f219c DH |
84 | switch (ack_reason) { |
85 | case RXRPC_ACK_REQUESTED: | |
86 | if (rxrpc_requested_ack_delay < expiry) | |
87 | expiry = rxrpc_requested_ack_delay; | |
88 | if (serial == 1) | |
89 | immediate = false; | |
90 | break; | |
17926a79 | 91 | |
248f219c DH |
92 | case RXRPC_ACK_DELAY: |
93 | if (rxrpc_soft_ack_delay < expiry) | |
94 | expiry = rxrpc_soft_ack_delay; | |
95 | break; | |
17926a79 | 96 | |
248f219c DH |
97 | case RXRPC_ACK_IDLE: |
98 | if (rxrpc_soft_ack_delay < expiry) | |
99 | expiry = rxrpc_idle_ack_delay; | |
100 | break; | |
17926a79 | 101 | |
248f219c DH |
102 | default: |
103 | immediate = true; | |
104 | break; | |
17926a79 DH |
105 | } |
106 | ||
248f219c DH |
107 | now = jiffies; |
108 | if (test_bit(RXRPC_CALL_EV_ACK, &call->events)) { | |
109 | _debug("already scheduled"); | |
110 | } else if (immediate || expiry == 0) { | |
111 | _debug("immediate ACK %lx", call->events); | |
112 | if (!test_and_set_bit(RXRPC_CALL_EV_ACK, &call->events) && | |
113 | background) | |
114 | rxrpc_queue_call(call); | |
115 | } else { | |
116 | ack_at = now + expiry; | |
117 | _debug("deferred ACK %ld < %ld", expiry, call->ack_at - now); | |
118 | if (time_before(ack_at, call->ack_at)) { | |
119 | call->ack_at = ack_at; | |
120 | rxrpc_set_timer(call); | |
17926a79 DH |
121 | } |
122 | } | |
17926a79 DH |
123 | } |
124 | ||
125 | /* | |
248f219c | 126 | * propose an ACK be sent, locking the call structure |
17926a79 | 127 | */ |
248f219c DH |
128 | void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
129 | u16 skew, u32 serial, bool immediate, bool background) | |
17926a79 | 130 | { |
248f219c DH |
131 | spin_lock_bh(&call->lock); |
132 | __rxrpc_propose_ACK(call, ack_reason, skew, serial, | |
133 | immediate, background); | |
134 | spin_unlock_bh(&call->lock); | |
17926a79 DH |
135 | } |
136 | ||
137 | /* | |
248f219c | 138 | * Perform retransmission of NAK'd and unack'd packets. |
17926a79 | 139 | */ |
248f219c | 140 | static void rxrpc_resend(struct rxrpc_call *call) |
17926a79 | 141 | { |
248f219c | 142 | struct rxrpc_wire_header *whdr; |
17926a79 DH |
143 | struct rxrpc_skb_priv *sp; |
144 | struct sk_buff *skb; | |
248f219c DH |
145 | rxrpc_seq_t cursor, seq, top; |
146 | unsigned long resend_at, now; | |
147 | int ix; | |
148 | u8 annotation; | |
17926a79 | 149 | |
248f219c | 150 | _enter("{%d,%d}", call->tx_hard_ack, call->tx_top); |
17926a79 DH |
151 | |
152 | spin_lock_bh(&call->lock); | |
153 | ||
248f219c DH |
154 | cursor = call->tx_hard_ack; |
155 | top = call->tx_top; | |
156 | ASSERT(before_eq(cursor, top)); | |
157 | if (cursor == top) | |
158 | goto out_unlock; | |
159 | ||
160 | /* Scan the packet list without dropping the lock and decide which of | |
161 | * the packets in the Tx buffer we're going to resend and what the new | |
162 | * resend timeout will be. | |
163 | */ | |
164 | now = jiffies; | |
165 | resend_at = now + rxrpc_resend_timeout; | |
166 | seq = cursor + 1; | |
167 | do { | |
168 | ix = seq & RXRPC_RXTX_BUFF_MASK; | |
169 | annotation = call->rxtx_annotations[ix]; | |
170 | if (annotation == RXRPC_TX_ANNO_ACK) | |
171 | continue; | |
17926a79 | 172 | |
248f219c | 173 | skb = call->rxtx_buffer[ix]; |
df844fd4 | 174 | rxrpc_see_skb(skb); |
17926a79 DH |
175 | sp = rxrpc_skb(skb); |
176 | ||
248f219c DH |
177 | if (annotation == RXRPC_TX_ANNO_UNACK) { |
178 | if (time_after(sp->resend_at, now)) { | |
179 | if (time_before(sp->resend_at, resend_at)) | |
180 | resend_at = sp->resend_at; | |
181 | continue; | |
33c40e24 | 182 | } |
17926a79 | 183 | } |
17926a79 | 184 | |
248f219c DH |
185 | /* Okay, we need to retransmit a packet. */ |
186 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_RETRANS; | |
187 | seq++; | |
188 | } while (before_eq(seq, top)); | |
189 | ||
190 | call->resend_at = resend_at; | |
191 | ||
192 | /* Now go through the Tx window and perform the retransmissions. We | |
193 | * have to drop the lock for each send. If an ACK comes in whilst the | |
194 | * lock is dropped, it may clear some of the retransmission markers for | |
195 | * packets that it soft-ACKs. | |
196 | */ | |
197 | seq = cursor + 1; | |
198 | do { | |
199 | ix = seq & RXRPC_RXTX_BUFF_MASK; | |
200 | annotation = call->rxtx_annotations[ix]; | |
201 | if (annotation != RXRPC_TX_ANNO_RETRANS) | |
202 | continue; | |
17926a79 | 203 | |
248f219c DH |
204 | skb = call->rxtx_buffer[ix]; |
205 | rxrpc_get_skb(skb); | |
17926a79 | 206 | spin_unlock_bh(&call->lock); |
248f219c | 207 | sp = rxrpc_skb(skb); |
17926a79 | 208 | |
248f219c DH |
209 | /* Each Tx packet needs a new serial number */ |
210 | sp->hdr.serial = atomic_inc_return(&call->conn->serial); | |
17926a79 | 211 | |
248f219c DH |
212 | whdr = (struct rxrpc_wire_header *)skb->head; |
213 | whdr->serial = htonl(sp->hdr.serial); | |
17926a79 | 214 | |
248f219c DH |
215 | if (rxrpc_send_data_packet(call->conn, skb) < 0) { |
216 | call->resend_at = now + 2; | |
217 | rxrpc_free_skb(skb); | |
218 | return; | |
219 | } | |
17926a79 | 220 | |
248f219c DH |
221 | if (rxrpc_is_client_call(call)) |
222 | rxrpc_expose_client_call(call); | |
223 | sp->resend_at = now + rxrpc_resend_timeout; | |
17926a79 | 224 | |
248f219c | 225 | rxrpc_free_skb(skb); |
17926a79 | 226 | spin_lock_bh(&call->lock); |
17926a79 | 227 | |
248f219c DH |
228 | /* We need to clear the retransmit state, but there are two |
229 | * things we need to be aware of: A new ACK/NAK might have been | |
230 | * received and the packet might have been hard-ACK'd (in which | |
231 | * case it will no longer be in the buffer). | |
232 | */ | |
233 | if (after(seq, call->tx_hard_ack) && | |
234 | (call->rxtx_annotations[ix] == RXRPC_TX_ANNO_RETRANS || | |
235 | call->rxtx_annotations[ix] == RXRPC_TX_ANNO_NAK)) | |
236 | call->rxtx_annotations[ix] = RXRPC_TX_ANNO_UNACK; | |
237 | ||
238 | if (after(call->tx_hard_ack, seq)) | |
239 | seq = call->tx_hard_ack; | |
240 | seq++; | |
241 | } while (before_eq(seq, top)); | |
242 | ||
243 | out_unlock: | |
244 | spin_unlock_bh(&call->lock); | |
245 | _leave(""); | |
17926a79 DH |
246 | } |
247 | ||
248 | /* | |
248f219c | 249 | * Handle retransmission and deferred ACK/abort generation. |
17926a79 DH |
250 | */ |
251 | void rxrpc_process_call(struct work_struct *work) | |
252 | { | |
253 | struct rxrpc_call *call = | |
254 | container_of(work, struct rxrpc_call, processor); | |
248f219c | 255 | unsigned long now; |
17926a79 | 256 | |
e34d4234 DH |
257 | rxrpc_see_call(call); |
258 | ||
17926a79 | 259 | //printk("\n--------------------\n"); |
248f219c DH |
260 | _enter("{%d,%s,%lx}", |
261 | call->debug_id, rxrpc_call_states[call->state], call->events); | |
17926a79 | 262 | |
248f219c DH |
263 | recheck_state: |
264 | if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) { | |
265 | rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ABORT); | |
266 | goto recheck_state; | |
17926a79 DH |
267 | } |
268 | ||
248f219c DH |
269 | if (call->state == RXRPC_CALL_COMPLETE) { |
270 | del_timer_sync(&call->timer); | |
271 | goto out_put; | |
17926a79 DH |
272 | } |
273 | ||
248f219c DH |
274 | now = jiffies; |
275 | if (time_after_eq(now, call->expire_at)) { | |
5a42976d | 276 | rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, ETIME); |
248f219c | 277 | set_bit(RXRPC_CALL_EV_ABORT, &call->events); |
17926a79 DH |
278 | } |
279 | ||
248f219c DH |
280 | if (test_and_clear_bit(RXRPC_CALL_EV_ACK, &call->events) || |
281 | time_after_eq(now, call->ack_at)) { | |
282 | call->ack_at = call->expire_at; | |
283 | if (call->ackr_reason) { | |
284 | rxrpc_send_call_packet(call, RXRPC_PACKET_TYPE_ACK); | |
285 | goto recheck_state; | |
17926a79 DH |
286 | } |
287 | } | |
288 | ||
248f219c DH |
289 | if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events) || |
290 | time_after_eq(now, call->resend_at)) { | |
17926a79 | 291 | rxrpc_resend(call); |
248f219c | 292 | goto recheck_state; |
17926a79 DH |
293 | } |
294 | ||
248f219c | 295 | rxrpc_set_timer(call); |
17926a79 DH |
296 | |
297 | /* other events may have been raised since we started checking */ | |
248f219c | 298 | if (call->events && call->state < RXRPC_CALL_COMPLETE) { |
8d94aa38 | 299 | __rxrpc_queue_call(call); |
248f219c | 300 | goto out; |
17926a79 DH |
301 | } |
302 | ||
248f219c DH |
303 | out_put: |
304 | rxrpc_put_call(call, rxrpc_call_put); | |
305 | out: | |
17926a79 | 306 | _leave(""); |
17926a79 | 307 | } |