diff options
author | David Howells <dhowells@redhat.com> | 2016-10-06 03:11:49 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-10-06 03:11:49 -0400 |
commit | a5af7e1fc69a46f29b977fd4b570e0ac414c2338 (patch) | |
tree | d3ecc4df97f90a40d3f3aa6827bfe4201eba71e7 /net/rxrpc | |
parent | 26cb02aa6d3efeb543805ed9ad599dae24f7c6d4 (diff) |
rxrpc: Fix loss of PING RESPONSE ACK production due to PING ACKs
Separate the output of PING ACKs from the output of other sorts of ACK so
that if we receive a PING ACK and schedule transmission of a PING RESPONSE
ACK, the response doesn't get cancelled by a PING ACK we happen to be
scheduling transmission of at the same time.
If a PING RESPONSE gets lost, the other side might just sit there waiting
for it and refuse to proceed otherwise.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc')
-rw-r--r-- | net/rxrpc/ar-internal.h | 12 | ||||
-rw-r--r-- | net/rxrpc/call_event.c | 48 | ||||
-rw-r--r-- | net/rxrpc/call_object.c | 1 | ||||
-rw-r--r-- | net/rxrpc/input.c | 4 | ||||
-rw-r--r-- | net/rxrpc/misc.c | 2 | ||||
-rw-r--r-- | net/rxrpc/output.c | 38 | ||||
-rw-r--r-- | net/rxrpc/recvmsg.c | 4 | ||||
-rw-r--r-- | net/rxrpc/sendmsg.c | 2 |
8 files changed, 82 insertions, 29 deletions
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index ef849a12a0f0..b56676be07c7 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
@@ -398,6 +398,7 @@ enum rxrpc_call_flag { | |||
398 | RXRPC_CALL_EXPOSED, /* The call was exposed to the world */ | 398 | RXRPC_CALL_EXPOSED, /* The call was exposed to the world */ |
399 | RXRPC_CALL_RX_LAST, /* Received the last packet (at rxtx_top) */ | 399 | RXRPC_CALL_RX_LAST, /* Received the last packet (at rxtx_top) */ |
400 | RXRPC_CALL_TX_LAST, /* Last packet in Tx buffer (at rxtx_top) */ | 400 | RXRPC_CALL_TX_LAST, /* Last packet in Tx buffer (at rxtx_top) */ |
401 | RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ | ||
401 | RXRPC_CALL_PINGING, /* Ping in process */ | 402 | RXRPC_CALL_PINGING, /* Ping in process */ |
402 | RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ | 403 | RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ |
403 | }; | 404 | }; |
@@ -410,6 +411,7 @@ enum rxrpc_call_event { | |||
410 | RXRPC_CALL_EV_ABORT, /* need to generate abort */ | 411 | RXRPC_CALL_EV_ABORT, /* need to generate abort */ |
411 | RXRPC_CALL_EV_TIMER, /* Timer expired */ | 412 | RXRPC_CALL_EV_TIMER, /* Timer expired */ |
412 | RXRPC_CALL_EV_RESEND, /* Tx resend required */ | 413 | RXRPC_CALL_EV_RESEND, /* Tx resend required */ |
414 | RXRPC_CALL_EV_PING, /* Ping send required */ | ||
413 | }; | 415 | }; |
414 | 416 | ||
415 | /* | 417 | /* |
@@ -466,6 +468,7 @@ struct rxrpc_call { | |||
466 | struct rxrpc_sock __rcu *socket; /* socket responsible */ | 468 | struct rxrpc_sock __rcu *socket; /* socket responsible */ |
467 | ktime_t ack_at; /* When deferred ACK needs to happen */ | 469 | ktime_t ack_at; /* When deferred ACK needs to happen */ |
468 | ktime_t resend_at; /* When next resend needs to happen */ | 470 | ktime_t resend_at; /* When next resend needs to happen */ |
471 | ktime_t ping_at; /* When next to send a ping */ | ||
469 | ktime_t expire_at; /* When the call times out */ | 472 | ktime_t expire_at; /* When the call times out */ |
470 | struct timer_list timer; /* Combined event timer */ | 473 | struct timer_list timer; /* Combined event timer */ |
471 | struct work_struct processor; /* Event processor */ | 474 | struct work_struct processor; /* Event processor */ |
@@ -558,8 +561,10 @@ struct rxrpc_call { | |||
558 | rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ | 561 | rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ |
559 | rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ | 562 | rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ |
560 | rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ | 563 | rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ |
561 | rxrpc_serial_t ackr_ping; /* Last ping sent */ | 564 | |
562 | ktime_t ackr_ping_time; /* Time last ping sent */ | 565 | /* ping management */ |
566 | rxrpc_serial_t ping_serial; /* Last ping sent */ | ||
567 | ktime_t ping_time; /* Time last ping sent */ | ||
563 | 568 | ||
564 | /* transmission-phase ACK management */ | 569 | /* transmission-phase ACK management */ |
565 | ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ | 570 | ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ |
@@ -730,6 +735,7 @@ enum rxrpc_timer_trace { | |||
730 | rxrpc_timer_init_for_reply, | 735 | rxrpc_timer_init_for_reply, |
731 | rxrpc_timer_expired, | 736 | rxrpc_timer_expired, |
732 | rxrpc_timer_set_for_ack, | 737 | rxrpc_timer_set_for_ack, |
738 | rxrpc_timer_set_for_ping, | ||
733 | rxrpc_timer_set_for_resend, | 739 | rxrpc_timer_set_for_resend, |
734 | rxrpc_timer_set_for_send, | 740 | rxrpc_timer_set_for_send, |
735 | rxrpc_timer__nr_trace | 741 | rxrpc_timer__nr_trace |
@@ -1068,7 +1074,7 @@ extern const s8 rxrpc_ack_priority[]; | |||
1068 | /* | 1074 | /* |
1069 | * output.c | 1075 | * output.c |
1070 | */ | 1076 | */ |
1071 | int rxrpc_send_ack_packet(struct rxrpc_call *); | 1077 | int rxrpc_send_ack_packet(struct rxrpc_call *, bool); |
1072 | int rxrpc_send_abort_packet(struct rxrpc_call *); | 1078 | int rxrpc_send_abort_packet(struct rxrpc_call *); |
1073 | int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool); | 1079 | int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool); |
1074 | void rxrpc_reject_packets(struct rxrpc_local *); | 1080 | void rxrpc_reject_packets(struct rxrpc_local *); |
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index e313099860d5..eeea9602cb89 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c | |||
@@ -54,6 +54,14 @@ void rxrpc_set_timer(struct rxrpc_call *call, enum rxrpc_timer_trace why, | |||
54 | t = call->ack_at; | 54 | t = call->ack_at; |
55 | } | 55 | } |
56 | 56 | ||
57 | if (!ktime_after(call->ping_at, now)) { | ||
58 | call->ping_at = call->expire_at; | ||
59 | if (!test_and_set_bit(RXRPC_CALL_EV_PING, &call->events)) | ||
60 | queue = true; | ||
61 | } else if (ktime_before(call->ping_at, t)) { | ||
62 | t = call->ping_at; | ||
63 | } | ||
64 | |||
57 | t_j = nsecs_to_jiffies(ktime_to_ns(ktime_sub(t, now))); | 65 | t_j = nsecs_to_jiffies(ktime_to_ns(ktime_sub(t, now))); |
58 | t_j += jiffies; | 66 | t_j += jiffies; |
59 | 67 | ||
@@ -78,6 +86,27 @@ out: | |||
78 | } | 86 | } |
79 | 87 | ||
80 | /* | 88 | /* |
89 | * Propose a PING ACK be sent. | ||
90 | */ | ||
91 | static void rxrpc_propose_ping(struct rxrpc_call *call, | ||
92 | bool immediate, bool background) | ||
93 | { | ||
94 | if (immediate) { | ||
95 | if (background && | ||
96 | !test_and_set_bit(RXRPC_CALL_EV_PING, &call->events)) | ||
97 | rxrpc_queue_call(call); | ||
98 | } else { | ||
99 | ktime_t now = ktime_get_real(); | ||
100 | ktime_t ping_at = ktime_add_ms(now, rxrpc_idle_ack_delay); | ||
101 | |||
102 | if (ktime_before(ping_at, call->ping_at)) { | ||
103 | call->ping_at = ping_at; | ||
104 | rxrpc_set_timer(call, rxrpc_timer_set_for_ping, now); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* | ||
81 | * propose an ACK be sent | 110 | * propose an ACK be sent |
82 | */ | 111 | */ |
83 | static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | 112 | static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, |
@@ -90,6 +119,14 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | |||
90 | ktime_t now, ack_at; | 119 | ktime_t now, ack_at; |
91 | s8 prior = rxrpc_ack_priority[ack_reason]; | 120 | s8 prior = rxrpc_ack_priority[ack_reason]; |
92 | 121 | ||
122 | /* Pings are handled specially because we don't want to accidentally | ||
123 | * lose a ping response by subsuming it into a ping. | ||
124 | */ | ||
125 | if (ack_reason == RXRPC_ACK_PING) { | ||
126 | rxrpc_propose_ping(call, immediate, background); | ||
127 | goto trace; | ||
128 | } | ||
129 | |||
93 | /* Update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial | 130 | /* Update DELAY, IDLE, REQUESTED and PING_RESPONSE ACK serial |
94 | * numbers, but we don't alter the timeout. | 131 | * numbers, but we don't alter the timeout. |
95 | */ | 132 | */ |
@@ -125,7 +162,6 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | |||
125 | expiry = rxrpc_soft_ack_delay; | 162 | expiry = rxrpc_soft_ack_delay; |
126 | break; | 163 | break; |
127 | 164 | ||
128 | case RXRPC_ACK_PING: | ||
129 | case RXRPC_ACK_IDLE: | 165 | case RXRPC_ACK_IDLE: |
130 | if (rxrpc_idle_ack_delay < expiry) | 166 | if (rxrpc_idle_ack_delay < expiry) |
131 | expiry = rxrpc_idle_ack_delay; | 167 | expiry = rxrpc_idle_ack_delay; |
@@ -253,7 +289,7 @@ static void rxrpc_resend(struct rxrpc_call *call, ktime_t now) | |||
253 | goto out; | 289 | goto out; |
254 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, | 290 | rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, 0, true, false, |
255 | rxrpc_propose_ack_ping_for_lost_ack); | 291 | rxrpc_propose_ack_ping_for_lost_ack); |
256 | rxrpc_send_ack_packet(call); | 292 | rxrpc_send_ack_packet(call, true); |
257 | goto out; | 293 | goto out; |
258 | } | 294 | } |
259 | 295 | ||
@@ -345,13 +381,17 @@ recheck_state: | |||
345 | } | 381 | } |
346 | 382 | ||
347 | if (test_and_clear_bit(RXRPC_CALL_EV_ACK, &call->events)) { | 383 | if (test_and_clear_bit(RXRPC_CALL_EV_ACK, &call->events)) { |
348 | call->ack_at = call->expire_at; | ||
349 | if (call->ackr_reason) { | 384 | if (call->ackr_reason) { |
350 | rxrpc_send_ack_packet(call); | 385 | rxrpc_send_ack_packet(call, false); |
351 | goto recheck_state; | 386 | goto recheck_state; |
352 | } | 387 | } |
353 | } | 388 | } |
354 | 389 | ||
390 | if (test_and_clear_bit(RXRPC_CALL_EV_PING, &call->events)) { | ||
391 | rxrpc_send_ack_packet(call, true); | ||
392 | goto recheck_state; | ||
393 | } | ||
394 | |||
355 | if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events)) { | 395 | if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events)) { |
356 | rxrpc_resend(call, now); | 396 | rxrpc_resend(call, now); |
357 | goto recheck_state; | 397 | goto recheck_state; |
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 07094012ac15..4353a29f3b57 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c | |||
@@ -205,6 +205,7 @@ static void rxrpc_start_call_timer(struct rxrpc_call *call) | |||
205 | expire_at = ktime_add_ms(now, rxrpc_max_call_lifetime); | 205 | expire_at = ktime_add_ms(now, rxrpc_max_call_lifetime); |
206 | call->expire_at = expire_at; | 206 | call->expire_at = expire_at; |
207 | call->ack_at = expire_at; | 207 | call->ack_at = expire_at; |
208 | call->ping_at = expire_at; | ||
208 | call->resend_at = expire_at; | 209 | call->resend_at = expire_at; |
209 | call->timer.expires = jiffies + LONG_MAX / 2; | 210 | call->timer.expires = jiffies + LONG_MAX / 2; |
210 | rxrpc_set_timer(call, rxrpc_timer_begin, now); | 211 | rxrpc_set_timer(call, rxrpc_timer_begin, now); |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 103d2b0d4690..a6da83f036d6 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
@@ -625,9 +625,9 @@ static void rxrpc_input_ping_response(struct rxrpc_call *call, | |||
625 | rxrpc_serial_t ping_serial; | 625 | rxrpc_serial_t ping_serial; |
626 | ktime_t ping_time; | 626 | ktime_t ping_time; |
627 | 627 | ||
628 | ping_time = call->ackr_ping_time; | 628 | ping_time = call->ping_time; |
629 | smp_rmb(); | 629 | smp_rmb(); |
630 | ping_serial = call->ackr_ping; | 630 | ping_serial = call->ping_serial; |
631 | 631 | ||
632 | if (!test_bit(RXRPC_CALL_PINGING, &call->flags) || | 632 | if (!test_bit(RXRPC_CALL_PINGING, &call->flags) || |
633 | before(orig_serial, ping_serial)) | 633 | before(orig_serial, ping_serial)) |
diff --git a/net/rxrpc/misc.c b/net/rxrpc/misc.c index 804a88e28739..1cdcba52f83b 100644 --- a/net/rxrpc/misc.c +++ b/net/rxrpc/misc.c | |||
@@ -93,7 +93,6 @@ const s8 rxrpc_ack_priority[] = { | |||
93 | [RXRPC_ACK_EXCEEDS_WINDOW] = 6, | 93 | [RXRPC_ACK_EXCEEDS_WINDOW] = 6, |
94 | [RXRPC_ACK_NOSPACE] = 7, | 94 | [RXRPC_ACK_NOSPACE] = 7, |
95 | [RXRPC_ACK_PING_RESPONSE] = 8, | 95 | [RXRPC_ACK_PING_RESPONSE] = 8, |
96 | [RXRPC_ACK_PING] = 9, | ||
97 | }; | 96 | }; |
98 | 97 | ||
99 | const char rxrpc_ack_names[RXRPC_ACK__INVALID + 1][4] = { | 98 | const char rxrpc_ack_names[RXRPC_ACK__INVALID + 1][4] = { |
@@ -197,6 +196,7 @@ const char rxrpc_timer_traces[rxrpc_timer__nr_trace][8] = { | |||
197 | [rxrpc_timer_expired] = "*EXPR*", | 196 | [rxrpc_timer_expired] = "*EXPR*", |
198 | [rxrpc_timer_init_for_reply] = "IniRpl", | 197 | [rxrpc_timer_init_for_reply] = "IniRpl", |
199 | [rxrpc_timer_set_for_ack] = "SetAck", | 198 | [rxrpc_timer_set_for_ack] = "SetAck", |
199 | [rxrpc_timer_set_for_ping] = "SetPng", | ||
200 | [rxrpc_timer_set_for_send] = "SetTx ", | 200 | [rxrpc_timer_set_for_send] = "SetTx ", |
201 | [rxrpc_timer_set_for_resend] = "SetRTx", | 201 | [rxrpc_timer_set_for_resend] = "SetRTx", |
202 | }; | 202 | }; |
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 2dae877c0876..a12cea0cbc05 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c | |||
@@ -38,7 +38,8 @@ struct rxrpc_abort_buffer { | |||
38 | static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, | 38 | static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, |
39 | struct rxrpc_ack_buffer *pkt, | 39 | struct rxrpc_ack_buffer *pkt, |
40 | rxrpc_seq_t *_hard_ack, | 40 | rxrpc_seq_t *_hard_ack, |
41 | rxrpc_seq_t *_top) | 41 | rxrpc_seq_t *_top, |
42 | u8 reason) | ||
42 | { | 43 | { |
43 | rxrpc_serial_t serial; | 44 | rxrpc_serial_t serial; |
44 | rxrpc_seq_t hard_ack, top, seq; | 45 | rxrpc_seq_t hard_ack, top, seq; |
@@ -58,10 +59,10 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, | |||
58 | pkt->ack.firstPacket = htonl(hard_ack + 1); | 59 | pkt->ack.firstPacket = htonl(hard_ack + 1); |
59 | pkt->ack.previousPacket = htonl(call->ackr_prev_seq); | 60 | pkt->ack.previousPacket = htonl(call->ackr_prev_seq); |
60 | pkt->ack.serial = htonl(serial); | 61 | pkt->ack.serial = htonl(serial); |
61 | pkt->ack.reason = call->ackr_reason; | 62 | pkt->ack.reason = reason; |
62 | pkt->ack.nAcks = top - hard_ack; | 63 | pkt->ack.nAcks = top - hard_ack; |
63 | 64 | ||
64 | if (pkt->ack.reason == RXRPC_ACK_PING) | 65 | if (reason == RXRPC_ACK_PING) |
65 | pkt->whdr.flags |= RXRPC_REQUEST_ACK; | 66 | pkt->whdr.flags |= RXRPC_REQUEST_ACK; |
66 | 67 | ||
67 | if (after(top, hard_ack)) { | 68 | if (after(top, hard_ack)) { |
@@ -93,7 +94,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, | |||
93 | /* | 94 | /* |
94 | * Send an ACK call packet. | 95 | * Send an ACK call packet. |
95 | */ | 96 | */ |
96 | int rxrpc_send_ack_packet(struct rxrpc_call *call) | 97 | int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping) |
97 | { | 98 | { |
98 | struct rxrpc_connection *conn = NULL; | 99 | struct rxrpc_connection *conn = NULL; |
99 | struct rxrpc_ack_buffer *pkt; | 100 | struct rxrpc_ack_buffer *pkt; |
@@ -102,8 +103,8 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call) | |||
102 | rxrpc_serial_t serial; | 103 | rxrpc_serial_t serial; |
103 | rxrpc_seq_t hard_ack, top; | 104 | rxrpc_seq_t hard_ack, top; |
104 | size_t len, n; | 105 | size_t len, n; |
105 | bool ping = false; | ||
106 | int ret; | 106 | int ret; |
107 | u8 reason; | ||
107 | 108 | ||
108 | spin_lock_bh(&call->lock); | 109 | spin_lock_bh(&call->lock); |
109 | if (call->conn) | 110 | if (call->conn) |
@@ -136,14 +137,18 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call) | |||
136 | pkt->whdr.serviceId = htons(call->service_id); | 137 | pkt->whdr.serviceId = htons(call->service_id); |
137 | 138 | ||
138 | spin_lock_bh(&call->lock); | 139 | spin_lock_bh(&call->lock); |
139 | if (!call->ackr_reason) { | 140 | if (ping) { |
140 | spin_unlock_bh(&call->lock); | 141 | reason = RXRPC_ACK_PING; |
141 | ret = 0; | 142 | } else { |
142 | goto out; | 143 | reason = call->ackr_reason; |
144 | if (!call->ackr_reason) { | ||
145 | spin_unlock_bh(&call->lock); | ||
146 | ret = 0; | ||
147 | goto out; | ||
148 | } | ||
149 | call->ackr_reason = 0; | ||
143 | } | 150 | } |
144 | ping = (call->ackr_reason == RXRPC_ACK_PING); | 151 | n = rxrpc_fill_out_ack(call, pkt, &hard_ack, &top, reason); |
145 | n = rxrpc_fill_out_ack(call, pkt, &hard_ack, &top); | ||
146 | call->ackr_reason = 0; | ||
147 | 152 | ||
148 | spin_unlock_bh(&call->lock); | 153 | spin_unlock_bh(&call->lock); |
149 | 154 | ||
@@ -161,7 +166,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call) | |||
161 | pkt->ack.reason, pkt->ack.nAcks); | 166 | pkt->ack.reason, pkt->ack.nAcks); |
162 | 167 | ||
163 | if (ping) { | 168 | if (ping) { |
164 | call->ackr_ping = serial; | 169 | call->ping_serial = serial; |
165 | smp_wmb(); | 170 | smp_wmb(); |
166 | /* We need to stick a time in before we send the packet in case | 171 | /* We need to stick a time in before we send the packet in case |
167 | * the reply gets back before kernel_sendmsg() completes - but | 172 | * the reply gets back before kernel_sendmsg() completes - but |
@@ -170,18 +175,19 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call) | |||
170 | * the packet transmission is more likely to happen towards the | 175 | * the packet transmission is more likely to happen towards the |
171 | * end of the kernel_sendmsg() call. | 176 | * end of the kernel_sendmsg() call. |
172 | */ | 177 | */ |
173 | call->ackr_ping_time = ktime_get_real(); | 178 | call->ping_time = ktime_get_real(); |
174 | set_bit(RXRPC_CALL_PINGING, &call->flags); | 179 | set_bit(RXRPC_CALL_PINGING, &call->flags); |
175 | trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_ping, serial); | 180 | trace_rxrpc_rtt_tx(call, rxrpc_rtt_tx_ping, serial); |
176 | } | 181 | } |
177 | 182 | ||
178 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); | 183 | ret = kernel_sendmsg(conn->params.local->socket, &msg, iov, 2, len); |
179 | if (ping) | 184 | if (ping) |
180 | call->ackr_ping_time = ktime_get_real(); | 185 | call->ping_time = ktime_get_real(); |
181 | 186 | ||
182 | if (call->state < RXRPC_CALL_COMPLETE) { | 187 | if (call->state < RXRPC_CALL_COMPLETE) { |
183 | if (ret < 0) { | 188 | if (ret < 0) { |
184 | clear_bit(RXRPC_CALL_PINGING, &call->flags); | 189 | if (ping) |
190 | clear_bit(RXRPC_CALL_PINGING, &call->flags); | ||
185 | rxrpc_propose_ACK(call, pkt->ack.reason, | 191 | rxrpc_propose_ACK(call, pkt->ack.reason, |
186 | ntohs(pkt->ack.maxSkew), | 192 | ntohs(pkt->ack.maxSkew), |
187 | ntohl(pkt->ack.serial), | 193 | ntohl(pkt->ack.serial), |
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 11723bc1c783..3fa7771c2a9d 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
@@ -143,7 +143,7 @@ static void rxrpc_end_rx_phase(struct rxrpc_call *call, rxrpc_serial_t serial) | |||
143 | if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { | 143 | if (call->state == RXRPC_CALL_CLIENT_RECV_REPLY) { |
144 | rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, true, false, | 144 | rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, 0, serial, true, false, |
145 | rxrpc_propose_ack_terminal_ack); | 145 | rxrpc_propose_ack_terminal_ack); |
146 | rxrpc_send_ack_packet(call); | 146 | rxrpc_send_ack_packet(call, false); |
147 | } | 147 | } |
148 | 148 | ||
149 | write_lock_bh(&call->state_lock); | 149 | write_lock_bh(&call->state_lock); |
@@ -212,7 +212,7 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call) | |||
212 | true, false, | 212 | true, false, |
213 | rxrpc_propose_ack_rotate_rx); | 213 | rxrpc_propose_ack_rotate_rx); |
214 | if (call->ackr_reason) | 214 | if (call->ackr_reason) |
215 | rxrpc_send_ack_packet(call); | 215 | rxrpc_send_ack_packet(call, false); |
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 901b28ceeff4..55a2fb2cfc2f 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
@@ -197,7 +197,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, | |||
197 | do { | 197 | do { |
198 | /* Check to see if there's a ping ACK to reply to. */ | 198 | /* Check to see if there's a ping ACK to reply to. */ |
199 | if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE) | 199 | if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE) |
200 | rxrpc_send_ack_packet(call); | 200 | rxrpc_send_ack_packet(call, false); |
201 | 201 | ||
202 | if (!skb) { | 202 | if (!skb) { |
203 | size_t size, chunk, max, space; | 203 | size_t size, chunk, max, space; |