aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ccids
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:30:19 -0400
committerGerrit Renker <gerrit@erg.abdn.ac.uk>2008-09-04 01:45:34 -0400
commit63b3a73bb85daf441f964aaf9b3fc89be4209c23 (patch)
tree6ac875b3971ff8299106ca6b878fc56d5cd77e84 /net/dccp/ccids
parentde6f2b59e5cd15a8772adb732a1d80e141a77115 (diff)
dccp ccid-3: Remove ugly RTT-sampling history lookup
This removes the RTT-sampling function tfrc_tx_hist_rtt(), since 1. it suffered from complex passing of return values (the return value both indicated successful lookup while the value doubled as RTT sample); 2. when for some odd reason the sample value equalled 0, this triggered a bug warning about "bogus Ack", due to the ambiguity of the return value; 3. on a passive host which has not sent anything the TX history is empty and thus will lead to unwanted "bogus Ack" warnings such as ccid3_hc_tx_packet_recv: server(e7b7d518): DATAACK with bogus ACK-28197148 ccid3_hc_tx_packet_recv: server(e7b7d518): DATAACK with bogus ACK-26641606. The fix is to replace the implicit encoding by performing the steps manually. Furthermore, the "bogus Ack" warning has been removed, since it can actually be triggered due to several reasons (network reordering, old packet, (3) above), hence it is not very useful. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Diffstat (limited to 'net/dccp/ccids')
-rw-r--r--net/dccp/ccids/ccid3.c34
-rw-r--r--net/dccp/ccids/lib/packet_history.c40
-rw-r--r--net/dccp/ccids/lib/packet_history.h22
3 files changed, 38 insertions, 58 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index eb1bda08eeb2..f74e58d9793f 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -371,6 +371,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
371{ 371{
372 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 372 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
373 struct ccid3_options_received *opt_recv = &hctx->options_received; 373 struct ccid3_options_received *opt_recv = &hctx->options_received;
374 struct tfrc_tx_hist_entry *acked;
374 ktime_t now; 375 ktime_t now;
375 unsigned long t_nfb; 376 unsigned long t_nfb;
376 u32 pinv, r_sample; 377 u32 pinv, r_sample;
@@ -384,17 +385,24 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
384 hctx->state != TFRC_SSTATE_NO_FBACK) 385 hctx->state != TFRC_SSTATE_NO_FBACK)
385 return; 386 return;
386 387
387 now = ktime_get_real(); 388 /*
388 389 * Locate the acknowledged packet in the TX history.
389 /* Estimate RTT from history if ACK number is valid */ 390 *
390 r_sample = tfrc_tx_hist_rtt(hctx->hist, 391 * Returning "entry not found" here can for instance happen when
391 DCCP_SKB_CB(skb)->dccpd_ack_seq, now); 392 * - the host has not sent out anything (e.g. a passive server),
392 if (r_sample == 0) { 393 * - the Ack is outdated (packet with higher Ack number was received),
393 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, 394 * - it is a bogus Ack (for a packet not sent on this connection).
394 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), 395 */
395 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); 396 acked = tfrc_tx_hist_find_entry(hctx->hist, dccp_hdr_ack_seq(skb));
397 if (acked == NULL)
396 return; 398 return;
397 } 399 /* For the sake of RTT sampling, ignore/remove all older entries */
400 tfrc_tx_hist_purge(&acked->next);
401
402 /* Update the moving average for the RTT estimate (RFC 3448, 4.3) */
403 now = ktime_get_real();
404 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
405 hctx->rtt = tfrc_ewma(hctx->rtt, r_sample, 9);
398 406
399 /* Update receive rate in units of 64 * bytes/second */ 407 /* Update receive rate in units of 64 * bytes/second */
400 hctx->x_recv = opt_recv->ccid3or_receive_rate; 408 hctx->x_recv = opt_recv->ccid3or_receive_rate;
@@ -406,11 +414,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
406 hctx->p = 0; 414 hctx->p = 0;
407 else /* can not exceed 100% */ 415 else /* can not exceed 100% */
408 hctx->p = scaled_div(1, pinv); 416 hctx->p = scaled_div(1, pinv);
409 /* 417
410 * Validate new RTT sample and update moving average
411 */
412 r_sample = dccp_sample_rtt(sk, r_sample);
413 hctx->rtt = tfrc_ewma(hctx->rtt, r_sample, 9);
414 /* 418 /*
415 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 419 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
416 */ 420 */
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 6cc108afdc3b..5c4450866904 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -40,18 +40,6 @@
40#include "packet_history.h" 40#include "packet_history.h"
41#include "../../dccp.h" 41#include "../../dccp.h"
42 42
43/**
44 * tfrc_tx_hist_entry - Simple singly-linked TX history list
45 * @next: next oldest entry (LIFO order)
46 * @seqno: sequence number of this entry
47 * @stamp: send time of packet with sequence number @seqno
48 */
49struct tfrc_tx_hist_entry {
50 struct tfrc_tx_hist_entry *next;
51 u64 seqno;
52 ktime_t stamp;
53};
54
55/* 43/*
56 * Transmitter History Routines 44 * Transmitter History Routines
57 */ 45 */
@@ -73,15 +61,6 @@ void tfrc_tx_packet_history_exit(void)
73 } 61 }
74} 62}
75 63
76static struct tfrc_tx_hist_entry *
77 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
78{
79 while (head != NULL && head->seqno != seqno)
80 head = head->next;
81
82 return head;
83}
84
85int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) 64int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno)
86{ 65{
87 struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any()); 66 struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any());
@@ -111,25 +90,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
111} 90}
112EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge); 91EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge);
113 92
114u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
115 const ktime_t now)
116{
117 u32 rtt = 0;
118 struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno);
119
120 if (packet != NULL) {
121 rtt = ktime_us_delta(now, packet->stamp);
122 /*
123 * Garbage-collect older (irrelevant) entries:
124 */
125 tfrc_tx_hist_purge(&packet->next);
126 }
127
128 return rtt;
129}
130EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt);
131
132
133/* 93/*
134 * Receiver History Routines 94 * Receiver History Routines
135 */ 95 */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 461cc91cce88..221d8102da51 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -40,12 +40,28 @@
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include "tfrc.h" 41#include "tfrc.h"
42 42
43struct tfrc_tx_hist_entry; 43/**
44 * tfrc_tx_hist_entry - Simple singly-linked TX history list
45 * @next: next oldest entry (LIFO order)
46 * @seqno: sequence number of this entry
47 * @stamp: send time of packet with sequence number @seqno
48 */
49struct tfrc_tx_hist_entry {
50 struct tfrc_tx_hist_entry *next;
51 u64 seqno;
52 ktime_t stamp;
53};
54
55static inline struct tfrc_tx_hist_entry *
56 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
57{
58 while (head != NULL && head->seqno != seqno)
59 head = head->next;
60 return head;
61}
44 62
45extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); 63extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
46extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); 64extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
47extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head,
48 const u64 seqno, const ktime_t now);
49 65
50/* Subtraction a-b modulo-16, respects circular wrap-around */ 66/* Subtraction a-b modulo-16, respects circular wrap-around */
51#define SUB16(a, b) (((a) + 16 - (b)) & 0xF) 67#define SUB16(a, b) (((a) + 16 - (b)) & 0xF)