--- zzzz-none-000/linux-2.6.32.61/net/ipv4/tcp.c 2013-06-10 09:43:48.000000000 +0000 +++ virian-300e-630/linux-2.6.32.61/net/ipv4/tcp.c 2013-10-22 16:49:27.000000000 +0000 @@ -275,6 +275,12 @@ #include #include +#if defined(CONFIG_AVM_SCATTER_GATHER) +unsigned int avm_scatter_gather_optimization = 1; +module_param(avm_scatter_gather_optimization, uint, S_IRUSR | S_IWUSR); +#endif + + int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; struct percpu_counter tcp_orphan_count; @@ -754,6 +760,11 @@ ssize_t copied; long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); +#if defined(CONFIG_AVM_SCATTER_GATHER) + int send_entire_page = (psize == PAGE_SIZE ); + int socket_is_corked = (tp->nonagle&TCP_NAGLE_CORK); +#endif + /* Wait for a connection to finish. */ if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) @@ -847,8 +858,25 @@ } out: - if (copied && !(flags & MSG_SENDPAGE_NOTLAST)) + +#if defined(CONFIG_AVM_SCATTER_GATHER) + if ((copied && !(flags & MSG_SENDPAGE_NOTLAST) && !avm_scatter_gather_optimization) || + (copied && !send_entire_page) || + (copied && !socket_is_corked) ){ + /* + * CBU@AVM: + * This is a performance optimization for small instruction cache CPUs + * It seems to be save to skip tcp_push here, as __tcp_push_pending_frames + * is also called by: + * (1) tcp_rcv_established + * (2) tcp_fin handler + */ +#else + if (copied && !(flags & MSG_SENDPAGE_NOTLAST)){ +#endif + tcp_push(sk, flags, mss_now, tp->nonagle); + } return copied; do_error: