diff options
Diffstat (limited to 'net/rxrpc/call_event.c')
-rw-r--r-- | net/rxrpc/call_event.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index 8e7434e92097..468efc3660c0 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c | |||
@@ -123,6 +123,7 @@ static void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason, | |||
123 | else | 123 | else |
124 | ack_at = expiry; | 124 | ack_at = expiry; |
125 | 125 | ||
126 | ack_at += READ_ONCE(call->tx_backoff); | ||
126 | ack_at += now; | 127 | ack_at += now; |
127 | if (time_before(ack_at, call->ack_at)) { | 128 | if (time_before(ack_at, call->ack_at)) { |
128 | WRITE_ONCE(call->ack_at, ack_at); | 129 | WRITE_ONCE(call->ack_at, ack_at); |
@@ -311,6 +312,7 @@ void rxrpc_process_call(struct work_struct *work) | |||
311 | container_of(work, struct rxrpc_call, processor); | 312 | container_of(work, struct rxrpc_call, processor); |
312 | rxrpc_serial_t *send_ack; | 313 | rxrpc_serial_t *send_ack; |
313 | unsigned long now, next, t; | 314 | unsigned long now, next, t; |
315 | unsigned int iterations = 0; | ||
314 | 316 | ||
315 | rxrpc_see_call(call); | 317 | rxrpc_see_call(call); |
316 | 318 | ||
@@ -319,6 +321,11 @@ void rxrpc_process_call(struct work_struct *work) | |||
319 | call->debug_id, rxrpc_call_states[call->state], call->events); | 321 | call->debug_id, rxrpc_call_states[call->state], call->events); |
320 | 322 | ||
321 | recheck_state: | 323 | recheck_state: |
324 | /* Limit the number of times we do this before returning to the manager */ | ||
325 | iterations++; | ||
326 | if (iterations > 5) | ||
327 | goto requeue; | ||
328 | |||
322 | if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) { | 329 | if (test_and_clear_bit(RXRPC_CALL_EV_ABORT, &call->events)) { |
323 | rxrpc_send_abort_packet(call); | 330 | rxrpc_send_abort_packet(call); |
324 | goto recheck_state; | 331 | goto recheck_state; |
@@ -447,13 +454,16 @@ recheck_state: | |||
447 | rxrpc_reduce_call_timer(call, next, now, rxrpc_timer_restart); | 454 | rxrpc_reduce_call_timer(call, next, now, rxrpc_timer_restart); |
448 | 455 | ||
449 | /* other events may have been raised since we started checking */ | 456 | /* other events may have been raised since we started checking */ |
450 | if (call->events && call->state < RXRPC_CALL_COMPLETE) { | 457 | if (call->events && call->state < RXRPC_CALL_COMPLETE) |
451 | __rxrpc_queue_call(call); | 458 | goto requeue; |
452 | goto out; | ||
453 | } | ||
454 | 459 | ||
455 | out_put: | 460 | out_put: |
456 | rxrpc_put_call(call, rxrpc_call_put); | 461 | rxrpc_put_call(call, rxrpc_call_put); |
457 | out: | 462 | out: |
458 | _leave(""); | 463 | _leave(""); |
464 | return; | ||
465 | |||
466 | requeue: | ||
467 | __rxrpc_queue_call(call); | ||
468 | goto out; | ||
459 | } | 469 | } |