diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2007-11-28 08:15:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:55:11 -0500 |
commit | 276f2edc52e309b38a216245952e05880e182c83 (patch) | |
tree | 3f581eb831a6f7f16ab30bd0f8e8d80b5b97fe50 /net/dccp/ccids/ccid3.c | |
parent | ea4f76ae13b4240dac304ed50636391d6b22e9c5 (diff) |
[TFRC]: Migrate TX history to singly-linked lis
This patch was based on another made by Gerrit Renker, his changelog was:
------------------------------------------------------
The patch set migrates TFRC TX history to a singly-linked list.
The details are:
* use of a consistent naming scheme (all TFRC functions now begin with `tfrc_');
* allocation and cleanup are taken care of internally;
* provision of a lookup function, which is used by the CCID TX infrastructure
to determine the time a packet was sent (in turn used for RTT sampling);
* integration of the new interface with the present use in CCID3.
------------------------------------------------------
Simplifications I did:
. removing the tfrc_tx_hist_head that had a pointer to the list head and
another for the slabcache.
. No need for creating a slabcache for each CCID that wants to use the TFRC
tx history routines, create a single slabcache when the dccp_tfrc_lib module
init routine is called.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/ccids/ccid3.c')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 57 |
1 files changed, 17 insertions, 40 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 42893b1dfa09..f73542ab9d08 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -49,7 +49,6 @@ static int ccid3_debug; | |||
49 | #define ccid3_pr_debug(format, a...) | 49 | #define ccid3_pr_debug(format, a...) |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | static struct dccp_tx_hist *ccid3_tx_hist; | ||
53 | static struct dccp_rx_hist *ccid3_rx_hist; | 52 | static struct dccp_rx_hist *ccid3_rx_hist; |
54 | 53 | ||
55 | /* | 54 | /* |
@@ -389,28 +388,18 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, | |||
389 | unsigned int len) | 388 | unsigned int len) |
390 | { | 389 | { |
391 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 390 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
392 | struct dccp_tx_hist_entry *packet; | ||
393 | 391 | ||
394 | ccid3_hc_tx_update_s(hctx, len); | 392 | ccid3_hc_tx_update_s(hctx, len); |
395 | 393 | ||
396 | packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC); | 394 | if (tfrc_tx_hist_add(&hctx->ccid3hctx_hist, dccp_sk(sk)->dccps_gss)) |
397 | if (unlikely(packet == NULL)) { | ||
398 | DCCP_CRIT("packet history - out of memory!"); | 395 | DCCP_CRIT("packet history - out of memory!"); |
399 | return; | ||
400 | } | ||
401 | dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet); | ||
402 | |||
403 | packet->dccphtx_tstamp = ktime_get_real(); | ||
404 | packet->dccphtx_seqno = dccp_sk(sk)->dccps_gss; | ||
405 | packet->dccphtx_rtt = hctx->ccid3hctx_rtt; | ||
406 | packet->dccphtx_sent = 1; | ||
407 | } | 396 | } |
408 | 397 | ||
409 | static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | 398 | static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) |
410 | { | 399 | { |
411 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); | 400 | struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); |
412 | struct ccid3_options_received *opt_recv; | 401 | struct ccid3_options_received *opt_recv; |
413 | struct dccp_tx_hist_entry *packet; | 402 | struct tfrc_tx_hist_entry *packet; |
414 | ktime_t now; | 403 | ktime_t now; |
415 | unsigned long t_nfb; | 404 | unsigned long t_nfb; |
416 | u32 pinv, r_sample; | 405 | u32 pinv, r_sample; |
@@ -425,16 +414,19 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
425 | switch (hctx->ccid3hctx_state) { | 414 | switch (hctx->ccid3hctx_state) { |
426 | case TFRC_SSTATE_NO_FBACK: | 415 | case TFRC_SSTATE_NO_FBACK: |
427 | case TFRC_SSTATE_FBACK: | 416 | case TFRC_SSTATE_FBACK: |
428 | /* get packet from history to look up t_recvdata */ | 417 | /* estimate RTT from history if ACK number is valid */ |
429 | packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, | 418 | packet = tfrc_tx_hist_find_entry(hctx->ccid3hctx_hist, |
430 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 419 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
431 | if (unlikely(packet == NULL)) { | 420 | if (packet == NULL) { |
432 | DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist " | 421 | DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, |
433 | "in history!\n", dccp_role(sk), sk, | 422 | dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), |
434 | (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, | 423 | (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); |
435 | dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); | ||
436 | return; | 424 | return; |
437 | } | 425 | } |
426 | /* | ||
427 | * Garbage-collect older (irrelevant) entries | ||
428 | */ | ||
429 | tfrc_tx_hist_purge(&packet->next); | ||
438 | 430 | ||
439 | /* Update receive rate in units of 64 * bytes/second */ | 431 | /* Update receive rate in units of 64 * bytes/second */ |
440 | hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate; | 432 | hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate; |
@@ -451,7 +443,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
451 | /* | 443 | /* |
452 | * Calculate new RTT sample and update moving average | 444 | * Calculate new RTT sample and update moving average |
453 | */ | 445 | */ |
454 | r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->dccphtx_tstamp)); | 446 | r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->stamp)); |
455 | hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); | 447 | hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9); |
456 | 448 | ||
457 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { | 449 | if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { |
@@ -493,9 +485,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) | |||
493 | /* unschedule no feedback timer */ | 485 | /* unschedule no feedback timer */ |
494 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); | 486 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); |
495 | 487 | ||
496 | /* remove all packets older than the one acked from history */ | ||
497 | dccp_tx_hist_purge_older(ccid3_tx_hist, | ||
498 | &hctx->ccid3hctx_hist, packet); | ||
499 | /* | 488 | /* |
500 | * As we have calculated new ipi, delta, t_nom it is possible | 489 | * As we have calculated new ipi, delta, t_nom it is possible |
501 | * that we now can send a packet, so wake up dccp_wait_for_ccid | 490 | * that we now can send a packet, so wake up dccp_wait_for_ccid |
@@ -598,7 +587,7 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) | |||
598 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); | 587 | struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); |
599 | 588 | ||
600 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; | 589 | hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; |
601 | INIT_LIST_HEAD(&hctx->ccid3hctx_hist); | 590 | hctx->ccid3hctx_hist = NULL; |
602 | setup_timer(&hctx->ccid3hctx_no_feedback_timer, | 591 | setup_timer(&hctx->ccid3hctx_no_feedback_timer, |
603 | ccid3_hc_tx_no_feedback_timer, (unsigned long)sk); | 592 | ccid3_hc_tx_no_feedback_timer, (unsigned long)sk); |
604 | 593 | ||
@@ -612,8 +601,7 @@ static void ccid3_hc_tx_exit(struct sock *sk) | |||
612 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); | 601 | ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); |
613 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); | 602 | sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); |
614 | 603 | ||
615 | /* Empty packet history */ | 604 | tfrc_tx_hist_purge(&hctx->ccid3hctx_hist); |
616 | dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist); | ||
617 | } | 605 | } |
618 | 606 | ||
619 | static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) | 607 | static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) |
@@ -1036,19 +1024,12 @@ static __init int ccid3_module_init(void) | |||
1036 | if (ccid3_rx_hist == NULL) | 1024 | if (ccid3_rx_hist == NULL) |
1037 | goto out; | 1025 | goto out; |
1038 | 1026 | ||
1039 | ccid3_tx_hist = dccp_tx_hist_new("ccid3"); | ||
1040 | if (ccid3_tx_hist == NULL) | ||
1041 | goto out_free_rx; | ||
1042 | |||
1043 | rc = ccid_register(&ccid3); | 1027 | rc = ccid_register(&ccid3); |
1044 | if (rc != 0) | 1028 | if (rc != 0) |
1045 | goto out_free_tx; | 1029 | goto out_free_rx; |
1046 | out: | 1030 | out: |
1047 | return rc; | 1031 | return rc; |
1048 | 1032 | ||
1049 | out_free_tx: | ||
1050 | dccp_tx_hist_delete(ccid3_tx_hist); | ||
1051 | ccid3_tx_hist = NULL; | ||
1052 | out_free_rx: | 1033 | out_free_rx: |
1053 | dccp_rx_hist_delete(ccid3_rx_hist); | 1034 | dccp_rx_hist_delete(ccid3_rx_hist); |
1054 | ccid3_rx_hist = NULL; | 1035 | ccid3_rx_hist = NULL; |
@@ -1060,10 +1041,6 @@ static __exit void ccid3_module_exit(void) | |||
1060 | { | 1041 | { |
1061 | ccid_unregister(&ccid3); | 1042 | ccid_unregister(&ccid3); |
1062 | 1043 | ||
1063 | if (ccid3_tx_hist != NULL) { | ||
1064 | dccp_tx_hist_delete(ccid3_tx_hist); | ||
1065 | ccid3_tx_hist = NULL; | ||
1066 | } | ||
1067 | if (ccid3_rx_hist != NULL) { | 1044 | if (ccid3_rx_hist != NULL) { |
1068 | dccp_rx_hist_delete(ccid3_rx_hist); | 1045 | dccp_rx_hist_delete(ccid3_rx_hist); |
1069 | ccid3_rx_hist = NULL; | 1046 | ccid3_rx_hist = NULL; |