Message ID | 20170815130806.25168-1-mohamed.a.alrshah@ieee.org |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On Tue, Aug 15, 2017 at 9:08 AM, mohamedalrshah <mohamed.a.alrshah@ieee.org> wrote: > + > +/* Agile-SD Parameters */ > +struct agilesdtcp { > + u32 loss_cwnd; /* congestion window at last loss.*/ Please rebase your change on top of the latest net-next changes and update this module to use the latest approach from the recent commit: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=f1722a1be19dc38e0a4b282d4e6e6ec5e1b11a67 tcp: consolidate congestion control undo functions Specifically: - reference tp->prior_cwnd instead of ca->loss_cwnd - remove the ca->loss_cwnd field - have the .undo_cwnd field reference tcp_reno_undo_cwnd > + u32 frac_tracer; /* This is to trace the fractions of the increment.*/ > + u32 degraded_loss_cwnd; /* loss_cwnd after degradation.*/ > + enum dystate{SS=0, CA=1} agilesd_tcp_status; Per Linux style, please define the enum separately before declaring the variable of that type, and format the enum using Linux style. Also please use a longer, more specific name, to avoid name collisions. I'd suggest: enum dystate { AGILE_SD_SS = 0, /* comment ... */ AGILE_SD_CA = 1, /* comment ... */ }; > +}; > + > +/* To reset the parameters if needed*/ > +static inline void agilesdtcp_reset(struct sock *sk) > +{ > + > +} > + > +/* This function is called after the first acknowledgment is received and before the congestion > + * control algorithm will be called for the first time. If the congestion control algorithm has > + * private data, it should initialize its private date here. */ Multi-line comments should end with the trailing */ on a line by itself. Here and elsewhere. Please read: https://www.kernel.org/doc/html/v4.10/process/coding-style.html Please check the style of patches before submitting with the following script in the Linux kernel tree: scripts/checkpatch.pl > +static void agilesdtcp_init(struct sock *sk) > +{ > + struct agilesdtcp *ca = inet_csk_ca(sk); > + > + /* The value of initial_ssthresh parameter is not used here, thus, snd_ssthresh is initialized by a large value.*/ > + tcp_sk(sk)->snd_ssthresh = 0x7fffffff; > + > + ca->loss_cwnd = 0; > + ca->frac_tracer = 0; > + ca->agilesd_tcp_status = SS; > +} > + > +/* This function is called whenever an ack is received and the congestion window can be increased. > + * This is equivalent to opencwnd in tcp.cc. > + * ack is the number of bytes that are acknowledged in the latest acknowledgment; > + * rtt is the the rtt measured by the latest acknowledgment; > + * in_flight is the packet in flight before the latest acknowledgment; > + * good_ack is an indicator whether the current situation is normal (no duplicate ack, no loss and no SACK). */ > +static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) > +{ > + struct tcp_sock *tp = tcp_sk(sk); > + struct agilesdtcp *ca = inet_csk_ca(sk); > + u32 inc_factor; > + u32 ca_inc; > + u32 current_gap, total_gap; For coding style, please order local variable declarations from longest to shortest line, also know as Reverse Christmas Tree Format. > + /* The value of inc_factor is limited by lower_fl and upper_fl. > + * The lower_fl must be always = 1. The greater the upper_fl the higher the aggressiveness. > + * But, if upper_fl set to 1, Agile-SD will work exactly as newreno. > + * We have already designed an equation to calculate the optimum upper_fl based on the given beta. > + * This equation will be revealed once its article is published*/ > + u32 lower_fl = 1 * SCALE; > + u32 upper_fl = 3 * SCALE; > + > + if (!tcp_is_cwnd_limited(sk)) return; Please put this return (or any if/else body) on a line by itself. > + > + if (tp->snd_cwnd < tp->snd_ssthresh){ Need a space between ) and {. > + ca->agilesd_tcp_status = SS; > + tcp_slow_start(tp, in_flight); > + } > + else { The else needs to go on the same line as the closing brace. > + inc_factor = min(max(((upper_fl * current_gap) / total_gap), lower_fl), upper_fl); Please use the existing kernel helper macro for this: #define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi) > + > + ca_inc = ((inc_factor * SCALE) / tp->snd_cwnd); /* SCALE is used to avoid fractions*/ > + > + ca->frac_tracer += ca_inc; /* This in order to take the fraction increase into account */ > + if (ca->frac_tracer >= Double_SCALE) /* To take factor scale into account */ > + { The opening brace goes on the previous line. > +/* This function is called when the TCP flow detects a loss. > + * It returns the slow start threshold of a flow, after a packet loss is detected. */ Trailing */ style issue again. > +static u32 agilesdtcp_recalc_ssthresh(struct sock *sk) > +{ > + const struct tcp_sock *tp = tcp_sk(sk); > + struct agilesdtcp *ca = inet_csk_ca(sk); > + > + ca->loss_cwnd = tp->snd_cwnd; > + > + if (ca->agilesd_tcp_status == CA) > + ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U); > + else > + ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U); These two branches of the if/else look the same? Can they be condensed to a single line? Thanks, neal
On Tue, Aug 15, 2017 at 9:08 AM, mohamedalrshah
<mohamed.a.alrshah@ieee.org> wrote:
> This commit implements a new TCP congestion control algorithm, namely Agile-SD.
Also, please use a summary line for your patch that is more in keeping
with Linux style, using spaces rather than dashes, and leading with
tcp: or tcp_agile_sd:. For example:
tcp: add Agile SD TCP congestion control module
And please read:
https://www.kernel.org/doc/html/latest/process/submitting-patches.html
Thanks,
neal
On 08/15/2017 06:51 AM, Neal Cardwell wrote: > On Tue, Aug 15, 2017 at 9:08 AM, mohamedalrshah > <mohamed.a.alrshah@ieee.org> wrote: > >> +static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) >> +{ >> + struct tcp_sock *tp = tcp_sk(sk); >> + struct agilesdtcp *ca = inet_csk_ca(sk); >> + u32 inc_factor; >> + u32 ca_inc; >> + u32 current_gap, total_gap; > > For coding style, please order local variable declarations from > longest to shortest line, also know as Reverse Christmas Tree Format. Per what coding style, please? This is not in current coding style nor in the netdev-FAQ exceptions.
On 08/15/2017 06:08 AM, mohamedalrshah wrote: > diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig > index 91a2557..474f72c 100644 > --- a/net/ipv4/Kconfig > +++ b/net/ipv4/Kconfig > @@ -677,6 +677,17 @@ config TCP_CONG_BBR > bufferbloat, policers, or AQM schemes that do not provide a delay > signal. It requires the fq ("Fair Queue") pacing packet scheduler. > > +config TCP_CONG_AGILESD > + tristate "Agile-SD Congestion control" > + default n > + ---help--- > + > + This is version 1.0 of Agile-SD TCP. It is a sender-side only. It is a sender-side only <what>. > + It contributes the Agility Factor (AF) to shorten the epoch time > + and to make TCP independent from RTT. AF reduces the sensitivity > + to packet losses, which in turn Agile-SD to achieve better throughput in turn allows Agile-SD > + over high-speed networks. > + Please drop the tab(s) and space(s) at the ends of lines. > choice > prompt "Default TCP congestion control" > default DEFAULT_CUBIC > @@ -713,6 +724,9 @@ choice > > config DEFAULT_BBR > bool "BBR" if TCP_CONG_BBR=y > + > + config DEFAULT_AGILESD Indent above with tab, not spaces. > + bool "AGILESD" if TCP_CONG_AGILESD=y > > config DEFAULT_RENO > bool "Reno" > @@ -738,6 +752,7 @@ config DEFAULT_TCP_CONG > default "dctcp" if DEFAULT_DCTCP > default "cdg" if DEFAULT_CDG > default "bbr" if DEFAULT_BBR > + default "agilesd" if DEFAULT_AGILESD Indent above with tab, not spaces. > default "cubic" > > config TCP_MD5SIG
From: Randy Dunlap <rdunlap@infradead.org> Date: Tue, 15 Aug 2017 09:41:53 -0700 > On 08/15/2017 06:51 AM, Neal Cardwell wrote: >> On Tue, Aug 15, 2017 at 9:08 AM, mohamedalrshah >> <mohamed.a.alrshah@ieee.org> wrote: >> >>> +static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) >>> +{ >>> + struct tcp_sock *tp = tcp_sk(sk); >>> + struct agilesdtcp *ca = inet_csk_ca(sk); >>> + u32 inc_factor; >>> + u32 ca_inc; >>> + u32 current_gap, total_gap; >> >> For coding style, please order local variable declarations from >> longest to shortest line, also know as Reverse Christmas Tree Format. > > Per what coding style, please? This is not in current coding style nor in the > netdev-FAQ exceptions. It is the established practice, documented or not, and I enforce this for all networking code submissions.
On 08/15/2017 10:36 AM, David Miller wrote: > From: Randy Dunlap <rdunlap@infradead.org> > Date: Tue, 15 Aug 2017 09:41:53 -0700 > >> On 08/15/2017 06:51 AM, Neal Cardwell wrote: >>> On Tue, Aug 15, 2017 at 9:08 AM, mohamedalrshah >>> <mohamed.a.alrshah@ieee.org> wrote: >>> >>>> +static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) >>>> +{ >>>> + struct tcp_sock *tp = tcp_sk(sk); >>>> + struct agilesdtcp *ca = inet_csk_ca(sk); >>>> + u32 inc_factor; >>>> + u32 ca_inc; >>>> + u32 current_gap, total_gap; >>> >>> For coding style, please order local variable declarations from >>> longest to shortest line, also know as Reverse Christmas Tree Format. >> >> Per what coding style, please? This is not in current coding style nor in the >> netdev-FAQ exceptions. > > It is the established practice, documented or not, and I enforce this for all > networking code submissions. I see. Thanks for clarifying that.
Hi mohamedalrshah, [auto build test ERROR on net/master] [also build test ERROR on v4.13-rc5 next-20170816] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/mohamedalrshah/Adding-Agile-SD-TCP-module-and-modifying-Kconfig-and-makefile/20170817-055643 config: ia64-allyesconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 6.2.0 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=ia64 All errors (new ones prefixed by >>): >> net//ipv4/tcp_agilesd.c:169:16: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .pkts_acked = agilesdtcp_acked, ^~~~~~~~~~~~~~~~ net//ipv4/tcp_agilesd.c:169:16: note: (near initialization for 'agilesdtcp.pkts_acked') cc1: some warnings being treated as errors vim +169 net//ipv4/tcp_agilesd.c 162 163 static struct tcp_congestion_ops agilesdtcp __read_mostly = { 164 .init = agilesdtcp_init, 165 .ssthresh = agilesdtcp_recalc_ssthresh, 166 .cong_avoid = agilesdtcp_cong_avoid, 167 .set_state = agilesdtcp_state, 168 .undo_cwnd = agilesdtcp_undo_cwnd, > 169 .pkts_acked = agilesdtcp_acked, 170 .owner = THIS_MODULE, 171 .name = "agilesd", 172 }; 173 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi mohamedalrshah, [auto build test ERROR on net/master] [also build test ERROR on v4.13-rc5 next-20170816] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/mohamedalrshah/Adding-Agile-SD-TCP-module-and-modifying-Kconfig-and-makefile/20170817-055643 config: i386-allyesconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): >> net//ipv4/tcp_agilesd.c:35:15: error: expected identifier before numeric constant enum dystate{SS=0, CA=1} agilesd_tcp_status; ^~ net//ipv4/tcp_agilesd.c: In function 'agilesdtcp_cong_avoid': net//ipv4/tcp_agilesd.c:87:28: error: 'CA' undeclared (first use in this function) ca->agilesd_tcp_status = CA; ^~ net//ipv4/tcp_agilesd.c:87:28: note: each undeclared identifier is reported only once for each function it appears in net//ipv4/tcp_agilesd.c: In function 'agilesdtcp_recalc_ssthresh': net//ipv4/tcp_agilesd.c:121:32: error: 'CA' undeclared (first use in this function) if (ca->agilesd_tcp_status == CA) ^~ net//ipv4/tcp_agilesd.c: At top level: net//ipv4/tcp_agilesd.c:169:16: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types] .pkts_acked = agilesdtcp_acked, ^~~~~~~~~~~~~~~~ net//ipv4/tcp_agilesd.c:169:16: note: (near initialization for 'agilesdtcp.pkts_acked') cc1: some warnings being treated as errors vim +35 net//ipv4/tcp_agilesd.c 29 30 /* Agile-SD Parameters */ 31 struct agilesdtcp { 32 u32 loss_cwnd; /* congestion window at last loss.*/ 33 u32 frac_tracer; /* This is to trace the fractions of the increment.*/ 34 u32 degraded_loss_cwnd; /* loss_cwnd after degradation.*/ > 35 enum dystate{SS=0, CA=1} agilesd_tcp_status; 36 }; 37 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 91a2557..474f72c 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -677,6 +677,17 @@ config TCP_CONG_BBR bufferbloat, policers, or AQM schemes that do not provide a delay signal. It requires the fq ("Fair Queue") pacing packet scheduler. +config TCP_CONG_AGILESD + tristate "Agile-SD Congestion control" + default n + ---help--- + + This is version 1.0 of Agile-SD TCP. It is a sender-side only. + It contributes the Agility Factor (AF) to shorten the epoch time + and to make TCP independent from RTT. AF reduces the sensitivity + to packet losses, which in turn Agile-SD to achieve better throughput + over high-speed networks. + choice prompt "Default TCP congestion control" default DEFAULT_CUBIC @@ -713,6 +724,9 @@ choice config DEFAULT_BBR bool "BBR" if TCP_CONG_BBR=y + + config DEFAULT_AGILESD + bool "AGILESD" if TCP_CONG_AGILESD=y config DEFAULT_RENO bool "Reno" @@ -738,6 +752,7 @@ config DEFAULT_TCP_CONG default "dctcp" if DEFAULT_DCTCP default "cdg" if DEFAULT_CDG default "bbr" if DEFAULT_BBR + default "agilesd" if DEFAULT_AGILESD default "cubic" config TCP_MD5SIG diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index f83de23..33d398b 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o +obj-$(CONFIG_TCP_CONG_AGILESD) += tcp_agilesd.o obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o diff --git a/net/ipv4/tcp_agilesd.c b/net/ipv4/tcp_agilesd.c new file mode 100755 index 0000000..5de4779 --- /dev/null +++ b/net/ipv4/tcp_agilesd.c @@ -0,0 +1,193 @@ +/* Agile-SD is a Loss-Based Congestion Control Algorithm for High-speed Networks. + * Agile-SD is a new loss-based and RTT-independent TCP congestion control algorithm + * designed to support high-speed networks. It introduces the Agility Factor Mechanism (AFM), + * which allows Agile-SD to deal with small buffer sizes while reducing its sensitivity to + * packet loss. Due to the use of this mechanism, Agile-SD improves the throughput of TCP + * up to 50% compared to Cubic-TCP and Compound-TCP in many cases, especially when the buffer + * is small and the data loss is common. Its performance was evaluated using simulation and + * testbed to measure the average throughput, loss ratio, and fairness. + * + * Agile-SD is described in detail in: + * "Agile-SD: a Linux-based TCP congestion control algorithm for supporting high-speed and short-distance networks", + * Alrshah, M.A., Othman, M., Ali, B. and Hanapi, Z.M. + * Journal of Network and Computer Applications, Vol. 55, pages.181-190, May-June 2015. + * + * Moreover, Agile-SD performance has been mathematically proven in: + * "Modeling the Throughput of the Linux-Based Agile-SD Transmission Control Protocol", + * Alrshah, M.A., Othman, M., Ali, B. and Hanapi, Z.M. + * IEEE Access journal, Vol. 4, pages.9724-9732, Jan 2017. + */ + +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/math64.h> +#include <net/tcp.h> + +#define SCALE 1000 /* Scale factor to avoid fractions */ +#define Double_SCALE 1000000 /* Double_SCALE must be equal to SCALE^2 */ +#define beta 900 /* beta for multiplicative decrease */ + +/* Agile-SD Parameters */ +struct agilesdtcp { + u32 loss_cwnd; /* congestion window at last loss.*/ + u32 frac_tracer; /* This is to trace the fractions of the increment.*/ + u32 degraded_loss_cwnd; /* loss_cwnd after degradation.*/ + enum dystate{SS=0, CA=1} agilesd_tcp_status; +}; + +/* To reset the parameters if needed*/ +static inline void agilesdtcp_reset(struct sock *sk) +{ + +} + +/* This function is called after the first acknowledgment is received and before the congestion + * control algorithm will be called for the first time. If the congestion control algorithm has + * private data, it should initialize its private date here. */ +static void agilesdtcp_init(struct sock *sk) +{ + struct agilesdtcp *ca = inet_csk_ca(sk); + + /* The value of initial_ssthresh parameter is not used here, thus, snd_ssthresh is initialized by a large value.*/ + tcp_sk(sk)->snd_ssthresh = 0x7fffffff; + + ca->loss_cwnd = 0; + ca->frac_tracer = 0; + ca->agilesd_tcp_status = SS; +} + +/* This function is called whenever an ack is received and the congestion window can be increased. + * This is equivalent to opencwnd in tcp.cc. + * ack is the number of bytes that are acknowledged in the latest acknowledgment; + * rtt is the the rtt measured by the latest acknowledgment; + * in_flight is the packet in flight before the latest acknowledgment; + * good_ack is an indicator whether the current situation is normal (no duplicate ack, no loss and no SACK). */ +static void agilesdtcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct agilesdtcp *ca = inet_csk_ca(sk); + u32 inc_factor; + u32 ca_inc; + u32 current_gap, total_gap; + /* The value of inc_factor is limited by lower_fl and upper_fl. + * The lower_fl must be always = 1. The greater the upper_fl the higher the aggressiveness. + * But, if upper_fl set to 1, Agile-SD will work exactly as newreno. + * We have already designed an equation to calculate the optimum upper_fl based on the given beta. + * This equation will be revealed once its article is published*/ + u32 lower_fl = 1 * SCALE; + u32 upper_fl = 3 * SCALE; + + if (!tcp_is_cwnd_limited(sk)) return; + + if (tp->snd_cwnd < tp->snd_ssthresh){ + ca->agilesd_tcp_status = SS; + tcp_slow_start(tp, in_flight); + } + else { + ca->agilesd_tcp_status = CA; + + if (ca->loss_cwnd > ca->degraded_loss_cwnd) + total_gap = ca->loss_cwnd - ca->degraded_loss_cwnd; + else + total_gap = 1; + + if (ca->loss_cwnd > tp->snd_cwnd) + current_gap = ca->loss_cwnd - tp->snd_cwnd; + else + current_gap = 0; + + inc_factor = min(max(((upper_fl * current_gap) / total_gap), lower_fl), upper_fl); + + ca_inc = ((inc_factor * SCALE) / tp->snd_cwnd); /* SCALE is used to avoid fractions*/ + + ca->frac_tracer += ca_inc; /* This in order to take the fraction increase into account */ + if (ca->frac_tracer >= Double_SCALE) /* To take factor scale into account */ + { + tp->snd_cwnd += 1; + ca->frac_tracer -= Double_SCALE; + } + } +} + +/* This function is called when the TCP flow detects a loss. + * It returns the slow start threshold of a flow, after a packet loss is detected. */ +static u32 agilesdtcp_recalc_ssthresh(struct sock *sk) +{ + const struct tcp_sock *tp = tcp_sk(sk); + struct agilesdtcp *ca = inet_csk_ca(sk); + + ca->loss_cwnd = tp->snd_cwnd; + + if (ca->agilesd_tcp_status == CA) + ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U); + else + ca->degraded_loss_cwnd = max((tp->snd_cwnd * beta) / SCALE, 2U); + + ca->frac_tracer = 0; + + return ca->degraded_loss_cwnd; +} + +static u32 agilesdtcp_undo_cwnd(struct sock *sk) +{ + const struct tcp_sock *tp = tcp_sk(sk); + const struct agilesdtcp *ca = inet_csk_ca(sk); + return max(tp->snd_cwnd, ca->loss_cwnd); +} + +/* This function is called when the congestion state of the TCP is changed. + * newstate is the state code for the state that TCP is going to be in. + * The possible states are listed below: + * The current congestion control state, which can be one of the followings: + * TCP_CA_Open: normal state + * TCP_CA_Recovery: Loss Recovery after a Fast Transmission + * TCP_CA_Loss: Loss Recovery after a Timeout + * (The following two states are not effective in TCP-Linux but is effective in Linux) + * TCP_CA_Disorder: duplicate packets detected, but haven't reach the threshold. So TCP shall assume that packet reordering is happening. + * TCP_CA_CWR: the state that congestion window is decreasing (after local congestion in NIC, or ECN and etc). + * It is to notify the congestion control algorithm and is used by some + * algorithms which turn off their special control during loss recovery. */ +static void agilesdtcp_state(struct sock *sk, u8 new_state) +{ + if (new_state == TCP_CA_Loss) + agilesdtcp_reset(inet_csk_ca(sk)); +} + +/* This function is called when there is an acknowledgment that acknowledges some new packets. + * num_acked is the number of packets that are acknowledged by this acknowledgments. */ +static void agilesdtcp_acked(struct sock *sk, u32 num_acked, s32 rtt_us) +{ + +} + +static struct tcp_congestion_ops agilesdtcp __read_mostly = { + .init = agilesdtcp_init, + .ssthresh = agilesdtcp_recalc_ssthresh, + .cong_avoid = agilesdtcp_cong_avoid, + .set_state = agilesdtcp_state, + .undo_cwnd = agilesdtcp_undo_cwnd, + .pkts_acked = agilesdtcp_acked, + .owner = THIS_MODULE, + .name = "agilesd", +}; + +static int __init agilesdtcp_register(void) +{ + BUILD_BUG_ON(sizeof(struct agilesdtcp) > ICSK_CA_PRIV_SIZE); + return tcp_register_congestion_control(&agilesdtcp); +} + +static void __exit agilesdtcp_unregister(void) +{ + tcp_unregister_congestion_control(&agilesdtcp); +} + +module_init(agilesdtcp_register); +module_exit(agilesdtcp_unregister); + +MODULE_AUTHOR("Mohamed A. Alrshah <mohamed.a.alrshah@ieee.org>"); +MODULE_AUTHOR("Mohamed Othman"); +MODULE_AUTHOR("Borhanuddin Ali"); +MODULE_AUTHOR("Zurina Hanapi"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("Agile-SD is a Loss-Based Congestion Control Algorithm for High-speed Networks");