From d469db84ee2035c3f5d10d3072cdbddcbc94cbe9 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 21 Jul 2017 23:49:44 -0400 Subject: [PATCH] serialqueue: Allow a second nak after a retransmit If a nak message causes a retransmission then also accept a second nak message as long as it is for a sequence greater than the first nak. This should allow faster retransmits when there are multiple transmission errors in a small time period. Signed-off-by: Kevin O'Connor --- klippy/serialqueue.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/klippy/serialqueue.c b/klippy/serialqueue.c index 5886f8e1..6271911b 100644 --- a/klippy/serialqueue.c +++ b/klippy/serialqueue.c @@ -347,7 +347,7 @@ struct serialqueue { double last_receive_sent_time; // Retransmit support uint64_t send_seq, receive_seq; - uint64_t retransmit_seq, rtt_sample_seq; + uint64_t ignore_nak_seq, retransmit_seq, rtt_sample_seq; struct list_head sent_queue; double srtt, rttvar, rto; // Pending transmission message queues @@ -492,7 +492,7 @@ handle_message(struct serialqueue *sq, double eventtime, int len) if (rseq != sq->receive_seq) // New sequence number update_receive_seq(sq, eventtime, rseq); - else if (len == MESSAGE_MIN && rseq > sq->retransmit_seq + else if (len == MESSAGE_MIN && rseq > sq->ignore_nak_seq && !list_empty(&sq->sent_queue)) // Duplicate sequence number in an empty message is a nak pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW); @@ -581,10 +581,18 @@ retransmit_event(struct serialqueue *sq, double eventtime) sq->bytes_retransmit += buflen; // Update rto - if (pollreactor_get_timer(&sq->pr, SQPT_RETRANSMIT) != PR_NOW) { + if (pollreactor_get_timer(&sq->pr, SQPT_RETRANSMIT) == PR_NOW) { + // Retransmit due to nak + sq->ignore_nak_seq = sq->receive_seq; + if (sq->receive_seq < sq->retransmit_seq) + // Second nak for this retransmit - don't allow third + sq->ignore_nak_seq = sq->retransmit_seq; + } else { + // Retransmit due to timeout sq->rto *= 2.0; if (sq->rto > MAX_RTO) sq->rto = MAX_RTO; + sq->ignore_nak_seq = sq->send_seq - 1; } sq->retransmit_seq = sq->send_seq - 1; sq->rtt_sample_seq = 0;