author | libo <bo.li@amlogic.com> | 2018-05-18 12:47:38 (GMT) |
---|---|---|
committer | Bo Li <bo.li@amlogic.com> | 2019-07-29 11:09:18 (GMT) |
commit | dd999cbaf895913372f8a3ff320ba4004fce539a (patch) | |
tree | ea22696264401eb1034e393c9fffe7782cb2a1f6 | |
parent | 37c98ae7785bedbea04266880dc2e24fe2403a7c (diff) | |
download | common-dd999cbaf895913372f8a3ff320ba4004fce539a.zip common-dd999cbaf895913372f8a3ff320ba4004fce539a.tar.gz common-dd999cbaf895913372f8a3ff320ba4004fce539a.tar.bz2 |
wifi: add tcp delay ack support [1/1]
PD#OTT-5388
Problem:
wifi rx throughput issue
Solution:
add tcp delay ack support
enable tcp dealy ack by following command:
echo 1 > /proc/sys/net/ipv4/tcp_use_userconfig
echo 60 > /proc/sys/net/ipv4/tcp_delack_seg
Verify:
u211
Change-Id: I060810b2800bae377388ba6ed9f9256597c9e6ea
Signed-off-by: libo <bo.li@amlogic.com>
-rw-r--r-- | include/net/tcp.h | 12 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 23 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 14 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 6 | ||||
-rw-r--r-- | net/ipv4/tcp_timer.c | 56 |
5 files changed, 102 insertions, 9 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index e511825..370161d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -140,6 +140,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); * most likely due to retrans in 3WHS. */ +#define TCP_DELACK_SEG 1 /*Number of full MSS to receive before Acking RFC2581*/ + #define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes * for local resources. */ @@ -266,6 +268,11 @@ extern int sysctl_tcp_early_retrans; extern int sysctl_tcp_limit_output_bytes; extern int sysctl_tcp_challenge_ack_limit; extern int sysctl_tcp_min_tso_segs; + +/* sysctl variables for controlling various tcp parameters */ +extern int sysctl_tcp_delack_seg; +extern int sysctl_tcp_use_userconfig; + extern int sysctl_tcp_min_rtt_wlen; extern int sysctl_tcp_autocorking; extern int sysctl_tcp_invalid_ratelimit; @@ -364,6 +371,11 @@ ssize_t tcp_splice_read(struct socket *sk, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); +extern int tcp_use_userconfig_sysctl_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *length, loff_t *ppos); +extern int tcp_proc_delayed_ack_control(struct ctl_table *table, int write, + void __user *buffer, size_t *length, loff_t *ppos); + static inline void tcp_dec_quickack_mode(struct sock *sk, const unsigned int pkts) { diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d540bf1..a8d8b8d 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -42,6 +42,11 @@ static int tcp_syn_retries_max = MAX_TCP_SYNCNT; 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(struct net *net, int range[2]) { @@ -684,6 +689,24 @@ 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, + }, { } }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f0a2a86..3729137 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -297,6 +297,12 @@ EXPORT_SYMBOL(sysctl_tcp_mem); EXPORT_SYMBOL(sysctl_tcp_rmem); EXPORT_SYMBOL(sysctl_tcp_wmem); +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); + atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ EXPORT_SYMBOL(tcp_memory_allocated); @@ -1463,8 +1469,12 @@ static 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 diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 17d88e4..f384e0c 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5130,8 +5130,10 @@ 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 && + /* More than one full frame received... */ + 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... */ diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6952338..84383ad 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -24,6 +24,57 @@ 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( + struct 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( + struct 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; +} + +void tcp_init_xmit_timers(struct sock *sk) +{ + inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer, + &tcp_keepalive_timer); +} +EXPORT_SYMBOL(tcp_init_xmit_timers); + /** * tcp_write_err() - close socket and save error info * @sk: The socket the error has appeared on. @@ -722,8 +773,3 @@ out: sock_put(sk); } -void tcp_init_xmit_timers(struct sock *sk) -{ - inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer, - &tcp_keepalive_timer); -} |