Re: [quicwg/base-drafts] Rewrite of RTT estimation section (#2592)

ianswett <notifications@github.com> Tue, 09 April 2019 22:03 UTC

Return-Path: <noreply@github.com>
X-Original-To: quic-issues@ietfa.amsl.com
Delivered-To: quic-issues@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 963E3120485 for <quic-issues@ietfa.amsl.com>; Tue, 9 Apr 2019 15:03:08 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -8.001
X-Spam-Level:
X-Spam-Status: No, score=-8.001 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_HI=-5, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=github.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VuCKDIP_Z6eN for <quic-issues@ietfa.amsl.com>; Tue, 9 Apr 2019 15:03:04 -0700 (PDT)
Received: from out-14.smtp.github.com (out-14.smtp.github.com [192.30.254.197]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 0EC2E120490 for <quic-issues@ietf.org>; Tue, 9 Apr 2019 15:03:04 -0700 (PDT)
Date: Tue, 09 Apr 2019 15:03:03 -0700
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=github.com; s=pf2014; t=1554847383; bh=sNCu7iMmRs9afcvP9Zeb+tvd9K3y9fnBgSjR9HnnXL4=; h=Date:From:Reply-To:To:Cc:In-Reply-To:References:Subject:List-ID: List-Archive:List-Post:List-Unsubscribe:From; b=0beWlARvEI/lk8eO0/a0Rwf/bx4H/r9sL4nBXGP4tLI8WUY9pt9yzAV4XTBMJU/a8 WCpBf24mKpZORwBlDINDZxRLDw6Jo71yKJrFybtjmD697R4ogDCvHNg+ooXCCj/wSL 5gQTSS6YTidI639TPNOsmlllbLM6KZzKdR+aMZSs=
From: ianswett <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+0166e4ab8c50a71c44f44fc4a6ec09b111d9c5263ee4c20a92cebaba491792a169ce19a545f4@reply.github.com>
To: quicwg/base-drafts <base-drafts@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Message-ID: <quicwg/base-drafts/pull/2592/review/223838768@github.com>
In-Reply-To: <quicwg/base-drafts/pull/2592@github.com>
References: <quicwg/base-drafts/pull/2592@github.com>
Subject: Re: [quicwg/base-drafts] Rewrite of RTT estimation section (#2592)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5cad16972c8e0_163d3fbcf98d45b4135693"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: ianswett
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
X-GitHub-Recipient-Address: quic-issues@ietf.org
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic-issues/vp98xk_qLrHiEwMHOHZ7PGjlImA>
X-BeenThere: quic-issues@ietf.org
X-Mailman-Version: 2.1.29
List-Id: Notification list for GitHub issues related to the QUIC WG <quic-issues.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic-issues/>
List-Post: <mailto:quic-issues@ietf.org>
List-Help: <mailto:quic-issues-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 09 Apr 2019 22:03:15 -0000

ianswett commented on this pull request.

Thanks for the substantial rework, some comments.

> @@ -226,24 +226,25 @@ QUIC supports many ACK ranges, opposed to TCP's 3 SACK ranges.  In high loss
 environments, this speeds recovery, reduces spurious retransmits, and ensures
 forward progress without relying on timeouts.
 
-### Explicit Correction For Delayed ACKs
+### Explicit Correction For Delayed ACKs {#ack-delay}

Actually, ACKs are delayed by the receiver in this case and this whole section talks about the ACK frame, which makes sense to me.

>  
 
-# Generating Acknowledgements
-
-QUIC SHOULD delay sending acknowledgements in response to packets, but MUST NOT
-excessively delay acknowledgements of ack-eliciting packets. Specifically,
-implementations MUST attempt to enforce a maximum ack delay to avoid causing
-the peer spurious timeouts.  The maximum ack delay is communicated in the
-`max_ack_delay` transport parameter and the default value is 25ms.
+# Generating Acknowledgements {#generating-acks}

Sidenote: Are we ever going to move this to transport?

> -RTT when multiple such ACK frames are received within an RTT.  When multiple
-samples are generated within an RTT, the smoothed RTT and RTT variance could
-retain inadequate history, as suggested in {{?RFC6298}}. Changing these
-computations is currently an open research question.
-
-min_rtt is the minimum RTT measured over the connection, prior to adjusting by
-ack delay.  Ignoring ack delay for min RTT prevents intentional or unintentional
-underestimation of min RTT, which in turn prevents underestimating smoothed RTT.
-
-A sender calculates both smoothed RTT (SRTT) and RTT variance (RTTVAR) similar
-to those specified in {{?RFC6298}}.  Note that computing smoothed_rtt does not
-use ack_delay for the first RTT sample, because doing so would result in a
-smoothed_rtt that is smaller than the min_rtt.
-
-On every newly acknowledged ack-eliciting largest acked:
+## Measuring and Reporting Host Delay {#host-delay}

Would "receiver delay" be more accurate?  I know I've heard the term host delay before, but I thought it usually implied unintentional delays(ie: processing time, etc), not intentional delays like delayed ACKs?

> -retain inadequate history, as suggested in {{?RFC6298}}. Changing these
-computations is currently an open research question.
-
-min_rtt is the minimum RTT measured over the connection, prior to adjusting by
-ack delay.  Ignoring ack delay for min RTT prevents intentional or unintentional
-underestimation of min RTT, which in turn prevents underestimating smoothed RTT.
-
-A sender calculates both smoothed RTT (SRTT) and RTT variance (RTTVAR) similar
-to those specified in {{?RFC6298}}.  Note that computing smoothed_rtt does not
-use ack_delay for the first RTT sample, because doing so would result in a
-smoothed_rtt that is smaller than the min_rtt.
-
-On every newly acknowledged ack-eliciting largest acked:
+## Measuring and Reporting Host Delay {#host-delay}
+
+An endpoint measures the delay incurred between when a packet is received and

endpoint -> receiver?

> -ack delay.  Ignoring ack delay for min RTT prevents intentional or unintentional
-underestimation of min RTT, which in turn prevents underestimating smoothed RTT.
-
-A sender calculates both smoothed RTT (SRTT) and RTT variance (RTTVAR) similar
-to those specified in {{?RFC6298}}.  Note that computing smoothed_rtt does not
-use ack_delay for the first RTT sample, because doing so would result in a
-smoothed_rtt that is smaller than the min_rtt.
-
-On every newly acknowledged ack-eliciting largest acked:
+## Measuring and Reporting Host Delay {#host-delay}
+
+An endpoint measures the delay incurred between when a packet is received and
+when the corresponding acknowledgment is sent.  The endpoint encodes this host
+delay for the largest acknowledged packet in the Ack Delay field of an ACK frame
+(see Section 19.3 of {{QUIC-TRANSPORT}}).  This allows the receiver of the ACK
+to adjust for any host delays - importantly, for delayed acknowledgements - when

Can you avoid ' - ' with ", which is particularly important for delayed acknowledgements,"

> -A sender calculates both smoothed RTT (SRTT) and RTT variance (RTTVAR) similar
-to those specified in {{?RFC6298}}.  Note that computing smoothed_rtt does not
-use ack_delay for the first RTT sample, because doing so would result in a
-smoothed_rtt that is smaller than the min_rtt.
-
-On every newly acknowledged ack-eliciting largest acked:
+## Measuring and Reporting Host Delay {#host-delay}
+
+An endpoint measures the delay incurred between when a packet is received and
+when the corresponding acknowledgment is sent.  The endpoint encodes this host
+delay for the largest acknowledged packet in the Ack Delay field of an ACK frame
+(see Section 19.3 of {{QUIC-TRANSPORT}}).  This allows the receiver of the ACK
+to adjust for any host delays - importantly, for delayed acknowledgements - when
+estimating the path RTT.  In certain deployments, a packet might be held in the
+OS kernel or elsewhere on the host before being processed by the QUIC
+stack. Where possible, an endpoint SHOULD include these delays when populating

Based on my experience, I might be inclined towards a MAY.  Using receive timestamps creates as many(or more) complexities as it solves.

> -On every newly acknowledged ack-eliciting largest acked:
+## Measuring and Reporting Host Delay {#host-delay}
+
+An endpoint measures the delay incurred between when a packet is received and
+when the corresponding acknowledgment is sent.  The endpoint encodes this host
+delay for the largest acknowledged packet in the Ack Delay field of an ACK frame
+(see Section 19.3 of {{QUIC-TRANSPORT}}).  This allows the receiver of the ACK
+to adjust for any host delays - importantly, for delayed acknowledgements - when
+estimating the path RTT.  In certain deployments, a packet might be held in the
+OS kernel or elsewhere on the host before being processed by the QUIC
+stack. Where possible, an endpoint SHOULD include these delays when populating
+the Ack Delay field in an ACK frame.
+
+An endpoint MUST NOT excessively delay acknowledgements of ack-eliciting
+packets.  The maximum ack delay is communicated in the max_ack_delay transport
+parameter, see Section 18.1 of {{QUIC-TRANSPORT}}.  max_ack_delay implies an

```suggestion
parameter, see Section 18.1 of {{QUIC-TRANSPORT}}.  max_ack_delay specifies an
```

> +OS kernel or elsewhere on the host before being processed by the QUIC
+stack. Where possible, an endpoint SHOULD include these delays when populating
+the Ack Delay field in an ACK frame.
+
+An endpoint MUST NOT excessively delay acknowledgements of ack-eliciting
+packets.  The maximum ack delay is communicated in the max_ack_delay transport
+parameter, see Section 18.1 of {{QUIC-TRANSPORT}}.  max_ack_delay implies an
+explicit contract: an endpoint promises to never delay acknowledgments of an
+ack-eliciting packet by more than the indicated value. If it does, any excess
+accrues to the RTT estimate and could result in spurious retransmissions from
+the peer.
+
+
+# Estimating the Round-Trip Time {#compute-rtt}
+
+At a high level, an endpoint measures the time from when a packet was sent to

```suggestion
An endpoint measures the time from when a packet was sent to
```

>  ~~~
 latest_rtt = ack_time - send_time_of_largest_acked
 ~~~
 
-First RTT sample:
+An endpoint uses only locally observed times in generating RTT samples and does

I'm confused about where this is going, since we're going to adjust later on?

>  ~~~
 latest_rtt = ack_time - send_time_of_largest_acked
 ~~~
 
-First RTT sample:
+An endpoint uses only locally observed times in generating RTT samples and does
+not adjust for any host delays reported by the peer ({{host-delay}}).
+
+A peer reports host delays for only the largest acknowledged packet in an ACK
+frame, which is assumed by subsequent computations of smoothed_rtt and rttvar in

I'm unclear what the latter half of this sentence means?  Maybe remove it?

>  ~~~
 latest_rtt = ack_time - send_time_of_largest_acked
 ~~~
 
-First RTT sample:
+An endpoint uses only locally observed times in generating RTT samples and does
+not adjust for any host delays reported by the peer ({{host-delay}}).
+
+A peer reports host delays for only the largest acknowledged packet in an ACK
+frame, which is assumed by subsequent computations of smoothed_rtt and rttvar in
+adjusting for host delays.  As a result, an RTT sample is only generated using
+the largest acknowledged packet in the received ACK frame.
+
+To avoid generating multiple RTT samples using the same packet, an ACK frame
+SHOULD NOT be used to update RTT estimates if it does not newly acknowledge the

You say this two different ways, which are subtly different.  Above, you say the largest acked needs to be larger.  Here you say it needs to be newly acknowledged.  I think the latter is more correct, but we should be consistent.

>  ~~~
 latest_rtt = ack_time - send_time_of_largest_acked
 ~~~
 
-First RTT sample:
+An endpoint uses only locally observed times in generating RTT samples and does
+not adjust for any host delays reported by the peer ({{host-delay}}).
+
+A peer reports host delays for only the largest acknowledged packet in an ACK
+frame, which is assumed by subsequent computations of smoothed_rtt and rttvar in
+adjusting for host delays.  As a result, an RTT sample is only generated using
+the largest acknowledged packet in the received ACK frame.
+
+To avoid generating multiple RTT samples using the same packet, an ACK frame
+SHOULD NOT be used to update RTT estimates if it does not newly acknowledge the
+largest acknowledged packet.
+
+An RTT sample MUST NOT be generated on receiving an ACK frame that does not
+newly acknowledge at least one ack-eliciting packet.  A peer does not send an

peer -> receiver?

Also, this paragraph could be a bit clearer, since I think there's an important point here and it may not be clear to all readers.

>    // Based on {{?RFC6298}}.
   if (smoothed_rtt == 0):
-    smoothed_rtt = latest_rtt
+    smoothed_rtt = adjusted_rtt

I'd suggest moving the adjusted_rtt calculation into the else and using latest_rtt here?  If not, I'd ensure smoothed_rtt and rttvar are set as a function of the same field, not one based on adjusted_rtt and the other latest_rtt.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2592#pullrequestreview-223838768