aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/ccids/ccid3.c19
-rw-r--r--net/dccp/ccids/lib/packet_history.c33
-rw-r--r--net/dccp/ccids/lib/packet_history.h17
3 files changed, 41 insertions, 28 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index f73542ab9d08..49338370eb04 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -399,7 +399,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
399{ 399{
400 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 400 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
401 struct ccid3_options_received *opt_recv; 401 struct ccid3_options_received *opt_recv;
402 struct tfrc_tx_hist_entry *packet;
403 ktime_t now; 402 ktime_t now;
404 unsigned long t_nfb; 403 unsigned long t_nfb;
405 u32 pinv, r_sample; 404 u32 pinv, r_sample;
@@ -414,19 +413,17 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
414 switch (hctx->ccid3hctx_state) { 413 switch (hctx->ccid3hctx_state) {
415 case TFRC_SSTATE_NO_FBACK: 414 case TFRC_SSTATE_NO_FBACK:
416 case TFRC_SSTATE_FBACK: 415 case TFRC_SSTATE_FBACK:
416 now = ktime_get_real();
417
417 /* estimate RTT from history if ACK number is valid */ 418 /* estimate RTT from history if ACK number is valid */
418 packet = tfrc_tx_hist_find_entry(hctx->ccid3hctx_hist, 419 r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist,
419 DCCP_SKB_CB(skb)->dccpd_ack_seq); 420 DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
420 if (packet == NULL) { 421 if (r_sample == 0) {
421 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, 422 DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
422 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), 423 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type),
423 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); 424 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq);
424 return; 425 return;
425 } 426 }
426 /*
427 * Garbage-collect older (irrelevant) entries
428 */
429 tfrc_tx_hist_purge(&packet->next);
430 427
431 /* Update receive rate in units of 64 * bytes/second */ 428 /* Update receive rate in units of 64 * bytes/second */
432 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate; 429 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
@@ -438,12 +435,10 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
438 hctx->ccid3hctx_p = 0; 435 hctx->ccid3hctx_p = 0;
439 else /* can not exceed 100% */ 436 else /* can not exceed 100% */
440 hctx->ccid3hctx_p = 1000000 / pinv; 437 hctx->ccid3hctx_p = 1000000 / pinv;
441
442 now = ktime_get_real();
443 /* 438 /*
444 * Calculate new RTT sample and update moving average 439 * Validate new RTT sample and update moving average
445 */ 440 */
446 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->stamp)); 441 r_sample = dccp_sample_rtt(sk, r_sample);
447 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); 442 hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
448 443
449 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 444 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 139736064713..4805de996568 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -39,12 +39,24 @@
39#include <linux/string.h> 39#include <linux/string.h>
40#include "packet_history.h" 40#include "packet_history.h"
41 41
42/**
43 * tfrc_tx_hist_entry - Simple singly-linked TX history list
44 * @next: next oldest entry (LIFO order)
45 * @seqno: sequence number of this entry
46 * @stamp: send time of packet with sequence number @seqno
47 */
48struct tfrc_tx_hist_entry {
49 struct tfrc_tx_hist_entry *next;
50 u64 seqno;
51 ktime_t stamp;
52};
53
42/* 54/*
43 * Transmitter History Routines 55 * Transmitter History Routines
44 */ 56 */
45static struct kmem_cache *tfrc_tx_hist; 57static struct kmem_cache *tfrc_tx_hist;
46 58
47struct tfrc_tx_hist_entry * 59static struct tfrc_tx_hist_entry *
48 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) 60 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
49{ 61{
50 while (head != NULL && head->seqno != seqno) 62 while (head != NULL && head->seqno != seqno)
@@ -52,7 +64,6 @@ struct tfrc_tx_hist_entry *
52 64
53 return head; 65 return head;
54} 66}
55EXPORT_SYMBOL_GPL(tfrc_tx_hist_find_entry);
56 67
57int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) 68int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno)
58{ 69{
@@ -83,6 +94,24 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
83} 94}
84EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge); 95EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge);
85 96
97u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
98 const ktime_t now)
99{
100 u32 rtt = 0;
101 struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno);
102
103 if (packet != NULL) {
104 rtt = ktime_us_delta(now, packet->stamp);
105 /*
106 * Garbage-collect older (irrelevant) entries:
107 */
108 tfrc_tx_hist_purge(&packet->next);
109 }
110
111 return rtt;
112}
113EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt);
114
86/* 115/*
87 * Receiver History Routines 116 * Receiver History Routines
88 */ 117 */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 5c07182dd659..0670f46dd53c 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -48,23 +48,12 @@
48#define TFRC_WIN_COUNT_PER_RTT 4 48#define TFRC_WIN_COUNT_PER_RTT 4
49#define TFRC_WIN_COUNT_LIMIT 16 49#define TFRC_WIN_COUNT_LIMIT 16
50 50
51/** 51struct tfrc_tx_hist_entry;
52 * tfrc_tx_hist_entry - Simple singly-linked TX history list
53 * @next: next oldest entry (LIFO order)
54 * @seqno: sequence number of this entry
55 * @stamp: send time of packet with sequence number @seqno
56 */
57struct tfrc_tx_hist_entry {
58 struct tfrc_tx_hist_entry *next;
59 u64 seqno;
60 ktime_t stamp;
61};
62 52
63extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); 53extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
64extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); 54extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
65 55extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head,
66extern struct tfrc_tx_hist_entry * 56 const u64 seqno, const ktime_t now);
67 tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 ackno);
68 57
69/* 58/*
70 * Receiver History data structures and declarations 59 * Receiver History data structures and declarations