Loading include/net/tcp.h +14 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); * most likely due to retrans in 3WHS. */ /* Number of full MSS to receive before Acking RFC2581 */ #define TCP_DELACK_SEG 1 #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes * for local resources. */ Loading Loading @@ -289,6 +292,11 @@ extern int sysctl_tcp_limit_output_bytes; extern int sysctl_tcp_challenge_ack_limit; extern atomic_long_t tcp_memory_allocated; /* sysctl variables for controlling various tcp parameters */ extern int sysctl_tcp_delack_seg; extern int sysctl_tcp_use_userconfig; extern struct percpu_counter tcp_sockets_allocated; extern int tcp_memory_pressure; Loading Loading @@ -386,6 +394,12 @@ extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); /* sysctl master controller */ extern int tcp_use_userconfig_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern int tcp_proc_delayed_ack_control(struct ctl_table *, int, void __user *, size_t *, loff_t *); static inline void tcp_dec_quickack_mode(struct sock *sk, const unsigned int pkts) { Loading net/ipv4/sysctl_net_ipv4.c +23 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,10 @@ static int ip_ttl_min = 1; static int ip_ttl_max = 255; static int ip_ping_group_range_min[] = { 0, 0 }; static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; static int tcp_delack_seg_min = TCP_DELACK_MIN; static int tcp_delack_seg_max = 60; static int tcp_use_userconfig_min; static int tcp_use_userconfig_max = 1; /* Update system visible IP port range */ static void set_local_port_range(int range[2]) Loading Loading @@ -771,6 +775,25 @@ static struct ctl_table ipv4_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &one }, { .procname = "tcp_delack_seg", .data = &sysctl_tcp_delack_seg, .maxlen = sizeof(sysctl_tcp_delack_seg), .mode = 0644, .proc_handler = tcp_proc_delayed_ack_control, .extra1 = &tcp_delack_seg_min, .extra2 = &tcp_delack_seg_max, }, { .procname = "tcp_use_userconfig", .data = &sysctl_tcp_use_userconfig, .maxlen = sizeof(sysctl_tcp_use_userconfig), .mode = 0644, .proc_handler = tcp_use_userconfig_sysctl_handler, .extra1 = &tcp_use_userconfig_min, .extra2 = &tcp_use_userconfig_max, }, { } }; Loading net/ipv4/tcp.c +12 −2 Original line number Diff line number Diff line Loading @@ -298,6 +298,13 @@ EXPORT_SYMBOL(sysctl_tcp_wmem); atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ EXPORT_SYMBOL(tcp_memory_allocated); int sysctl_tcp_delack_seg __read_mostly = TCP_DELACK_SEG; EXPORT_SYMBOL(sysctl_tcp_delack_seg); int sysctl_tcp_use_userconfig __read_mostly; EXPORT_SYMBOL(sysctl_tcp_use_userconfig); /* * Current number of TCP sockets. */ Loading Loading @@ -1336,8 +1343,11 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) /* Delayed ACKs frequently hit locked sockets during bulk * receive. */ if (icsk->icsk_ack.blocked || /* Once-per-two-segments ACK was not sent by tcp_input.c */ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || /* Once-per-sysctl_tcp_delack_seg segments * ACK was not sent by tcp_input.c */ tp->rcv_nxt - tp->rcv_wup > (icsk->icsk_ack.rcv_mss) * sysctl_tcp_delack_seg || /* * If this read emptied read buffer, we send ACK, if * connection is not bidirectional, user drained Loading net/ipv4/tcp_input.c +2 −1 Original line number Diff line number Diff line Loading @@ -4757,7 +4757,8 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) struct tcp_sock *tp = tcp_sk(sk); /* More than one full frame received... */ if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && if (((tp->rcv_nxt - tp->rcv_wup) > (inet_csk(sk)->icsk_ack.rcv_mss) * sysctl_tcp_delack_seg && /* ... and right edge of window advances far enough. * (tcp_recvmsg() will send ACK otherwise). Or... */ Loading net/ipv4/tcp_timer.c +36 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,42 @@ int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; int sysctl_tcp_orphan_retries __read_mostly; int sysctl_tcp_thin_linear_timeouts __read_mostly; static void tcp_write_timer(unsigned long); static void tcp_delack_timer(unsigned long); static void tcp_keepalive_timer(unsigned long data); /*Function to reset tcp_ack related sysctl on resetting master control */ void set_tcp_default(void) { sysctl_tcp_delack_seg = TCP_DELACK_SEG; } /*sysctl handler for tcp_ack realted master control */ int tcp_proc_delayed_ack_control(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { int ret = proc_dointvec_minmax(table, write, buffer, length, ppos); /* The ret value will be 0 if the input validation is successful * and the values are written to sysctl table. If not, the stack * will continue to work with currently configured values */ return ret; } /*sysctl handler for tcp_ack realted master control */ int tcp_use_userconfig_sysctl_handler(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { int ret = proc_dointvec_minmax(table, write, buffer, length, ppos); if (write && ret == 0) { if (!sysctl_tcp_use_userconfig) set_tcp_default(); } return ret; } static void tcp_write_err(struct sock *sk) { sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; Loading Loading
include/net/tcp.h +14 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); * most likely due to retrans in 3WHS. */ /* Number of full MSS to receive before Acking RFC2581 */ #define TCP_DELACK_SEG 1 #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes * for local resources. */ Loading Loading @@ -289,6 +292,11 @@ extern int sysctl_tcp_limit_output_bytes; extern int sysctl_tcp_challenge_ack_limit; extern atomic_long_t tcp_memory_allocated; /* sysctl variables for controlling various tcp parameters */ extern int sysctl_tcp_delack_seg; extern int sysctl_tcp_use_userconfig; extern struct percpu_counter tcp_sockets_allocated; extern int tcp_memory_pressure; Loading Loading @@ -386,6 +394,12 @@ extern ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); /* sysctl master controller */ extern int tcp_use_userconfig_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern int tcp_proc_delayed_ack_control(struct ctl_table *, int, void __user *, size_t *, loff_t *); static inline void tcp_dec_quickack_mode(struct sock *sk, const unsigned int pkts) { Loading
net/ipv4/sysctl_net_ipv4.c +23 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,10 @@ static int ip_ttl_min = 1; static int ip_ttl_max = 255; static int ip_ping_group_range_min[] = { 0, 0 }; static int ip_ping_group_range_max[] = { GID_T_MAX, GID_T_MAX }; static int tcp_delack_seg_min = TCP_DELACK_MIN; static int tcp_delack_seg_max = 60; static int tcp_use_userconfig_min; static int tcp_use_userconfig_max = 1; /* Update system visible IP port range */ static void set_local_port_range(int range[2]) Loading Loading @@ -771,6 +775,25 @@ static struct ctl_table ipv4_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &one }, { .procname = "tcp_delack_seg", .data = &sysctl_tcp_delack_seg, .maxlen = sizeof(sysctl_tcp_delack_seg), .mode = 0644, .proc_handler = tcp_proc_delayed_ack_control, .extra1 = &tcp_delack_seg_min, .extra2 = &tcp_delack_seg_max, }, { .procname = "tcp_use_userconfig", .data = &sysctl_tcp_use_userconfig, .maxlen = sizeof(sysctl_tcp_use_userconfig), .mode = 0644, .proc_handler = tcp_use_userconfig_sysctl_handler, .extra1 = &tcp_use_userconfig_min, .extra2 = &tcp_use_userconfig_max, }, { } }; Loading
net/ipv4/tcp.c +12 −2 Original line number Diff line number Diff line Loading @@ -298,6 +298,13 @@ EXPORT_SYMBOL(sysctl_tcp_wmem); atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ EXPORT_SYMBOL(tcp_memory_allocated); int sysctl_tcp_delack_seg __read_mostly = TCP_DELACK_SEG; EXPORT_SYMBOL(sysctl_tcp_delack_seg); int sysctl_tcp_use_userconfig __read_mostly; EXPORT_SYMBOL(sysctl_tcp_use_userconfig); /* * Current number of TCP sockets. */ Loading Loading @@ -1336,8 +1343,11 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) /* Delayed ACKs frequently hit locked sockets during bulk * receive. */ if (icsk->icsk_ack.blocked || /* Once-per-two-segments ACK was not sent by tcp_input.c */ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || /* Once-per-sysctl_tcp_delack_seg segments * ACK was not sent by tcp_input.c */ tp->rcv_nxt - tp->rcv_wup > (icsk->icsk_ack.rcv_mss) * sysctl_tcp_delack_seg || /* * If this read emptied read buffer, we send ACK, if * connection is not bidirectional, user drained Loading
net/ipv4/tcp_input.c +2 −1 Original line number Diff line number Diff line Loading @@ -4757,7 +4757,8 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) struct tcp_sock *tp = tcp_sk(sk); /* More than one full frame received... */ if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && if (((tp->rcv_nxt - tp->rcv_wup) > (inet_csk(sk)->icsk_ack.rcv_mss) * sysctl_tcp_delack_seg && /* ... and right edge of window advances far enough. * (tcp_recvmsg() will send ACK otherwise). Or... */ Loading
net/ipv4/tcp_timer.c +36 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,42 @@ int sysctl_tcp_retries2 __read_mostly = TCP_RETR2; int sysctl_tcp_orphan_retries __read_mostly; int sysctl_tcp_thin_linear_timeouts __read_mostly; static void tcp_write_timer(unsigned long); static void tcp_delack_timer(unsigned long); static void tcp_keepalive_timer(unsigned long data); /*Function to reset tcp_ack related sysctl on resetting master control */ void set_tcp_default(void) { sysctl_tcp_delack_seg = TCP_DELACK_SEG; } /*sysctl handler for tcp_ack realted master control */ int tcp_proc_delayed_ack_control(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { int ret = proc_dointvec_minmax(table, write, buffer, length, ppos); /* The ret value will be 0 if the input validation is successful * and the values are written to sysctl table. If not, the stack * will continue to work with currently configured values */ return ret; } /*sysctl handler for tcp_ack realted master control */ int tcp_use_userconfig_sysctl_handler(ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) { int ret = proc_dointvec_minmax(table, write, buffer, length, ppos); if (write && ret == 0) { if (!sysctl_tcp_use_userconfig) set_tcp_default(); } return ret; } static void tcp_write_err(struct sock *sk) { sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; Loading