dccp tfrc: Receiver history initialisation routine
authorGerrit Renker <gerrit@erg.abdn.ac.uk>
Thu, 4 Sep 2008 05:30:19 +0000 (07:30 +0200)
committerGerrit Renker <gerrit@erg.abdn.ac.uk>
Thu, 4 Sep 2008 05:45:40 +0000 (07:45 +0200)
This patch
 1) separates history allocation and initialisation, to facilitate early
    loss detection (implemented by a subsequent patch);

 2) removes duplication by using the existing tfrc_rx_hist_purge() if the
    allocation fails. This is now possible, since the initialisation routine
 3) zeroes out the entire history before using it.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
net/dccp/ccids/ccid3.c
net/dccp/ccids/lib/packet_history.c
net/dccp/ccids/lib/packet_history.h

index 5470a97..36f4992 100644 (file)
@@ -766,7 +766,7 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
 
        hcrx->state = TFRC_RSTATE_NO_DATA;
        tfrc_lh_init(&hcrx->li_hist);
-       return tfrc_rx_hist_alloc(&hcrx->hist);
+       return tfrc_rx_hist_init(&hcrx->hist, sk);
 }
 
 static void ccid3_hc_rx_exit(struct sock *sk)
index 5c44508..5b4e1cf 100644 (file)
@@ -352,28 +352,6 @@ int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
 }
 EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss);
 
-int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h)
-{
-       int i;
-
-       for (i = 0; i <= TFRC_NDUPACK; i++) {
-               h->ring[i] = kmem_cache_alloc(tfrc_rx_hist_slab, GFP_ATOMIC);
-               if (h->ring[i] == NULL)
-                       goto out_free;
-       }
-
-       h->loss_count = h->loss_start = 0;
-       return 0;
-
-out_free:
-       while (i-- != 0) {
-               kmem_cache_free(tfrc_rx_hist_slab, h->ring[i]);
-               h->ring[i] = NULL;
-       }
-       return -ENOBUFS;
-}
-EXPORT_SYMBOL_GPL(tfrc_rx_hist_alloc);
-
 void tfrc_rx_hist_purge(struct tfrc_rx_hist *h)
 {
        int i;
@@ -386,6 +364,36 @@ void tfrc_rx_hist_purge(struct tfrc_rx_hist *h)
 }
 EXPORT_SYMBOL_GPL(tfrc_rx_hist_purge);
 
+static int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h)
+{
+       int i;
+
+       memset(h, 0, sizeof(*h));
+
+       for (i = 0; i <= TFRC_NDUPACK; i++) {
+               h->ring[i] = kmem_cache_alloc(tfrc_rx_hist_slab, GFP_ATOMIC);
+               if (h->ring[i] == NULL) {
+                       tfrc_rx_hist_purge(h);
+                       return -ENOBUFS;
+               }
+       }
+       return 0;
+}
+
+int tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk)
+{
+       if (tfrc_rx_hist_alloc(h))
+               return -ENOBUFS;
+       /*
+        * Initialise first entry with GSR to start loss detection as early as
+        * possible. Code using this must not use any other fields. The entry
+        * will be overwritten once the CCID updates its received packets.
+        */
+       tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno = dccp_sk(sk)->dccps_gsr;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_init);
+
 /**
  * tfrc_rx_hist_rtt_last_s - reference entry to compute RTT samples against
  */
index 221d810..e9d8097 100644 (file)
@@ -153,7 +153,7 @@ extern int  tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
                                struct sock *sk);
 extern u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h,
                                   const struct sk_buff *skb);
-extern int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h);
+extern int  tfrc_rx_hist_init(struct tfrc_rx_hist *h, struct sock *sk);
 extern void tfrc_rx_hist_purge(struct tfrc_rx_hist *h);
 
 #endif /* _DCCP_PKT_HIST_ */