Date: Wed, 1 Jul 2009 13:30:01 +0000 (UTC) From: Lawrence Stewart <lstewart@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195239 - projects/tcp_cc_8.x/sys/netinet Message-ID: <200907011330.n61DU1Vk013941@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: lstewart Date: Wed Jul 1 13:30:01 2009 New Revision: 195239 URL: http://svn.freebsd.org/changeset/base/195239 Log: Create a set of CC related hook function wrappers around the algorithm specific hook function calls. These wrappers provide a place to do various asserts and place code that is algorithm agnostic. There is scope to move more code into some of these wrappers than has been done so far. It may also be beneficial to optimise for the case where the system default algorithm is in use for the connection and there are no other algorithms available e.g. don't indirect through the tcpcb and call the default algorithm's function directly. Not sure what savings could be made if any, but probably worth exploring. Modified: projects/tcp_cc_8.x/sys/netinet/cc.c projects/tcp_cc_8.x/sys/netinet/tcp_input.c projects/tcp_cc_8.x/sys/netinet/tcp_output.c projects/tcp_cc_8.x/sys/netinet/tcp_timer.c Modified: projects/tcp_cc_8.x/sys/netinet/cc.c ============================================================================== --- projects/tcp_cc_8.x/sys/netinet/cc.c Wed Jul 1 13:22:08 2009 (r195238) +++ projects/tcp_cc_8.x/sys/netinet/cc.c Wed Jul 1 13:30:01 2009 (r195239) @@ -204,6 +204,12 @@ cc_deregister_algo(struct cc_algo *remov * Check all active control blocks and change any that are * using this algorithm back to newreno. If the algorithm that * was in use requires cleanup code to be run, call it. + * + * New connections already part way through being initialised + * with the CC algo we're removing will not race with this code + * because the INP_INFO_WLOCK is held during initialisation. + * We therefore don't enter the loop below until the connection + * list has stabilised. */ INP_INFO_RLOCK(&V_tcbinfo); LIST_FOREACH(inp, &V_tcb, inp_list) { Modified: projects/tcp_cc_8.x/sys/netinet/tcp_input.c ============================================================================== --- projects/tcp_cc_8.x/sys/netinet/tcp_input.c Wed Jul 1 13:22:08 2009 (r195238) +++ projects/tcp_cc_8.x/sys/netinet/tcp_input.c Wed Jul 1 13:30:01 2009 (r195239) @@ -214,6 +214,59 @@ static void tcp_pulloutofband(struct so struct tcphdr *, struct mbuf *, int); static void tcp_xmit_timer(struct tcpcb *, int); static void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *); +static void inline cc_ack_received(struct tcpcb *tp, struct tcphdr *th); +static void inline cc_cwnd_init(struct tcpcb *tp); +static void inline cc_pre_fr(struct tcpcb *tp, struct tcphdr *th); +static void inline cc_post_fr(struct tcpcb *tp, struct tcphdr *th); + +/* + * CC wrapper hook functions + */ +static void inline +cc_ack_received(struct tcpcb *tp, struct tcphdr *th) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + if (!IN_FASTRECOVERY(tp) && CC_ALGO(tp)->ack_received != NULL) + CC_ALGO(tp)->ack_received(tp, th); +} + +static void inline +cc_cwnd_init(struct tcpcb *tp) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + /* + * XXXLS: Should rename this hook and do + * ssthresh init in there as well + */ + + if (CC_ALGO(tp)->cwnd_init != NULL) + CC_ALGO(tp)->cwnd_init(tp); +} + +static void inline +cc_pre_fr(struct tcpcb *tp, struct tcphdr *th) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + if (CC_ALGO(tp)->pre_fr != NULL) + CC_ALGO(tp)->pre_fr(tp, th); + + ENTER_FASTRECOVERY(tp); + tp->snd_recover = tp->snd_max; + if (tp->t_flags & TF_ECN_PERMIT) + tp->t_flags |= TF_ECN_SND_CWR; +} + +static void inline +cc_post_fr(struct tcpcb *tp, struct tcphdr *th) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + if (CC_ALGO(tp)->post_fr != NULL) + CC_ALGO(tp)->post_fr(tp, th); +} /* Neighbor Discovery, Neighbor Unreachability Detection Upper layer hint. */ #ifdef INET6 @@ -1160,17 +1213,7 @@ tcp_do_segment(struct mbuf *m, struct tc if ((thflags & TH_ECE) && SEQ_LEQ(th->th_ack, tp->snd_recover)) { TCPSTAT_INC(tcps_ecn_rcwnd); - /* - * If the current CC algo has - * defined a hook for tasks to run - * before entering FR, call it. - */ - if (CC_ALGO(tp)->pre_fr != NULL) - CC_ALGO(tp)->pre_fr(tp, th); - ENTER_FASTRECOVERY(tp); - tp->snd_recover = tp->snd_max; - if (tp->t_flags & TF_ECN_PERMIT) - tp->t_flags |= TF_ECN_SND_CWR; + cc_pre_fr(tp, th); } } @@ -2105,17 +2148,7 @@ tcp_do_segment(struct mbuf *m, struct tc } } - /* - * If the current CC algo has - * defined a hook for tasks to run - * before entering FR, call it. - */ - if (CC_ALGO(tp)->pre_fr != NULL) - CC_ALGO(tp)->pre_fr(tp, th); - ENTER_FASTRECOVERY(tp); - tp->snd_recover = tp->snd_max; - if (tp->t_flags & TF_ECN_PERMIT) - tp->t_flags |= TF_ECN_SND_CWR; + cc_pre_fr(tp, th); tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; if (tp->t_flags & TF_SACK_PERMIT) { @@ -2186,10 +2219,8 @@ tcp_do_segment(struct mbuf *m, struct tc tcp_sack_partialack(tp, th); else tcp_newreno_partial_ack(tp, th); - } else { - if (CC_ALGO(tp)->post_fr != NULL) - CC_ALGO(tp)->post_fr(tp, th); - } + } else + cc_post_fr(tp, th); } tp->t_dupacks = 0; /* @@ -2292,10 +2323,8 @@ process_ACK: * The specifics of how this is achieved are up to the * congestion control algorithm in use for this connection. */ - if (!IN_FASTRECOVERY(tp)) { - if (CC_ALGO(tp)->ack_received != NULL) - CC_ALGO(tp)->ack_received(tp, th); - } + cc_ack_received(tp, th); + SOCKBUF_LOCK(&so->so_snd); if (acked > so->so_snd.sb_cc) { tp->snd_wnd -= so->so_snd.sb_cc; @@ -3274,9 +3303,7 @@ tcp_mss(struct tcpcb *tp, int offer) if (metrics.rmx_bandwidth) tp->snd_bandwidth = metrics.rmx_bandwidth; - /* Set the initial cwnd value. */ - if (CC_ALGO(tp)->cwnd_init != NULL) - CC_ALGO(tp)->cwnd_init(tp); + cc_cwnd_init(tp); /* Check the interface for TSO capabilities. */ if (mtuflags & CSUM_TSO) Modified: projects/tcp_cc_8.x/sys/netinet/tcp_output.c ============================================================================== --- projects/tcp_cc_8.x/sys/netinet/tcp_output.c Wed Jul 1 13:22:08 2009 (r195238) +++ projects/tcp_cc_8.x/sys/netinet/tcp_output.c Wed Jul 1 13:30:01 2009 (r195239) @@ -125,6 +125,19 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet CTLFLAG_RW, tcp_autosndbuf_max, 0, "Max size of automatic send buffer"); +static void inline cc_after_idle(struct tcpcb *tp); + +/* + * CC wrapper hook functions + */ +static void inline +cc_after_idle(struct tcpcb *tp) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + if (CC_ALGO(tp)->after_idle != NULL) + CC_ALGO(tp)->after_idle(tp); +} /* * Tcp output routine: figure out what should be sent and send it. @@ -169,11 +182,8 @@ tcp_output(struct tcpcb *tp) * to send, then transmit; otherwise, investigate further. */ idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una); - if (idle && ticks - tp->t_rcvtime >= tp->t_rxtcur) { - /* reset cwnd after a period of idleness */ - if (CC_ALGO(tp)->after_idle != NULL) - CC_ALGO(tp)->after_idle(tp); - } + if (idle && ticks - tp->t_rcvtime >= tp->t_rxtcur) + cc_after_idle(tp); tp->t_flags &= ~TF_LASTIDLE; if (idle) { if (tp->t_flags & TF_MORETOCOME) { Modified: projects/tcp_cc_8.x/sys/netinet/tcp_timer.c ============================================================================== --- projects/tcp_cc_8.x/sys/netinet/tcp_timer.c Wed Jul 1 13:22:08 2009 (r195238) +++ projects/tcp_cc_8.x/sys/netinet/tcp_timer.c Wed Jul 1 13:30:01 2009 (r195239) @@ -118,6 +118,24 @@ int tcp_maxpersistidle; /* max idle time in persist */ int tcp_maxidle; +static void inline cc_after_timeout(struct tcpcb *tp); + +/* + * CC wrapper hook functions + */ +static void inline +cc_after_timeout(struct tcpcb *tp) +{ + INP_WLOCK_ASSERT(tp->t_inpcb); + + if (CC_ALGO(tp)->after_timeout != NULL) + CC_ALGO(tp)->after_timeout(tp); + + tp->t_dupacks = 0; + EXIT_FASTRECOVERY(tp); + tp->t_bytes_acked = 0; +} + /* * Tcp protocol timeout routine called every 500 ms. * Updates timestamps used for TCP @@ -555,12 +573,8 @@ tcp_timer_rexmt(void * xtp) */ tp->t_rtttime = 0; - if (CC_ALGO(tp)->after_timeout != NULL) - CC_ALGO(tp)->after_timeout(tp); + cc_after_timeout(tp); - tp->t_dupacks = 0; - EXIT_FASTRECOVERY(tp); - tp->t_bytes_acked = 0; (void) tcp_output(tp); out:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907011330.n61DU1Vk013941>