10e57976bSJohn Heffner /* Tom Kelly's Scalable TCP 20e57976bSJohn Heffner * 3a52b8bd3SJoe Perches * See http://www.deneholme.net/tom/scalable/ 40e57976bSJohn Heffner * 50e57976bSJohn Heffner * John Heffner <jheffner@sc.edu> 60e57976bSJohn Heffner */ 70e57976bSJohn Heffner 80e57976bSJohn Heffner #include <linux/module.h> 90e57976bSJohn Heffner #include <net/tcp.h> 100e57976bSJohn Heffner 110e57976bSJohn Heffner /* These factors derived from the recommended values in the aer: 120e57976bSJohn Heffner * .01 and and 7/8. We use 50 instead of 100 to account for 130e57976bSJohn Heffner * delayed ack. 140e57976bSJohn Heffner */ 150e57976bSJohn Heffner #define TCP_SCALABLE_AI_CNT 50U 160e57976bSJohn Heffner #define TCP_SCALABLE_MD_SCALE 3 170e57976bSJohn Heffner 18c3a05c60SIlpo Järvinen static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) 190e57976bSJohn Heffner { 206687e988SArnaldo Carvalho de Melo struct tcp_sock *tp = tcp_sk(sk); 21f4805edeSStephen Hemminger 22f4805edeSStephen Hemminger if (!tcp_is_cwnd_limited(sk, in_flight)) 230e57976bSJohn Heffner return; 240e57976bSJohn Heffner 257faffa1cSStephen Hemminger if (tp->snd_cwnd <= tp->snd_ssthresh) 267faffa1cSStephen Hemminger tcp_slow_start(tp); 27758ce5c8SIlpo Järvinen else 28758ce5c8SIlpo Järvinen tcp_cong_avoid_ai(tp, min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)); 290e57976bSJohn Heffner } 300e57976bSJohn Heffner 316687e988SArnaldo Carvalho de Melo static u32 tcp_scalable_ssthresh(struct sock *sk) 320e57976bSJohn Heffner { 336687e988SArnaldo Carvalho de Melo const struct tcp_sock *tp = tcp_sk(sk); 340e57976bSJohn Heffner return max(tp->snd_cwnd - (tp->snd_cwnd>>TCP_SCALABLE_MD_SCALE), 2U); 350e57976bSJohn Heffner } 360e57976bSJohn Heffner 370e57976bSJohn Heffner 38*a252bebeSStephen Hemminger static struct tcp_congestion_ops tcp_scalable __read_mostly = { 390e57976bSJohn Heffner .ssthresh = tcp_scalable_ssthresh, 400e57976bSJohn Heffner .cong_avoid = tcp_scalable_cong_avoid, 410e57976bSJohn Heffner .min_cwnd = tcp_reno_min_cwnd, 420e57976bSJohn Heffner 430e57976bSJohn Heffner .owner = THIS_MODULE, 440e57976bSJohn Heffner .name = "scalable", 450e57976bSJohn Heffner }; 460e57976bSJohn Heffner 470e57976bSJohn Heffner static int __init tcp_scalable_register(void) 480e57976bSJohn Heffner { 490e57976bSJohn Heffner return tcp_register_congestion_control(&tcp_scalable); 500e57976bSJohn Heffner } 510e57976bSJohn Heffner 520e57976bSJohn Heffner static void __exit tcp_scalable_unregister(void) 530e57976bSJohn Heffner { 540e57976bSJohn Heffner tcp_unregister_congestion_control(&tcp_scalable); 550e57976bSJohn Heffner } 560e57976bSJohn Heffner 570e57976bSJohn Heffner module_init(tcp_scalable_register); 580e57976bSJohn Heffner module_exit(tcp_scalable_unregister); 590e57976bSJohn Heffner 600e57976bSJohn Heffner MODULE_AUTHOR("John Heffner"); 610e57976bSJohn Heffner MODULE_LICENSE("GPL"); 620e57976bSJohn Heffner MODULE_DESCRIPTION("Scalable TCP"); 63