[CCID 3]: Use a function to update p_inv, and p is never used

This
 1) concentrates previously scattered computation of p_inv into one function;
 2) removes the `p' element of the CCID3 RX sock (it is redundant);
 3) makes the tfrc_rx_info structure standalone, only used on demand.

The reason for (2) is that the code essentially only uses p_inv = 1/p. It does 
not
need p, since all the relevant information is already in p_inv.
The motivation for (3) is that the embedded info structure will not be used 
often,
so that the extra cost of keeping p in synch with p_inv (which has to be done at
each packet reception) is overhead most of the time.

Advantages that this buys:
--------------------------
 * the RX sock loses further weight;
 * computation of p_inv is no longer scattered in different places;
 * not having to keep p in sync with p_inv speeds up computation
   (important, as p_inv has to be recomputed for each new data packet);
 * several test cases can now be removed since all is in one function;
 * the send_feedback and packet_recv code becomes simpler.

Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
 net/dccp/ccids/ccid3.c |   57 +++++++++++++++++++++++++------------------------
 net/dccp/ccids/ccid3.h |   19 ++++++----------
 2 files changed, 38 insertions(+), 38 deletions(-)

--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -726,6 +726,25 @@ static inline void ccid3_hc_rx_update_s(
                TFRC_EWMA(hcrx->ccid3hcrx_s, len, 9);
 }
 
+/* returns: 1 when p > p_prev (i.e. when feedback is required); 0 else */
+static int ccid3_hc_rx_update_p(struct ccid3_hc_rx_sock *hcrx)
+{
+       struct list_head *li_hist = &hcrx->ccid3hcrx_li_hist;
+       u32 pinv_prev = hcrx->ccid3hcrx_pinv;
+
+       if (list_empty(li_hist)) /* only empty if no loss so far, i.e. p == 0 */
+               return 0;
+
+       hcrx->ccid3hcrx_pinv = dccp_li_hist_calc_i_mean(li_hist);
+       if (hcrx->ccid3hcrx_pinv == 0) {
+               DCCP_BUG("non-empty LI history and yet I_mean == 0!");
+               return 0;
+       }
+
+       /* exploit that  p > p_prev  <=>  1/p < 1/p_prev  */
+       return (hcrx->ccid3hcrx_pinv < pinv_prev);
+}
+
 static void ccid3_hc_rx_send_feedback(struct sock *sk)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
@@ -741,6 +760,7 @@ static void ccid3_hc_rx_send_feedback(st
        switch (hcrx->ccid3hcrx_state) {
        case TFRC_RSTATE_NO_DATA:
                hcrx->ccid3hcrx_x_recv = 0;
+               hcrx->ccid3hcrx_pinv   = ~0U;   /* see RFC 4342, 8.5 */
                break;
        case TFRC_RSTATE_DATA:
                delta = timeval_delta(&now,
@@ -770,14 +790,6 @@ static void ccid3_hc_rx_send_feedback(st
        DCCP_BUG_ON(delta < 0);
        hcrx->ccid3hcrx_elapsed_time = delta / 10;
 
-       if (hcrx->ccid3hcrx_p == 0)
-               hcrx->ccid3hcrx_pinv = ~0U;     /* see RFC 4342, 8.5 */
-       else if (hcrx->ccid3hcrx_p > 1000000) {
-               DCCP_WARN("p (%u) > 100%%\n", hcrx->ccid3hcrx_p);
-               hcrx->ccid3hcrx_pinv = 1;       /* use 100% in this case */
-       } else
-               hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
-
        dp->dccps_hc_rx_insert_options = 1;
        dccp_send_ack(sk);
 }
@@ -1016,7 +1028,7 @@ static void ccid3_hc_rx_packet_recv(stru
        const struct dccp_options_received *opt_recv;
        struct dccp_rx_hist_entry *packet;
        struct timeval now;
-       u32 p_prev, r_sample, rtt_prev;
+       u32 r_sample, rtt_prev;
        int loss, payload_size;
 
        BUG_ON(hcrx == NULL);
@@ -1096,22 +1108,8 @@ static void ccid3_hc_rx_packet_recv(stru
        ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n",
                       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
 
-       p_prev = hcrx->ccid3hcrx_p;
-
-       /* Calculate loss event rate */
-       if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
-               u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
-
-               /* Scaling up by 1000000 as fixed decimal */
-               if (i_mean != 0)
-                       hcrx->ccid3hcrx_p = 1000000 / i_mean;
-       } else
-               DCCP_BUG("empty loss history");
-
-       if (hcrx->ccid3hcrx_p > p_prev) {
+       if (ccid3_hc_rx_update_p(hcrx))
                ccid3_hc_rx_send_feedback(sk);
-               return;
-       }
 }
 
 static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
@@ -1165,6 +1163,11 @@ static int ccid3_hc_rx_getsockopt(struct
 {
        const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
        const void *val;
+       struct tfrc_rx_info rx_info = {
+               .tfrcrx_x_recv  = hcrx->ccid3hcrx_x_recv,
+               .tfrcrx_rtt     = hcrx->ccid3hcrx_rtt,
+               .tfrcrx_p       = scaled_div(1, hcrx->ccid3hcrx_pinv)
+       };
 
        /* Listen socks doesn't have a private CCID block */
        if (sk->sk_state == DCCP_LISTEN)
@@ -1172,10 +1175,10 @@ static int ccid3_hc_rx_getsockopt(struct
 
        switch (optname) {
        case DCCP_SOCKOPT_CCID_RX_INFO:
-               if (len < sizeof(hcrx->ccid3hcrx_tfrc))
+               if (len < sizeof(rx_info))
                        return -EINVAL;
-               len = sizeof(hcrx->ccid3hcrx_tfrc);
-               val = &hcrx->ccid3hcrx_tfrc;
+               len = sizeof(rx_info);
+               val = &rx_info;
                break;
        default:
                return -ENOPROTOOPT;
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -127,38 +127,35 @@ enum ccid3_hc_rx_states {
 
 /** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
  *
- *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
- *  @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
- *  @ccid3hcrx_p  -  current loss event rate (RFC 3448 5.4)
  *  @ccid3hcrx_seqno_nonloss  -  Last received non-loss sequence number
  *  @ccid3hcrx_ccval_nonloss  -  Last received non-loss Window CCVal
  *  @ccid3hcrx_ccval_last_counter  -  Tracks window counter (RFC 4342, 8.1)
  *  @ccid3hcrx_state  -  receiver state, one of %ccid3_hc_rx_states
+ *  @ccid3hcrx_s  -  Received packet size in bytes
  *  @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
+ *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
+ *  @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
+ *  @ccid3hcrx_pinv  -  Reciprocal of Loss Event Rate p (RFC 4342, sec. 8.5)
  *  @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
  *  @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
  *  @ccid3hcrx_hist  -  Packet history
  *  @ccid3hcrx_li_hist  -  Loss Interval History
- *  @ccid3hcrx_s  -  Received packet size in bytes
- *  @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
  *  @ccid3hcrx_elapsed_time  -  Time since packet reception
  */
 struct ccid3_hc_rx_sock {
-       struct tfrc_rx_info             ccid3hcrx_tfrc;
-#define ccid3hcrx_x_recv               ccid3hcrx_tfrc.tfrcrx_x_recv
-#define ccid3hcrx_rtt                  ccid3hcrx_tfrc.tfrcrx_rtt
-#define ccid3hcrx_p                    ccid3hcrx_tfrc.tfrcrx_p
        u64                             ccid3hcrx_seqno_nonloss:48,
                                        ccid3hcrx_ccval_nonloss:4,
                                        ccid3hcrx_ccval_last_counter:4;
        enum ccid3_hc_rx_states         ccid3hcrx_state:8;
+       u16                             ccid3hcrx_s;
        u32                             ccid3hcrx_bytes_recv;
+       u32                             ccid3hcrx_x_recv;
+       u32                             ccid3hcrx_rtt;
+       u32                             ccid3hcrx_pinv;
        struct timeval                  ccid3hcrx_tstamp_last_feedback;
        struct timeval                  ccid3hcrx_tstamp_last_ack;
        struct list_head                ccid3hcrx_hist;
        struct list_head                ccid3hcrx_li_hist;
-       u16                             ccid3hcrx_s;
-       u32                             ccid3hcrx_pinv;
        u32                             ccid3hcrx_elapsed_time;
 };
 
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to