aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorKrishna Kumar <krkumar2@in.ibm.com>2009-12-10 02:16:59 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-23 17:13:29 -0500
commitdef87cf42069a6d4fd42a2ede8f19c620a292568 (patch)
tree1e8e97b452dd95d389feb4f04c0f25b6a9264412 /net/ipv4/tcp.c
parentafeca340c078e17ca233b3c68c3c3a70c56bfe1d (diff)
tcp: Slightly optimize tcp_sendmsg
Slightly optimize tcp_sendmsg since NETIF_F_SG is used many times iteratively in the loop. The only other modification is to change: } else if (i == MAX_SKB_FRAGS || (!i && !(sk->sk_route_caps & NETIF_F_SG))) { to: } else if (i == MAX_SKB_FRAGS || !sg) { The reason why this change is correct: this code (other than the MAX_SKB_FRAGS case) executes only due to the else part of: "if (skb_tailroom(skb) > 0) {" - i.e. there was no space in the skb to put the data inline. Hence SG is false is a sufficient condition, and there is no way a fragment can be added to the skb. Changelog: - Added the above explanation for the change Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com> Acked-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8a3f05adb39b..d5d69ea8f249 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -876,12 +876,12 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
876#define TCP_PAGE(sk) (sk->sk_sndmsg_page) 876#define TCP_PAGE(sk) (sk->sk_sndmsg_page)
877#define TCP_OFF(sk) (sk->sk_sndmsg_off) 877#define TCP_OFF(sk) (sk->sk_sndmsg_off)
878 878
879static inline int select_size(struct sock *sk) 879static inline int select_size(struct sock *sk, int sg)
880{ 880{
881 struct tcp_sock *tp = tcp_sk(sk); 881 struct tcp_sock *tp = tcp_sk(sk);
882 int tmp = tp->mss_cache; 882 int tmp = tp->mss_cache;
883 883
884 if (sk->sk_route_caps & NETIF_F_SG) { 884 if (sg) {
885 if (sk_can_gso(sk)) 885 if (sk_can_gso(sk))
886 tmp = 0; 886 tmp = 0;
887 else { 887 else {
@@ -905,7 +905,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
905 struct sk_buff *skb; 905 struct sk_buff *skb;
906 int iovlen, flags; 906 int iovlen, flags;
907 int mss_now, size_goal; 907 int mss_now, size_goal;
908 int err, copied; 908 int sg, err, copied;
909 long timeo; 909 long timeo;
910 910
911 lock_sock(sk); 911 lock_sock(sk);
@@ -933,6 +933,8 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
933 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) 933 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
934 goto out_err; 934 goto out_err;
935 935
936 sg = sk->sk_route_caps & NETIF_F_SG;
937
936 while (--iovlen >= 0) { 938 while (--iovlen >= 0) {
937 int seglen = iov->iov_len; 939 int seglen = iov->iov_len;
938 unsigned char __user *from = iov->iov_base; 940 unsigned char __user *from = iov->iov_base;
@@ -958,8 +960,9 @@ new_segment:
958 if (!sk_stream_memory_free(sk)) 960 if (!sk_stream_memory_free(sk))
959 goto wait_for_sndbuf; 961 goto wait_for_sndbuf;
960 962
961 skb = sk_stream_alloc_skb(sk, select_size(sk), 963 skb = sk_stream_alloc_skb(sk,
962 sk->sk_allocation); 964 select_size(sk, sg),
965 sk->sk_allocation);
963 if (!skb) 966 if (!skb)
964 goto wait_for_memory; 967 goto wait_for_memory;
965 968
@@ -996,9 +999,7 @@ new_segment:
996 /* We can extend the last page 999 /* We can extend the last page
997 * fragment. */ 1000 * fragment. */
998 merge = 1; 1001 merge = 1;
999 } else if (i == MAX_SKB_FRAGS || 1002 } else if (i == MAX_SKB_FRAGS || !sg) {
1000 (!i &&
1001 !(sk->sk_route_caps & NETIF_F_SG))) {
1002 /* Need to add new fragment and cannot 1003 /* Need to add new fragment and cannot
1003 * do this because interface is non-SG, 1004 * do this because interface is non-SG,
1004 * or because all the page slots are 1005 * or because all the page slots are