Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78404
b: refs/heads/master
c: 954c2db
h: refs/heads/master
v: v3
  • Loading branch information
Gerrit Renker authored and David S. Miller committed Jan 28, 2008
1 parent d324e34 commit ac9fc42
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de0d411cb8ea51175f52d935faead5c542b6e007
refs/heads/master: 954c2db868ce896325dced91d5fba5e2226897a4
72 changes: 60 additions & 12 deletions trunk/net/dccp/ccids/ccid3.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* net/dccp/ccids/ccid3.c
*
* Copyright (c) 2007 The University of Aberdeen, Scotland, UK
* Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
* Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
*
Expand Down Expand Up @@ -33,11 +34,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "../ccid.h"
#include "../dccp.h"
#include "lib/packet_history.h"
#include "lib/loss_interval.h"
#include "lib/tfrc.h"
#include "ccid3.h"

#include <asm/unaligned.h>
Expand Down Expand Up @@ -757,6 +754,46 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
return 0;
}

/** ccid3_first_li - Implements [RFC 3448, 6.3.1]
*
* Determine the length of the first loss interval via inverse lookup.
* Assume that X_recv can be computed by the throughput equation
* s
* X_recv = --------
* R * fval
* Find some p such that f(p) = fval; return 1/p (scaled).
*/
static u32 ccid3_first_li(struct sock *sk)
{
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u32 x_recv, p, delta;
u64 fval;

if (hcrx->ccid3hcrx_rtt == 0) {
DCCP_WARN("No RTT estimate available, using fallback RTT\n");
hcrx->ccid3hcrx_rtt = DCCP_FALLBACK_RTT;
}

delta = ktime_to_us(net_timedelta(hcrx->ccid3hcrx_tstamp_last_feedback));
x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
if (x_recv == 0) { /* would also trigger divide-by-zero */
DCCP_WARN("X_recv==0\n");
if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
DCCP_BUG("stored value of X_recv is zero");
return ~0U;
}
}

fval = scaled_div(hcrx->ccid3hcrx_s, hcrx->ccid3hcrx_rtt);
fval = scaled_div32(fval, x_recv);
p = tfrc_calc_x_reverse_lookup(fval);

ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
"loss rate=%u\n", dccp_role(sk), sk, x_recv, p);

return p == 0 ? ~0U : scaled_div(1, p);
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
Expand Down Expand Up @@ -794,6 +831,14 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
/*
* Handle pending losses and otherwise check for new loss
*/
if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist) &&
tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist,
skb, ndp, ccid3_first_li, sk) ) {
do_feedback = CCID3_FBACK_PARAM_CHANGE;
goto done_receiving;
}

if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
goto update_records;

Expand All @@ -803,7 +848,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
if (unlikely(!is_data_packet))
goto update_records;

if (list_empty(&hcrx->ccid3hcrx_li_hist)) { /* no loss so far: p = 0 */
if (!tfrc_lh_is_initialised(&hcrx->ccid3hcrx_li_hist)) {
const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
/*
* Empty loss history: no loss so far, hence p stays 0.
Expand All @@ -812,6 +857,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
*/
if (sample != 0)
hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);

} else if (tfrc_lh_update_i_mean(&hcrx->ccid3hcrx_li_hist, skb)) {
/*
* Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
* has decreased (resp. p has increased), send feedback now.
*/
do_feedback = CCID3_FBACK_PARAM_CHANGE;
}

/*
Expand All @@ -823,6 +875,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
update_records:
tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);

done_receiving:
if (do_feedback)
ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
}
Expand All @@ -831,10 +884,8 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
{
struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);

ccid3_pr_debug("entry\n");

hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
tfrc_lh_init(&hcrx->ccid3hcrx_li_hist);
return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist);
}

Expand All @@ -844,11 +895,8 @@ static void ccid3_hc_rx_exit(struct sock *sk)

ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);

/* Empty packet history */
tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist);

/* Empty loss interval history */
dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
tfrc_lh_cleanup(&hcrx->ccid3hcrx_li_hist);
}

static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
Expand Down
10 changes: 5 additions & 5 deletions trunk/net/dccp/ccids/ccid3.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include <linux/list.h>
#include <linux/types.h>
#include <linux/tfrc.h>
#include "lib/packet_history.h"
#include "lib/tfrc.h"
#include "../ccid.h"

/* Two seconds as per RFC 3448 4.2 */
Expand Down Expand Up @@ -141,8 +141,8 @@ enum ccid3_hc_rx_states {
* @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes
* @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_hist - Packet history (loss detection + RTT sampling)
* @ccid3hcrx_li_hist - Loss Interval database
* @ccid3hcrx_s - Received packet size in bytes
* @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
*/
Expand All @@ -156,9 +156,9 @@ struct ccid3_hc_rx_sock {
u32 ccid3hcrx_bytes_recv;
ktime_t ccid3hcrx_tstamp_last_feedback;
struct tfrc_rx_hist ccid3hcrx_hist;
struct list_head ccid3hcrx_li_hist;
struct tfrc_loss_hist ccid3hcrx_li_hist;
u16 ccid3hcrx_s;
u32 ccid3hcrx_pinv;
#define ccid3hcrx_pinv ccid3hcrx_li_hist.i_mean
};

static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
Expand Down
18 changes: 9 additions & 9 deletions trunk/net/dccp/ccids/lib/loss_interval.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,18 +435,18 @@ int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
}
EXPORT_SYMBOL_GPL(tfrc_lh_interval_add);

int __init dccp_li_init(void)
int __init tfrc_li_init(void)
{
dccp_li_cachep = kmem_cache_create("dccp_li_hist",
sizeof(struct dccp_li_hist_entry),
0, SLAB_HWCACHE_ALIGN, NULL);
return dccp_li_cachep == NULL ? -ENOBUFS : 0;
tfrc_lh_slab = kmem_cache_create("tfrc_li_hist",
sizeof(struct tfrc_loss_interval), 0,
SLAB_HWCACHE_ALIGN, NULL);
return tfrc_lh_slab == NULL ? -ENOBUFS : 0;
}

void dccp_li_exit(void)
void tfrc_li_exit(void)
{
if (dccp_li_cachep != NULL) {
kmem_cache_destroy(dccp_li_cachep);
dccp_li_cachep = NULL;
if (tfrc_lh_slab != NULL) {
kmem_cache_destroy(tfrc_lh_slab);
tfrc_lh_slab = NULL;
}
}
10 changes: 5 additions & 5 deletions trunk/net/dccp/ccids/lib/tfrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ extern void tfrc_tx_packet_history_exit(void);
extern int tfrc_rx_packet_history_init(void);
extern void tfrc_rx_packet_history_exit(void);

extern int dccp_li_init(void);
extern void dccp_li_exit(void);
extern int tfrc_li_init(void);
extern void tfrc_li_exit(void);

static int __init tfrc_module_init(void)
{
int rc = dccp_li_init();
int rc = tfrc_li_init();

if (rc)
goto out;
Expand All @@ -41,7 +41,7 @@ static int __init tfrc_module_init(void)
out_free_tx_history:
tfrc_tx_packet_history_exit();
out_free_loss_intervals:
dccp_li_exit();
tfrc_li_exit();
out:
return rc;
}
Expand All @@ -50,7 +50,7 @@ static void __exit tfrc_module_exit(void)
{
tfrc_rx_packet_history_exit();
tfrc_tx_packet_history_exit();
dccp_li_exit();
tfrc_li_exit();
}

module_init(tfrc_module_init);
Expand Down
7 changes: 5 additions & 2 deletions trunk/net/dccp/dccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);

#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */

/* bounds for sampled RTT values from packet exchanges (in usec) */
/*
* RTT sampling: sanity bounds and fallback RTT value from RFC 4340, section 3.4
*/
#define DCCP_SANE_RTT_MIN 100
#define DCCP_SANE_RTT_MAX (4 * USEC_PER_SEC)
#define DCCP_FALLBACK_RTT (USEC_PER_SEC / 5)
#define DCCP_SANE_RTT_MAX (3 * USEC_PER_SEC)

/* Maximal interval between probes for local resources. */
#define DCCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ / 2U))
Expand Down

0 comments on commit ac9fc42

Please sign in to comment.