aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-05-06 18:02:07 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-06 18:37:57 -0400
commitbdc712b4c2baf9515887de3a52e7ecd89fafc0c7 (patch)
tree3ce09227fb75593256403eaa459d178a2668db25 /net/ipv4/ip_output.c
parentad638bd16d91012a512979327b5c17c867d260c6 (diff)
inet: Decrease overhead of on-stack inet_cork.
When we fast path datagram sends to avoid locking by putting the inet_cork on the stack we use up lots of space that isn't necessary. This is because inet_cork contains a "struct flowi" which isn't used in these code paths. Split inet_cork to two parts, "inet_cork" and "inet_cork_full". Only the latter of which has the "struct flowi" and is what is stored in inet_sock. Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r--net/ipv4/ip_output.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index db38c1822de8..eb0647a2f073 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1096,14 +1096,14 @@ int ip_append_data(struct sock *sk,
1096 return 0; 1096 return 0;
1097 1097
1098 if (skb_queue_empty(&sk->sk_write_queue)) { 1098 if (skb_queue_empty(&sk->sk_write_queue)) {
1099 err = ip_setup_cork(sk, &inet->cork, ipc, rtp); 1099 err = ip_setup_cork(sk, &inet->cork.base, ipc, rtp);
1100 if (err) 1100 if (err)
1101 return err; 1101 return err;
1102 } else { 1102 } else {
1103 transhdrlen = 0; 1103 transhdrlen = 0;
1104 } 1104 }
1105 1105
1106 return __ip_append_data(sk, &sk->sk_write_queue, &inet->cork, getfrag, 1106 return __ip_append_data(sk, &sk->sk_write_queue, &inet->cork.base, getfrag,
1107 from, length, transhdrlen, flags); 1107 from, length, transhdrlen, flags);
1108} 1108}
1109 1109
@@ -1114,6 +1114,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1114 struct sk_buff *skb; 1114 struct sk_buff *skb;
1115 struct rtable *rt; 1115 struct rtable *rt;
1116 struct ip_options *opt = NULL; 1116 struct ip_options *opt = NULL;
1117 struct inet_cork *cork;
1117 int hh_len; 1118 int hh_len;
1118 int mtu; 1119 int mtu;
1119 int len; 1120 int len;
@@ -1129,20 +1130,21 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1129 if (skb_queue_empty(&sk->sk_write_queue)) 1130 if (skb_queue_empty(&sk->sk_write_queue))
1130 return -EINVAL; 1131 return -EINVAL;
1131 1132
1132 rt = (struct rtable *)inet->cork.dst; 1133 cork = &inet->cork.base;
1133 if (inet->cork.flags & IPCORK_OPT) 1134 rt = (struct rtable *)cork->dst;
1134 opt = inet->cork.opt; 1135 if (cork->flags & IPCORK_OPT)
1136 opt = cork->opt;
1135 1137
1136 if (!(rt->dst.dev->features&NETIF_F_SG)) 1138 if (!(rt->dst.dev->features&NETIF_F_SG))
1137 return -EOPNOTSUPP; 1139 return -EOPNOTSUPP;
1138 1140
1139 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 1141 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
1140 mtu = inet->cork.fragsize; 1142 mtu = cork->fragsize;
1141 1143
1142 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0); 1144 fragheaderlen = sizeof(struct iphdr) + (opt ? opt->optlen : 0);
1143 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen; 1145 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen;
1144 1146
1145 if (inet->cork.length + size > 0xFFFF - fragheaderlen) { 1147 if (cork->length + size > 0xFFFF - fragheaderlen) {
1146 ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport, mtu); 1148 ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->inet_dport, mtu);
1147 return -EMSGSIZE; 1149 return -EMSGSIZE;
1148 } 1150 }
@@ -1150,7 +1152,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1150 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) 1152 if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
1151 return -EINVAL; 1153 return -EINVAL;
1152 1154
1153 inet->cork.length += size; 1155 cork->length += size;
1154 if ((size + skb->len > mtu) && 1156 if ((size + skb->len > mtu) &&
1155 (sk->sk_protocol == IPPROTO_UDP) && 1157 (sk->sk_protocol == IPPROTO_UDP) &&
1156 (rt->dst.dev->features & NETIF_F_UFO)) { 1158 (rt->dst.dev->features & NETIF_F_UFO)) {
@@ -1245,7 +1247,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1245 return 0; 1247 return 0;
1246 1248
1247error: 1249error:
1248 inet->cork.length -= size; 1250 cork->length -= size;
1249 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS); 1251 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
1250 return err; 1252 return err;
1251} 1253}
@@ -1396,7 +1398,7 @@ static void __ip_flush_pending_frames(struct sock *sk,
1396 1398
1397void ip_flush_pending_frames(struct sock *sk) 1399void ip_flush_pending_frames(struct sock *sk)
1398{ 1400{
1399 __ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork); 1401 __ip_flush_pending_frames(sk, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
1400} 1402}
1401 1403
1402struct sk_buff *ip_make_skb(struct sock *sk, 1404struct sk_buff *ip_make_skb(struct sock *sk,