diff options
-rw-r--r-- | include/linux/skbuff.h | 5 | ||||
-rw-r--r-- | net/core/skbuff.c | 18 | ||||
-rw-r--r-- | net/core/sock.c | 2 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 14 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 3 | ||||
-rw-r--r-- | net/iucv/af_iucv.c | 2 | ||||
-rw-r--r-- | net/sctp/protocol.c | 2 |
8 files changed, 32 insertions, 19 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index ac6b05a325cc..64f86951ef74 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -46,6 +46,11 @@ | |||
46 | #define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0)) | 46 | #define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0)) |
47 | #define SKB_MAX_ALLOC (SKB_MAX_ORDER(0, 2)) | 47 | #define SKB_MAX_ALLOC (SKB_MAX_ORDER(0, 2)) |
48 | 48 | ||
49 | /* return minimum truesize of one skb containing X bytes of data */ | ||
50 | #define SKB_TRUESIZE(X) ((X) + \ | ||
51 | SKB_DATA_ALIGN(sizeof(struct sk_buff)) + \ | ||
52 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | ||
53 | |||
49 | /* A. Checksumming of received packets by device. | 54 | /* A. Checksumming of received packets by device. |
50 | * | 55 | * |
51 | * NONE: device failed to checksum this packet. | 56 | * NONE: device failed to checksum this packet. |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5b2c5f1d4dba..a7f855dca922 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -184,11 +184,20 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
184 | goto out; | 184 | goto out; |
185 | prefetchw(skb); | 185 | prefetchw(skb); |
186 | 186 | ||
187 | size = SKB_DATA_ALIGN(size); | 187 | /* We do our best to align skb_shared_info on a separate cache |
188 | data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), | 188 | * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives |
189 | gfp_mask, node); | 189 | * aligned memory blocks, unless SLUB/SLAB debug is enabled. |
190 | * Both skb->head and skb_shared_info are cache line aligned. | ||
191 | */ | ||
192 | size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
193 | data = kmalloc_node_track_caller(size, gfp_mask, node); | ||
190 | if (!data) | 194 | if (!data) |
191 | goto nodata; | 195 | goto nodata; |
196 | /* kmalloc(size) might give us more room than requested. | ||
197 | * Put skb_shared_info exactly at the end of allocated zone, | ||
198 | * to allow max possible filling before reallocation. | ||
199 | */ | ||
200 | size = SKB_WITH_OVERHEAD(ksize(data)); | ||
192 | prefetchw(data + size); | 201 | prefetchw(data + size); |
193 | 202 | ||
194 | /* | 203 | /* |
@@ -197,7 +206,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
197 | * the tail pointer in struct sk_buff! | 206 | * the tail pointer in struct sk_buff! |
198 | */ | 207 | */ |
199 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 208 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
200 | skb->truesize = size + sizeof(struct sk_buff); | 209 | /* Account for allocated memory : skb + skb->head */ |
210 | skb->truesize = SKB_TRUESIZE(size); | ||
201 | atomic_set(&skb->users, 1); | 211 | atomic_set(&skb->users, 1); |
202 | skb->head = data; | 212 | skb->head = data; |
203 | skb->data = data; | 213 | skb->data = data; |
diff --git a/net/core/sock.c b/net/core/sock.c index 83c462d3f451..5a087626bb3a 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -207,7 +207,7 @@ static struct lock_class_key af_callback_keys[AF_MAX]; | |||
207 | * not depend upon such differences. | 207 | * not depend upon such differences. |
208 | */ | 208 | */ |
209 | #define _SK_MEM_PACKETS 256 | 209 | #define _SK_MEM_PACKETS 256 |
210 | #define _SK_MEM_OVERHEAD (sizeof(struct sk_buff) + 256) | 210 | #define _SK_MEM_OVERHEAD SKB_TRUESIZE(256) |
211 | #define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) | 211 | #define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) |
212 | #define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) | 212 | #define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS) |
213 | 213 | ||
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 23ef31baa1af..ab188ae12fd9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -1152,10 +1152,9 @@ static int __net_init icmp_sk_init(struct net *net) | |||
1152 | net->ipv4.icmp_sk[i] = sk; | 1152 | net->ipv4.icmp_sk[i] = sk; |
1153 | 1153 | ||
1154 | /* Enough space for 2 64K ICMP packets, including | 1154 | /* Enough space for 2 64K ICMP packets, including |
1155 | * sk_buff struct overhead. | 1155 | * sk_buff/skb_shared_info struct overhead. |
1156 | */ | 1156 | */ |
1157 | sk->sk_sndbuf = | 1157 | sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024); |
1158 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | ||
1159 | 1158 | ||
1160 | /* | 1159 | /* |
1161 | * Speedup sock_wfree() | 1160 | * Speedup sock_wfree() |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 81cae641c9a9..c1653fe47255 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -265,8 +265,7 @@ static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th) | |||
265 | 265 | ||
266 | static void tcp_fixup_sndbuf(struct sock *sk) | 266 | static void tcp_fixup_sndbuf(struct sock *sk) |
267 | { | 267 | { |
268 | int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + | 268 | int sndmem = SKB_TRUESIZE(tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER); |
269 | sizeof(struct sk_buff); | ||
270 | 269 | ||
271 | if (sk->sk_sndbuf < 3 * sndmem) { | 270 | if (sk->sk_sndbuf < 3 * sndmem) { |
272 | sk->sk_sndbuf = 3 * sndmem; | 271 | sk->sk_sndbuf = 3 * sndmem; |
@@ -349,7 +348,7 @@ static void tcp_grow_window(struct sock *sk, struct sk_buff *skb) | |||
349 | static void tcp_fixup_rcvbuf(struct sock *sk) | 348 | static void tcp_fixup_rcvbuf(struct sock *sk) |
350 | { | 349 | { |
351 | struct tcp_sock *tp = tcp_sk(sk); | 350 | struct tcp_sock *tp = tcp_sk(sk); |
352 | int rcvmem = tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff); | 351 | int rcvmem = SKB_TRUESIZE(tp->advmss + MAX_TCP_HEADER); |
353 | 352 | ||
354 | /* Try to select rcvbuf so that 4 mss-sized segments | 353 | /* Try to select rcvbuf so that 4 mss-sized segments |
355 | * will fit to window and corresponding skbs will fit to our rcvbuf. | 354 | * will fit to window and corresponding skbs will fit to our rcvbuf. |
@@ -540,8 +539,7 @@ void tcp_rcv_space_adjust(struct sock *sk) | |||
540 | space /= tp->advmss; | 539 | space /= tp->advmss; |
541 | if (!space) | 540 | if (!space) |
542 | space = 1; | 541 | space = 1; |
543 | rcvmem = (tp->advmss + MAX_TCP_HEADER + | 542 | rcvmem = SKB_TRUESIZE(tp->advmss + MAX_TCP_HEADER); |
544 | 16 + sizeof(struct sk_buff)); | ||
545 | while (tcp_win_from_space(rcvmem) < tp->advmss) | 543 | while (tcp_win_from_space(rcvmem) < tp->advmss) |
546 | rcvmem += 128; | 544 | rcvmem += 128; |
547 | space *= rcvmem; | 545 | space *= rcvmem; |
@@ -4950,8 +4948,10 @@ static void tcp_new_space(struct sock *sk) | |||
4950 | struct tcp_sock *tp = tcp_sk(sk); | 4948 | struct tcp_sock *tp = tcp_sk(sk); |
4951 | 4949 | ||
4952 | if (tcp_should_expand_sndbuf(sk)) { | 4950 | if (tcp_should_expand_sndbuf(sk)) { |
4953 | int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) + | 4951 | int sndmem = SKB_TRUESIZE(max_t(u32, |
4954 | MAX_TCP_HEADER + 16 + sizeof(struct sk_buff); | 4952 | tp->rx_opt.mss_clamp, |
4953 | tp->mss_cache) + | ||
4954 | MAX_TCP_HEADER); | ||
4955 | int demanded = max_t(unsigned int, tp->snd_cwnd, | 4955 | int demanded = max_t(unsigned int, tp->snd_cwnd, |
4956 | tp->reordering + 1); | 4956 | tp->reordering + 1); |
4957 | sndmem *= 2 * demanded; | 4957 | sndmem *= 2 * demanded; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 2b59154c65d3..90868fb42757 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -835,8 +835,7 @@ static int __net_init icmpv6_sk_init(struct net *net) | |||
835 | /* Enough space for 2 64K ICMP packets, including | 835 | /* Enough space for 2 64K ICMP packets, including |
836 | * sk_buff struct overhead. | 836 | * sk_buff struct overhead. |
837 | */ | 837 | */ |
838 | sk->sk_sndbuf = | 838 | sk->sk_sndbuf = 2 * SKB_TRUESIZE(64 * 1024); |
839 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | ||
840 | } | 839 | } |
841 | return 0; | 840 | return 0; |
842 | 841 | ||
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index c39f3a43cd80..274d150320c0 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1819,7 +1819,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) | |||
1819 | goto save_message; | 1819 | goto save_message; |
1820 | 1820 | ||
1821 | len = atomic_read(&sk->sk_rmem_alloc); | 1821 | len = atomic_read(&sk->sk_rmem_alloc); |
1822 | len += iucv_msg_length(msg) + sizeof(struct sk_buff); | 1822 | len += SKB_TRUESIZE(iucv_msg_length(msg)); |
1823 | if (len > sk->sk_rcvbuf) | 1823 | if (len > sk->sk_rcvbuf) |
1824 | goto save_message; | 1824 | goto save_message; |
1825 | 1825 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 91784f44a2e2..61b9fca5a173 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1299,7 +1299,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1299 | max_share = min(4UL*1024*1024, limit); | 1299 | max_share = min(4UL*1024*1024, limit); |
1300 | 1300 | ||
1301 | sysctl_sctp_rmem[0] = SK_MEM_QUANTUM; /* give each asoc 1 page min */ | 1301 | sysctl_sctp_rmem[0] = SK_MEM_QUANTUM; /* give each asoc 1 page min */ |
1302 | sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1)); | 1302 | sysctl_sctp_rmem[1] = 1500 * SKB_TRUESIZE(1); |
1303 | sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share); | 1303 | sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share); |
1304 | 1304 | ||
1305 | sysctl_sctp_wmem[0] = SK_MEM_QUANTUM; | 1305 | sysctl_sctp_wmem[0] = SK_MEM_QUANTUM; |