aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccids/ccid3.c34
-rw-r--r--net/dccp/ccids/lib/packet_history.c39
-rw-r--r--net/dccp/ccids/lib/packet_history.h22
3 files changed, 38 insertions, 57 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index e9ca0983ac58..b2ddd205d438 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -370,6 +370,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
370{ 370{
371 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); 371 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
372 struct ccid3_options_received *opt_recv = &hc->tx_options_received; 372 struct ccid3_options_received *opt_recv = &hc->tx_options_received;
373 struct tfrc_tx_hist_entry *acked;
373 ktime_t now; 374 ktime_t now;
374 unsigned long t_nfb; 375 unsigned long t_nfb;
375 u32 pinv, r_sample; 376 u32 pinv, r_sample;
@@ -383,17 +384,24 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
383 hc->tx_state != TFRC_SSTATE_NO_FBACK) 384 hc->tx_state != TFRC_SSTATE_NO_FBACK)
384 return; 385 return;
385 386
386 now = ktime_get_real(); 387 /*
387 388 * Locate the acknowledged packet in the TX history.
388 /* Estimate RTT from history if ACK number is valid */ 389 *
389 r_sample = tfrc_tx_hist_rtt(hc->tx_hist, 390 * Returning "entry not found" here can for instance happen when
390 DCCP_SKB_CB(skb)->dccpd_ack_seq, now); 391 * - the host has not sent out anything (e.g. a passive server),
391 if (r_sample == 0) { 392 * - the Ack is outdated (packet with higher Ack number was received),
392 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, 393 * - it is a bogus Ack (for a packet not sent on this connection).
393 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), 394 */
394 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); 395 acked = tfrc_tx_hist_find_entry(hc->tx_hist, dccp_hdr_ack_seq(skb));
396 if (acked == NULL)
395 return; 397 return;
396 } 398 /* For the sake of RTT sampling, ignore/remove all older entries */
399 tfrc_tx_hist_purge(&acked->next);
400
401 /* Update the moving average for the RTT estimate (RFC 3448, 4.3) */
402 now = ktime_get_real();
403 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
404 hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
397 405
398 /* Update receive rate in units of 64 * bytes/second */ 406 /* Update receive rate in units of 64 * bytes/second */
399 hc->tx_x_recv = opt_recv->ccid3or_receive_rate; 407 hc->tx_x_recv = opt_recv->ccid3or_receive_rate;
@@ -405,11 +413,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
405 hc->tx_p = 0; 413 hc->tx_p = 0;
406 else /* can not exceed 100% */ 414 else /* can not exceed 100% */
407 hc->tx_p = scaled_div(1, pinv); 415 hc->tx_p = scaled_div(1, pinv);
408 /* 416
409 * Validate new RTT sample and update moving average
410 */
411 r_sample = dccp_sample_rtt(sk, r_sample);
412 hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
413 /* 417 /*
414 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 418 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
415 */ 419 */
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 3a4f414e94a0..de8fe294bf0b 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -38,18 +38,6 @@
38#include "packet_history.h" 38#include "packet_history.h"
39#include "../../dccp.h" 39#include "../../dccp.h"
40 40
41/**
42 * tfrc_tx_hist_entry - Simple singly-linked TX history list
43 * @next: next oldest entry (LIFO order)
44 * @seqno: sequence number of this entry
45 * @stamp: send time of packet with sequence number @seqno
46 */
47struct tfrc_tx_hist_entry {
48 struct tfrc_tx_hist_entry *next;
49 u64 seqno;
50 ktime_t stamp;
51};
52
53/* 41/*
54 * Transmitter History Routines 42 * Transmitter History Routines
55 */ 43 */
@@ -71,15 +59,6 @@ void tfrc_tx_packet_history_exit(void)
71 } 59 }
72} 60}
73 61
74static struct tfrc_tx_hist_entry *
75 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
76{
77 while (head != NULL && head->seqno != seqno)
78 head = head->next;
79
80 return head;
81}
82
83int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) 62int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno)
84{ 63{
85 struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any()); 64 struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any());
@@ -107,24 +86,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
107 *headp = NULL; 86 *headp = NULL;
108} 87}
109 88
110u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
111 const ktime_t now)
112{
113 u32 rtt = 0;
114 struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno);
115
116 if (packet != NULL) {
117 rtt = ktime_us_delta(now, packet->stamp);
118 /*
119 * Garbage-collect older (irrelevant) entries:
120 */
121 tfrc_tx_hist_purge(&packet->next);
122 }
123
124 return rtt;
125}
126
127
128/* 89/*
129 * Receiver History Routines 90 * Receiver History Routines
130 */ 91 */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 7df6c5299999..7ee4a9d9d335 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)