Netdev List
 help / color / mirror / Atom feed
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
To: acme@redhat.com
Cc: dccp@vger.kernel.org, netdev@vger.kernel.org,
	Gerrit Renker <gerrit@erg.abdn.ac.uk>
Subject: [PATCH 11/14] [ACKVEC]: Implement algorithm to update buffer state
Date: Wed, 19 Dec 2007 14:25:52 +0000	[thread overview]
Message-ID: <1198074355-18842-12-git-send-email-gerrit@erg.abdn.ac.uk> (raw)
In-Reply-To: <1198074355-18842-11-git-send-email-gerrit@erg.abdn.ac.uk>

This implements an algorithm to consistently update the buffer state when
the peer acknowledges receipt of Ack Vectors; updating state in the list of
Ack Vectors as well as in the circular buffer.

The algorithm
 * deals with HC-sender acknowledging to HC-receiver and vice versa,
 * keeps track of the last unacknowledged but received seqno in tail_ackno,
 * has special cases to reset the overflow condition when appropriate,
 * is protected against receiving older information (would mess up buffer state).

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
---
 net/dccp/ackvec.c |   82 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 62 insertions(+), 20 deletions(-)

--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -262,34 +262,76 @@ out_duplicate:
 	return -EILSEQ;
 }
 
-static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
-				     struct dccp_ackvec_record *avr)
-{
-	struct dccp_ackvec_record *next;
+/**
+ * dccp_ackvec_clear_state  -  Perform house-keeping / garbage-collection
+ * This routine is called when the peer acknowledges the receipt of Ack Vectors
+ * up to and including @ackno. While based on on section A.3 of RFC 4340, here
+ * are additional precautions to prevent corrupted buffer state. In particular,
+ * we use tail_ackno to identify outdated records; it always marks the earliest
+ * packet of group (2) in 11.4.2.
+ */
+void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno)
+ {
+	struct dccp_ackvec_record *avr, *next;
+	u8 runlen_now, eff_runlen;
+	s64 delta;
 
-	/* sort out vector length */
-	if (av->av_buf_head <= avr->avr_ack_ptr)
-		av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head;
-	else
-		av->av_vec_len = DCCPAV_MAX_ACKVEC_LEN - 1 -
-				 av->av_buf_head + avr->avr_ack_ptr;
+	avr = dccp_ackvec_lookup(&av->av_records, ackno);
+	if (avr == NULL)
+		return;
+	/*
+	 * Deal with outdated acknowledgments: this arises when e.g. there are
+	 * several old records and the acks from the peer come in slowly. In
+	 * that case we may still have records that pre-date tail_ackno.
+	 */
+	delta = dccp_delta_seqno(av->av_tail_ackno, avr->avr_ack_ackno);
+	if (delta < 0)
+		goto free_records;
+	/*
+	 * Deal with overlapping Ack Vectors: don't subtract more than the
+	 * number of packets between tail_ackno and ack_ackno.
+	 */
+	eff_runlen = delta < avr->avr_ack_runlen ? delta : avr->avr_ack_runlen;
 
-	/* free records */
+	runlen_now = dccp_ackvec_runlen(av->av_buf + avr->avr_ack_ptr);
+	/*
+	 * The run length of Ack Vector cells does not decrease over time. If
+	 * the run length is the same as at the time the Ack Vector was sent, we
+	 * free the ack_ptr cell. That cell can however not be freed if the run
+	 * length has increased: in this case we need to move the tail pointer
+	 * backwards (towards higher indices), to its next-oldest neighbour.
+	 */
+	if (runlen_now > eff_runlen) {
+
+		av->av_buf[avr->avr_ack_ptr] -= eff_runlen + 1;
+		av->av_buf_tail = dccp_ackvec_idx_add(avr->avr_ack_ptr, 1);
+
+		/* This move may not have cleared the overflow flag. */
+		if (av->av_overflow)
+			av->av_overflow = (av->av_buf_head == av->av_buf_tail);
+	} else {
+		av->av_buf_tail	= avr->avr_ack_ptr;
+		/*
+		 * We have made sure that avr points to a valid cell within the
+		 * buffer. This cell is either older than head, or equals head
+		 * (empty buffer): in both cases we no longer have any overflow.
+		 */
+		av->av_overflow	= 0;
+	}
+
+	/*
+	 * The peer has acknowledged up to and including ack_ackno. Hence the
+	 * first packet in group (2) of 11.4.2 is the successor of ack_ackno.
+	 */
+	av->av_tail_ackno = ADD48(avr->avr_ack_ackno, 1);
+
+free_records:
 	list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) {
 		list_del(&avr->avr_node);
 		kmem_cache_free(dccp_ackvec_record_slab, avr);
 	}
 }
 
-void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno)
-{
-	struct dccp_ackvec_record *avr;
-
-	avr = dccp_ackvec_lookup(&av->av_records, ackno);
-	if (avr != NULL)
-		dccp_ackvec_throw_record(av, avr);
-}
-
 int __init dccp_ackvec_init(void)
 {
 	dccp_ackvec_slab = kmem_cache_create("dccp_ackvec",
-- 
1.5.3.GIT


  reply	other threads:[~2007-12-19 14:27 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-19 14:25 [DCCP] [RFC] [Patch 0/14]: Ack Vector implementation + fixes Gerrit Renker
2007-12-19 14:25 ` [PATCH 01/14] [CCID2]: Ack Vectors can happen on most packets Gerrit Renker
2007-12-19 14:25   ` [PATCH 02/14] [ACKVEC]: Update Ack Vector fields Gerrit Renker
2007-12-19 14:25     ` [PATCH 03/14] [ACKVEC]: Use Elapsed Time separately Gerrit Renker
2007-12-19 14:25       ` [PATCH 04/14] [ACKVEC]: Inlines for run length and state Gerrit Renker
2007-12-19 14:25         ` [PATCH 05/14] [ACKVEC]: Smaller allocation/deallocation routines Gerrit Renker
2007-12-19 14:25           ` [PATCH 06/14] [ACKVEC]: Simplify adding Ack Vector records, split option-specific code Gerrit Renker
2007-12-19 14:25             ` [PATCH 07/14] [ACKVEC]: Unnecessary to parse Ack Vectors when clearing HC-receiver state Gerrit Renker
2007-12-19 14:25               ` [PATCH 08/14] [ACKVEC]: Use enum to enumerate Ack Vector states Gerrit Renker
2007-12-19 14:25                 ` [PATCH 09/14] [ACKVEC]: Support for circular Ack Vector buffer with overflow handling Gerrit Renker
2007-12-19 14:25                   ` [PATCH 10/14] [ACKVEC]: Determine buffer length dynamically Gerrit Renker
2007-12-19 14:25                     ` Gerrit Renker [this message]
2007-12-19 14:25                       ` [PATCH 12/14] [ACKVEC]: Update Ack Vector input routine Gerrit Renker
2007-12-19 14:25                         ` [PATCH 13/14] [ACKVEC]: Aggregate Ack-Vector related processing into single function Gerrit Renker
2007-12-19 14:25                           ` [PATCH 14/14] [ACKVEC]: Remove old infrastructure 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=1198074355-18842-12-git-send-email-gerrit@erg.abdn.ac.uk \
    --to=gerrit@erg.abdn.ac.uk \
    --cc=acme@redhat.com \
    --cc=dccp@vger.kernel.org \
    --cc=netdev@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