Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33618
b: refs/heads/master
c: 66a377c
h: refs/heads/master
v: v3
  • Loading branch information
Ian McDonald authored and David S. Miller committed Aug 27, 2006
1 parent 22e477c commit de12c28
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 194 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: 3a13813e6effcfad5910d47b15b724621b50b878
refs/heads/master: 66a377c5041e1e399633153c8b500d457281e7c1
149 changes: 119 additions & 30 deletions trunk/net/dccp/ccids/ccid3.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
new_packet->dccphtx_ccval =
DCCP_SKB_CB(skb)->dccpd_ccval =
hctx->ccid3hctx_last_win_count;
timeval_add_usecs(&hctx->ccid3hctx_t_nom,
hctx->ccid3hctx_t_ipi);
}
out:
return rc;
Expand Down Expand Up @@ -413,7 +415,8 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
case TFRC_SSTATE_NO_FBACK:
case TFRC_SSTATE_FBACK:
if (len > 0) {
hctx->ccid3hctx_t_nom = now;
timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
hctx->ccid3hctx_t_ipi);
ccid3_calc_new_t_ipi(hctx);
ccid3_calc_new_delta(hctx);
timeval_add_usecs(&hctx->ccid3hctx_t_nom,
Expand Down Expand Up @@ -757,8 +760,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
}

hcrx->ccid3hcrx_tstamp_last_feedback = now;
hcrx->ccid3hcrx_last_counter = packet->dccphrx_ccval;
hcrx->ccid3hcrx_seqno_last_counter = packet->dccphrx_seqno;
hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval;
hcrx->ccid3hcrx_bytes_recv = 0;

/* Convert to multiples of 10us */
Expand All @@ -782,7 +784,7 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
return 0;

DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;

if (dccp_packet_without_ack(skb))
return 0;
Expand Down Expand Up @@ -854,6 +856,11 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
interval = 1;
}
found:
if (!tail) {
LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n",
__FUNCTION__);
return ~0;
}
rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
dccp_role(sk), sk, rtt);
Expand All @@ -864,9 +871,20 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);

if (x_recv == 0)
x_recv = hcrx->ccid3hcrx_x_recv;

tmp1 = (u64)x_recv * (u64)rtt;
do_div(tmp1,10000000);
tmp2 = (u32)tmp1;

if (!tmp2) {
LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 "
"%s: x_recv = %u, rtt =%u\n",
__FUNCTION__, x_recv, rtt);
return ~0;
}

fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
/* do not alter order above or you will get overflow on 32 bit */
p = tfrc_calc_x_reverse_lookup(fval);
Expand All @@ -882,31 +900,101 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
{
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_li_hist_entry *next, *head;
u64 seq_temp;

if (seq_loss != DCCP_MAX_SEQNO + 1 &&
list_empty(&hcrx->ccid3hcrx_li_hist)) {
struct dccp_li_hist_entry *li_tail;
if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
if (!dccp_li_hist_interval_new(ccid3_li_hist,
&hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
return;

li_tail = dccp_li_hist_interval_new(ccid3_li_hist,
&hcrx->ccid3hcrx_li_hist,
seq_loss, win_loss);
if (li_tail == NULL)
next = (struct dccp_li_hist_entry *)
hcrx->ccid3hcrx_li_hist.next;
next->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
} else {
struct dccp_li_hist_entry *entry;
struct list_head *tail;

head = (struct dccp_li_hist_entry *)
hcrx->ccid3hcrx_li_hist.next;
/* FIXME win count check removed as was wrong */
/* should make this check with receive history */
/* and compare there as per section 10.2 of RFC4342 */

/* new loss event detected */
/* calculate last interval length */
seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC);

if (entry == NULL) {
printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__);
dump_stack();
return;
li_tail->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
} else
LIMIT_NETDEBUG(KERN_WARNING "%s: FIXME: find end of "
"interval\n", __FUNCTION__);
}

list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);

tail = hcrx->ccid3hcrx_li_hist.prev;
list_del(tail);
kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);

/* Create the newest interval */
entry->dccplih_seqno = seq_loss;
entry->dccplih_interval = seq_temp;
entry->dccplih_win_count = win_loss;
}
}

static void ccid3_hc_rx_detect_loss(struct sock *sk)
static int ccid3_hc_rx_detect_loss(struct sock *sk,
struct dccp_rx_hist_entry *packet)
{
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u8 win_loss;
const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist,
&win_loss);
struct dccp_rx_hist_entry *rx_hist = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
u64 seqno = packet->dccphrx_seqno;
u64 tmp_seqno;
int loss = 0;
u8 ccval;


tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;

if (!rx_hist ||
follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
hcrx->ccid3hcrx_seqno_nonloss = seqno;
hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
goto detect_out;
}


ccid3_hc_rx_update_li(sk, seq_loss, win_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);
tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
dccp_inc_seqno(&tmp_seqno);
hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
dccp_inc_seqno(&tmp_seqno);
while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist,
tmp_seqno, &ccval)) {
hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
hcrx->ccid3hcrx_ccval_nonloss = ccval;
dccp_inc_seqno(&tmp_seqno);
}
}

/* FIXME - this code could be simplified with above while */
/* but works at moment */
if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
hcrx->ccid3hcrx_seqno_nonloss = seqno;
hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
}

detect_out:
dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist, packet,
hcrx->ccid3hcrx_seqno_nonloss);
return loss;
}

static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
Expand All @@ -916,8 +1004,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
struct dccp_rx_hist_entry *packet;
struct timeval now;
u8 win_count;
u32 p_prev, r_sample, t_elapsed;
int ins;
u32 p_prev, rtt_prev, r_sample, t_elapsed;
int loss;

BUG_ON(hcrx == NULL ||
!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
Expand All @@ -932,7 +1020,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
case DCCP_PKT_DATAACK:
if (opt_recv->dccpor_timestamp_echo == 0)
break;
p_prev = hcrx->ccid3hcrx_rtt;
rtt_prev = hcrx->ccid3hcrx_rtt;
dccp_timestamp(sk, &now);
timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
r_sample = timeval_usecs(&now);
Expand All @@ -951,8 +1039,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
r_sample / 10;

if (p_prev != hcrx->ccid3hcrx_rtt)
ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
if (rtt_prev != hcrx->ccid3hcrx_rtt)
ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n",
dccp_role(sk), hcrx->ccid3hcrx_rtt,
opt_recv->dccpor_elapsed_time);
break;
Expand All @@ -973,8 +1061,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)

win_count = packet->dccphrx_ccval;

ins = dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist, packet);
loss = ccid3_hc_rx_detect_loss(sk, packet);

if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
return;
Expand All @@ -991,7 +1078,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
case TFRC_RSTATE_DATA:
hcrx->ccid3hcrx_bytes_recv += skb->len -
dccp_hdr(skb)->dccph_doff * 4;
if (ins != 0)
if (loss)
break;

dccp_timestamp(sk, &now);
Expand All @@ -1012,7 +1099,6 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
dccp_role(sk), sk, dccp_state_name(sk->sk_state));

ccid3_hc_rx_detect_loss(sk);
p_prev = hcrx->ccid3hcrx_p;

/* Calculate loss event rate */
Expand All @@ -1022,6 +1108,9 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
/* Scaling up by 1000000 as fixed decimal */
if (i_mean != 0)
hcrx->ccid3hcrx_p = 1000000 / i_mean;
} else {
printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__);
dump_stack();
}

if (hcrx->ccid3hcrx_p > p_prev) {
Expand Down
5 changes: 3 additions & 2 deletions trunk/net/dccp/ccids/ccid3.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,10 @@ struct ccid3_hc_rx_sock {
#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_last_counter:48,
u64 ccid3hcrx_seqno_nonloss:48,
ccid3hcrx_ccval_nonloss:4,
ccid3hcrx_state:8,
ccid3hcrx_last_counter:4;
ccid3hcrx_ccval_last_counter:4;
u32 ccid3hcrx_bytes_recv;
struct timeval ccid3hcrx_tstamp_last_feedback;
struct timeval ccid3hcrx_tstamp_last_ack;
Expand Down
34 changes: 17 additions & 17 deletions trunk/net/dccp/ccids/lib/loss_interval.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include <linux/module.h>
#include <net/sock.h>

#include "loss_interval.h"

Expand Down Expand Up @@ -90,13 +91,13 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
u32 w_tot = 0;

list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) {
if (i < DCCP_LI_HIST_IVAL_F_LENGTH) {
if (li_entry->dccplih_interval != ~0) {
i_tot0 += li_entry->dccplih_interval * dccp_li_hist_w[i];
w_tot += dccp_li_hist_w[i];
if (i != 0)
i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1];
}

if (i != 0)
i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1];

if (++i > DCCP_LI_HIST_IVAL_F_LENGTH)
break;
Expand All @@ -107,37 +108,36 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)

i_tot = max(i_tot0, i_tot1);

/* FIXME: Why do we do this? -Ian McDonald */
if (i_tot * 4 < w_tot)
i_tot = w_tot * 4;
if (!w_tot) {
LIMIT_NETDEBUG(KERN_WARNING "%s: w_tot = 0\n", __FUNCTION__);
return 1;
}

return i_tot * 4 / w_tot;
return i_tot / w_tot;
}

EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);

struct dccp_li_hist_entry *dccp_li_hist_interval_new(struct dccp_li_hist *hist,
struct list_head *list,
const u64 seq_loss,
const u8 win_loss)
int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
struct list_head *list, const u64 seq_loss, const u8 win_loss)
{
struct dccp_li_hist_entry *tail = NULL, *entry;
struct dccp_li_hist_entry *entry;
int i;

for (i = 0; i <= DCCP_LI_HIST_IVAL_F_LENGTH; ++i) {
for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC);
if (entry == NULL) {
dccp_li_hist_purge(hist, list);
return NULL;
dump_stack();
return 0;
}
if (tail == NULL)
tail = entry;
entry->dccplih_interval = ~0;
list_add(&entry->dccplih_node, list);
}

entry->dccplih_seqno = seq_loss;
entry->dccplih_win_count = win_loss;
return tail;
return 1;
}

EXPORT_SYMBOL_GPL(dccp_li_hist_interval_new);
7 changes: 2 additions & 5 deletions trunk/net/dccp/ccids/lib/loss_interval.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ extern void dccp_li_hist_purge(struct dccp_li_hist *hist,

extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);

extern struct dccp_li_hist_entry *
dccp_li_hist_interval_new(struct dccp_li_hist *hist,
struct list_head *list,
const u64 seq_loss,
const u8 win_loss);
extern int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
struct list_head *list, const u64 seq_loss, const u8 win_loss);
#endif /* _DCCP_LI_HIST_ */
Loading

0 comments on commit de12c28

Please sign in to comment.