|
1 | 1 | /* |
2 | | - * Copyright (c) 2013-2016 Cisco Systems, Inc. All rights reserved. |
| 2 | + * Copyright (c) 2013-2017 Cisco Systems, Inc. All rights reserved. |
3 | 3 | * $COPYRIGHT$ |
4 | 4 | * |
5 | 5 | * Additional copyrights may follow |
|
26 | 26 | #include "btl_usnic_connectivity.h" |
27 | 27 |
|
28 | 28 | /* |
29 | | - * Force a retrans of a segment |
| 29 | + * Special case: we know exactly which segment is missing at the |
| 30 | + * receive; explicitly force retrans of that segment. |
30 | 31 | */ |
31 | 32 | static void |
32 | | -opal_btl_usnic_force_retrans( |
| 33 | +opal_btl_usnic_fast_retrans( |
33 | 34 | opal_btl_usnic_endpoint_t *endpoint, |
34 | 35 | opal_btl_usnic_seq_t ack_seq) |
35 | 36 | { |
36 | 37 | opal_btl_usnic_send_segment_t *sseg; |
37 | 38 | int is; |
38 | 39 |
|
39 | | - is = WINDOW_SIZE_MOD(ack_seq+1); |
| 40 | + is = WINDOW_SIZE_MOD(ack_seq + 1); |
40 | 41 | sseg = endpoint->endpoint_sent_segs[is]; |
| 42 | + |
| 43 | + // If the sseg is NULL, then there's nothing to retransmit. If |
| 44 | + // the hotel room is -1, the segment has already been queued up |
| 45 | + // for retransmit and there's nothing additional we need to do |
| 46 | + // here. |
41 | 47 | if (sseg == NULL || sseg->ss_hotel_room == -1) { |
42 | 48 | return; |
43 | 49 | } |
@@ -79,12 +85,14 @@ opal_btl_usnic_handle_ack( |
79 | 85 | #endif |
80 | 86 | ++module->stats.num_old_dup_acks; |
81 | 87 | return; |
| 88 | + } |
82 | 89 |
|
83 | | - /* A duplicate ACK means next seg was lost */ |
84 | | - } else if (ack_seq == endpoint->endpoint_ack_seq_rcvd) { |
| 90 | + /* A duplicate ACK means the sender did not receive the next |
| 91 | + seg that we sent */ |
| 92 | + else if (ack_seq == endpoint->endpoint_ack_seq_rcvd) { |
85 | 93 | ++module->stats.num_dup_acks; |
86 | 94 |
|
87 | | - opal_btl_usnic_force_retrans(endpoint, ack_seq); |
| 95 | + opal_btl_usnic_fast_retrans(endpoint, ack_seq); |
88 | 96 | return; |
89 | 97 | } |
90 | 98 |
|
@@ -114,12 +122,11 @@ opal_btl_usnic_handle_ack( |
114 | 122 | already been evicted and queued for resend. |
115 | 123 | If it's not in the hotel, don't check it out! */ |
116 | 124 | if (OPAL_LIKELY(sseg->ss_hotel_room != -1)) { |
117 | | - |
118 | 125 | opal_hotel_checkout(&endpoint->endpoint_hotel, sseg->ss_hotel_room); |
119 | 126 | sseg->ss_hotel_room = -1; |
120 | | - |
| 127 | + } |
121 | 128 | /* hotel_room == -1 means queued for resend, remove it */ |
122 | | - } else { |
| 129 | + else { |
123 | 130 | opal_list_remove_item((&module->pending_resend_segs), |
124 | 131 | &sseg->ss_base.us_list.super); |
125 | 132 | } |
@@ -191,19 +198,27 @@ opal_btl_usnic_handle_ack( |
191 | 198 | /* |
192 | 199 | * Send an ACK |
193 | 200 | */ |
194 | | -void |
| 201 | +int |
195 | 202 | opal_btl_usnic_ack_send( |
196 | 203 | opal_btl_usnic_module_t *module, |
197 | 204 | opal_btl_usnic_endpoint_t *endpoint) |
198 | 205 | { |
199 | 206 | opal_btl_usnic_ack_segment_t *ack; |
200 | 207 |
|
| 208 | + /* If we don't have any send credits in the priority channel, |
| 209 | + don't send it */ |
| 210 | + if (module->mod_channels[USNIC_PRIORITY_CHANNEL].credits < 1) { |
| 211 | + return OPAL_ERR_OUT_OF_RESOURCE; |
| 212 | + } |
| 213 | + |
201 | 214 | /* Get an ACK frag. If we don't get one, just discard this ACK. */ |
202 | 215 | ack = opal_btl_usnic_ack_segment_alloc(module); |
203 | 216 | if (OPAL_UNLIKELY(NULL == ack)) { |
204 | | - return; |
| 217 | + return OPAL_ERR_OUT_OF_RESOURCE; |
205 | 218 | } |
206 | 219 |
|
| 220 | + --module->mod_channels[USNIC_PRIORITY_CHANNEL].credits; |
| 221 | + |
207 | 222 | /* send the seq of the lowest item in the window that |
208 | 223 | we've received */ |
209 | 224 | ack->ss_base.us_btl_header->ack_seq = |
@@ -239,7 +254,7 @@ opal_btl_usnic_ack_send( |
239 | 254 | /* Stats */ |
240 | 255 | ++module->stats.num_ack_sends; |
241 | 256 |
|
242 | | - return; |
| 257 | + return OPAL_SUCCESS; |
243 | 258 | } |
244 | 259 |
|
245 | 260 | /* |
|
249 | 264 | opal_btl_usnic_ack_complete(opal_btl_usnic_module_t *module, |
250 | 265 | opal_btl_usnic_ack_segment_t *ack) |
251 | 266 | { |
| 267 | + ++module->mod_channels[USNIC_PRIORITY_CHANNEL].credits; |
252 | 268 | opal_btl_usnic_ack_segment_return(module, ack); |
253 | 269 | ++module->mod_channels[ack->ss_channel].credits; |
254 | 270 | } |
@@ -291,4 +307,3 @@ opal_btl_usnic_ack_timeout( |
291 | 307 | /* Stats */ |
292 | 308 | ++module->stats.num_timeout_retrans; |
293 | 309 | } |
294 | | - |
|
0 commit comments