Subject: [tcpPrague] Prague Cwnd reduction in CWR state

From: Deepak K <[email-masked]>
Date: Sat, 15 Aug 2020 00:36:09 +0530

Hi everyone,

I am currently trying to align TCP Prague in the ns-3 network simulator
with that of Linux.
In the process, I came across an interesting behaviour: if the sender is in
a CWR state, the cWnd update would look something like
cWnd = cWnd - cWnd * alpha / 2     --- (1)
I noted that this is how DCTCP updates its cWnd in Linux.

But in the case of current Linux Prague code, the value
reduction = cWnd * alpha / 2           --- (2)
is subtracted from the cwnd_cnt variable, which sort of acts as a cushion
and reduces the cWnd over many RTTs (in prague_update_cwnd( ) ), instead of
reducing it instantaneously.

I would like to mention a noticeable difference resulting from the approach
taken in (2). All the following simulations were carried out in ns-3.

While reproducing the single-flow topology from Pete Heist's scenario (
https://github.com/heistp/sce-l4s-ect1#scenario-1-one-flow : a Prague
sender, DualQ bottleneck and a Prague receiver), I decided to implement
both approaches in ns-3 to see how they differ from each other.

For lower bottleneck bandwidths (5mbps and 50mbps in the scenarios), I
didn't observe much difference between (1) and (2), and the approach in (1)
aligned with the cWnd graphs from Linux (which I obtained separately via
namespaces).

However, for the scenario with a higher bottleneck speed - 250mbps in
particular, the difference between (1) and the Linux approach (2) was
significant.
With (1), the cWnd was reduced by a smaller value when compared to (2), in
ns-3.This meant that (2) took more time to reach a stable value in Additive
Increase compared to (1). I also observed that cWnd reduced to a much lower
value in Linux (again, graphs obtained via namespaces) when compared with
the ns-3 plots from (1).

My guess would be that in (2), since cWnd is decreased gradually, the
sender would not immediately relieve the queue of congestion, and hence
would receive few more ECE marks leading to further reduction later on when
compared to (1).

I noted this behaviour for both higher (80ms) and lower (20ms) values of
RTT, with a 250mbps bottleneck.
Could you comment on the reason for choosing approach (2) in Linux instead
of (1)?

Thanks.

---

From: "Tilmans, Olivier (Nokia - BE/Antwerp)" <[email-masked]>
Date: Mon, 17 Aug 2020 12:57:26 +0000

Hi Deepak,

 > I noted that this is how DCTCP updates its cWnd in Linux.

Not exactly. DCTCP does indeed update ssthresh to that value, but does
not update cwnd immediately. Instead, the cwnd reduction is applied
gradually over the next RTT through PRR.

 > reducing it instantaneously.

As we transitioned Prague away from using the cong_avoid/ssthresh hooks and
instead use the unified cong_control hook, we lost the implementation of PRR
and the benefits it brings (namely: no transmission "silence" after a cwnd
reduction due to a drop/mark that effectively disables fast-recovery/...,
see RFC6937). This cwnd_cnt cushion is there as a stop-gap implementation;
Ideally a 'full' PRR should replace it.

 > While reproducing the single-flow topology from Pete Heist's scenario
 > (https://github.com/heistp/sce-l4s-ect1#scenario-1-one-flow : a Prague

When you compare "(1) and the Linux approach (2)", you are referring to
ns3's-DCTCP model as (1) and the Linux prague code as (2) right?
Does ns3 implement PRR? You could easily spot this on a cwnd graph by checking
whether the reductions are smooth or not.

 > value in Linux (again, graphs obtained via namespaces) when compared with

I am not sure I understand fully that paragraph. Are all the reductions in
(1) smaller than in (2)? You mention reaching a stable value, so I assume
you're also speaking of the SS->AI transition?

 > would receive few more ECE marks leading to further reduction later on when

Assuming your ns3 model in (1) does not have PRR, it would be interesting to
compare there the behavior of DCTCP with PRR (either directly in Linux or
extending ns3) to (2).
 
It is true that smoothing the cwnd decrease over (part of) a RTT will
keep some pressure in the queue (as opposed to a full quiet period where the
queue fully drains in the case of a 50% halving). 

 > Could you comment on the reason for choosing approach (2) in Linux instead

Originally, we had to add this in to re-enable fast-recovery when facing drops.
It is indeed true that this has an effect in the ECN-triggered reductions.

This would probably warrant an hybrid approach, using a PRR-inspired smooth
reduction in case of losses, and an instant reduction for cwnd-triggered
reduction.

The code is open-source, feel free to experiment with such a change. We'd be
happy to merge patches if you show experiments supporting the benefits of such
changes.

Best,
Olivier