DCCP protocol discussions
 help / color / mirror / Atom feed
From: Eddie Kohler <kohler@cs.ucla.edu>
To: dccp@vger.kernel.org
Subject: Re: [SUMMARY]: Problems with loss interval recalculation / audit
Date: Fri, 05 Jan 2007 21:26:18 +0000	[thread overview]
Message-ID: <459EC27A.6030507@cs.ucla.edu> (raw)
In-Reply-To: <200701051829.20415@strip-the-willow>

Gerrit, this summary is not right.

RFC 3448 says that I_0 "represents the number of packets received since the 
last loss event".  (Section 5.5)  In the Linux implementation, this number is 
NOT stored in the li_entry list.  It must be calculated.  This is what Ian's 
nonloss manipulations do.

There are a number of errors in your discussion.  You claim that I_0 is the 
"most recent loss interval", and that it is stored in the li_entry structures. 
  But what RFC 3448 means by I_0 is not stored in the Linux DCCP 
implementation's li_entry structures.  Your comments under "This is the 
crucial point" do not seem to realize this.

Your comments about Ian's patch are also wrong, for the same reason.  I 
believe Ian's patch calculates I_tot0 and I_tot1 correctly, although with 
swapped names.  Certainly if there is a problem it is not the one you have 
identified.

As a side note, you say: "if k < 7 then I_tot0 and I_tot1 always contain _all_ 
intervals, from 0..k, - which is again not conform with the specification". 
What do you think the specification demands here?  I think the specification 
DOES want I_tot0 and I_tot1 to contain all intervals when there are fewer than 8.

So your conclusion is wrong as well.  Ian's patch is a strict improvement on 
the existing code.  I don't see how it worsens compliance.

It would be useful to migrate to an array-based implementation but not a panacea.

Again, Ian's patch seems good to apply.

Eddie



Gerrit Renker wrote:
> This summarizes the issues that have been discussed, 
>      reviews Ian's patch, and
>      tries to identify related problems which impede progress.
> 
> 
> 1) List of known bugs affecting this problem
> ======================
> 
> The following problems are still unresolved:
> 
> BUG#1: No attempt is made to ensure that losses are within the same RTT. This code is 
>        missing. Ian has pointed this out already in December and I think he is working
>        on it (patch `fix_consecutive_loss.diff'). Now we have another problem:
> 
> BUG#2: RTT estimation from CCVal does currently not work. There is code which goes towards
>        this, but only for the first loss interval (function ccid3_hc_rx_calc_first_li, lines
>        793 ... 835). Currently the code uses timestamps everywhere, hence we are not conforming
>        to [RFC 4342, sec. 10.3]. This impedes fixing BUG#1; I have been working on this but not
>        completed testing yet.
> 
> BUG#3: ccid3_hc_rx_detect_loss does not update hcrx->ccid3hcrx_ccval_nonloss in sync with
>        hcrx->ccid3hcrx_seqno_nonloss  => this makes it difficult to fix BUG#1, since as a conseqence
>        we now longer know which non-loss CCVal belongs to which non-loss sequence number.
> 
> BUG#4: Weights are scaled by 4 but the end result, in dccp_li_hist_calc_i_mean, is not divided by 4.
>        This is fixed in Ian's patch, but _not_ in the existing code.> 
> WISH#1: Using an array for the loss history would much simplify the code (as per earlier emails).
> 
> 
> 2) Issues raised by Eddie
> ============> The following are quotes from earlier emails.
> 
> (a) "From Ian's patch, it appears that the OLD code DID NOT include the most 
>      recent loss interval (i.e., the incomplete loss interval, the one that has no 
>      losses) in its calculation of i_tot1.  Ian has added the following line to do 
>      this:
> 
>      > +    i_tot1 += non_loss * dccp_li_hist_w[0];
> 
>      This is correct.  The RFC requires that one of the i_tots include the 
>      incomplete loss interval.  So this part of the patch is required for RFC 
>      compliance.
> 
>      I am assuming however that the incomplete loss interval is NOT included in the 
>      'hcrx->ccid3hcrx_li_hist' list.  If that list DOES include the incomplete loss 
>      interval, then the code would need to be different."
> 
>    => This is the crucial point: the last loss interval is always added to the list first;
>        both before and in Ian's patch. To illustrate, the calling path for this is as follows.
> 
> 	ccid3_hc_rx_packet_recv():
> 		loss = ccid3_hc_rx_detect_loss(sk, packet);
> 
>         ccid3_hc_rx_detect_loss():
> 		while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) > TFRC_RECV_NUM_LATE_LOSS) {
> 			loss = 1;
> 			ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss,
> 		 	       	        	  hcrx->ccid3hcrx_ccval_nonloss);
> 
> 	ccid3_hc_rx_update_li(): adds interval to hcrx->ccid3hcrx_li_hist
> 
>         Back in ccid3_hc_rx_packet_recv(), dccp_li_hist_calc_i_mean() is only executed when loss = 1,
>         hence in dccp_li_hist_calc_i_mean() the most recent interval I_0 is always at the top of the list.
> 
> 
> (b) "i_tot0 should include non_loss, but in the code i_tot1 does."
>     => Please see below.
> 
> (c) "Also, the weights in dccp_li_hist_w appear to be wrong.  They should be 5, 5, 5, 5, 4, 3, 2, 1"
>     => Please see BUG#4. To me it seems better to use exact values, but the implication behind these
>         powers of 2 is that the implicitly get converted into bit-shifts and hence execute faster (as
>         Arnaldo taught me).
> 
> 		
> 3) Auditing against RFC 3448 (draft 3448bis)
> ======================
> I am referring to the more recent draft 3448bis, section 5.4, since the description in that draft is better
> with regard to the case where k < 8 loss intervals have been found.
> 
> The following preconditions and terminology apply:
> 
> 	* n is set to 7 and indices run 0..7, hence this is in accordance with [RFC 3448, 5.4]: we are
>           never using more than 8 loss intervals, as is suggested there.
> 
> 	* I_0 is the most recent loss interval. It is always included (see above for explanation).
> 
> 	* The loss interval list is managed in LIFO manner (list_add), hence I_0 is at the head, and
>           I_7 is at the tail.
> 
> 	* Due to static allocation in dccp_li_hist_interval_new() and due to the add/delete cycle in 
>           ccid3_hc_rx_update_li, the list always contains a constant number of 8 elements.
> 
> 
> (a) Checking the way I_tot0 and W_tot are added
> -----------------------------------------------    
> The specification states the following (irrelevant statements have been removed):
> 	I_tot0 = 0;
> 	W_tot = 0;
>         for (i = 0 to k-1) {
>            I_tot0 = I_tot0 + (I_i * w_i);
>            W_tot  = W_tot  + w_i;
>          }
> 	
> 	=> In the current code we have 
> 
> 	list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) {
> 		if (li_entry->dccplih_interval != ~0) {
> 			i_tot0 += li_entry->dccplih_interval * dccp_li_hist_w[i];
> 			w_tot  += dccp_li_hist_w[i];
> 			
> 	=> In the current code, w_tot is added correctly, but i_tot0 is not, since I_tot7 will
>             currentlly be added. Or, if k < 7, I_tot_k will be added (and it should not be).
>             This is _not_ fixed by Ian's patch.
> 
> 			
> (b) Checking the way I_tot1 is summed
> -------------------------------------
> Here the specification states the following (again only relevant parts printed):
> 
>          I_tot1 = 0;
>          for (i = 1 to k) {
>            I_tot1 = I_tot1 + (I_i * w_(i-1));
>          }
> 
> 	 => In the current code we have:
> 	
> 	list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) {
> 		if (li_entry->dccplih_interval != ~0) {
> 			if (i != 0)
> 				i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1];
> 
> 	 => This is correct, since it sums up all I_i's from 1..k as required
> 
> 	 => By contrast, Ian's patch does the following.
> 	
> 	list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) {
>  		if (li_entry->dccplih_interval != ~0U) {
> 			/* ... */
> 			if (i != 7)
> 				i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i + 1];
> 			if (i = 0) {
> 				non_loss = dccp_hdr_seq(skb);
> 				sub48(&non_loss, li_entry->dccplih_seqno);
> 			}
> 		}
> 		if (++i > DCCP_LI_HIST_IVAL_F_LENGTH)
>  			break;
>  	}
> 	/* ... */
> 	i_tot1 += non_loss * dccp_li_hist_w[0];
> 
> 	=> This stores the value of the first interval in the list into `non_loss' after recomputing it 
>             (which is not necessary, since the first interval is always at the head of the list).
>             Furthermore, transcribed into pseudo code, the loop does the following:
> 
> 	    I_tot1 = 0;
> 	    for (i = 0 to k) {           		/* k is less than or equal to 8 */
> 		if (i != 7 )
>                    I_tot1 = I_tot1 + (I_i * w_(i+1));
>             }
>             
>             This is not conform with [RFC 3448, 5.4], even if i_tot0 and i_tot1 are switched. 
> 
>            The other problem with this code is that if k < 7 then I_tot0 and I_tot1 always contain _all_ 
>            intervals, from 0..k, - which is again not conform with the specification.
> 
> 4) Conclusion
> ======> The current code does not in all cases conform with [RFC 3448, 5.4], Ian's patch changes parts which currently
> conform to non-conform ones and fixes one existing bug (BUG#4). On the whole, neither is a satisfactory solution.
> 
> 5) Suggested fix
> ========
> I think we should migrate to an array-based implementation and fix the issues flagged up above there. In particular,
>  * the statement 
> 	if (++i > DCCP_LI_HIST_IVAL_F_LENGTH)
>  			break;
>    is currently redundant: due to static allocation, we never have more than DCCP_LI_HIST_IVAL_F_LENGTH elements
> 
>  * we have to resort to the clumsy comparison against ~0U to identify empty loss intervals. With a ring-buffer-like        
>    array solution, we could keep track of the current fill level of the list
> 
>  * if k < 8 we have no way of knowing this before the loop, hence the problem with updating I_tot0 will persist
>    as long as we don't record the `fill level' of the buffer

  reply	other threads:[~2007-01-05 21:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-05 18:29 [SUMMARY]: Problems with loss interval recalculation / audit against [RFC 3448, 5.4] Gerrit Renker
2007-01-05 21:26 ` Eddie Kohler [this message]
2007-01-08 16:32 ` Gerrit Renker
2007-01-08 16:55 ` [SUMMARY]: Problems with loss interval recalculation / audit Eddie Kohler
2007-01-08 17:48 ` [SUMMARY]: Problems with loss interval recalculation / audit against [RFC 3448, 5.4] Arnaldo Carvalho de Melo
2007-01-08 20:36 ` Ian McDonald
2007-01-09  8:38 ` Gerrit Renker
2007-01-10  3:14 ` Ian McDonald
2007-01-10  4:27 ` Ian McDonald
2007-01-10 11:32 ` Gerrit Renker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=459EC27A.6030507@cs.ucla.edu \
    --to=kohler@cs.ucla.edu \
    --cc=dccp@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox