diff options
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 19 | ||||
| -rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 33 | ||||
| -rw-r--r-- | net/dccp/ccids/lib/packet_history.h | 17 |
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 | */ | ||
| 48 | struct 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 | */ |
| 45 | static struct kmem_cache *tfrc_tx_hist; | 57 | static struct kmem_cache *tfrc_tx_hist; |
| 46 | 58 | ||
| 47 | struct tfrc_tx_hist_entry * | 59 | static 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 | } |
| 55 | EXPORT_SYMBOL_GPL(tfrc_tx_hist_find_entry); | ||
| 56 | 67 | ||
| 57 | int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) | 68 | int 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 | } |
| 84 | EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge); | 95 | EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge); |
| 85 | 96 | ||
| 97 | u32 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 | } | ||
| 113 | EXPORT_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 | /** | 51 | struct 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 | */ | ||
| 57 | struct tfrc_tx_hist_entry { | ||
| 58 | struct tfrc_tx_hist_entry *next; | ||
| 59 | u64 seqno; | ||
| 60 | ktime_t stamp; | ||
| 61 | }; | ||
| 62 | 52 | ||
| 63 | extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); | 53 | extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); |
| 64 | extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); | 54 | extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); |
| 65 | 55 | extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, | |
| 66 | extern 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 |
