| Submitter | Eric Dumazet |
|---|---|
| Date | April 3, 2012, 3:28 p.m. |
| Message ID | <1333466908.18626.274.camel@edumazet-glaptop> |
| Download | mbox | patch |
| Permalink | /patch/150466/ |
| State | Accepted |
| Delegated to: | David Miller |
| Headers | show |
Comments
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 03 Apr 2012 17:28:28 +0200 > unix_dgram_sendmsg() currently builds linear skbs, and this can stress > page allocator with high order page allocations. When memory gets > fragmented, this can eventually fail. > > We can try to use order-2 allocations for skb head (SKB_MAX_ALLOC) plus > up to 16 page fragments to lower pressure on buddy allocator. > > This patch has no effect on messages of less than 16064 bytes. > (on 64bit arches with PAGE_SIZE=4096) > > For bigger messages (from 16065 to 81600 bytes), this patch brings > reliability at the expense of performance penalty because of extra pages > allocations. > > netperf -t DG_STREAM -T 0,2 -- -m 16064 -s 200000 > ->4086040 Messages / 10s > > netperf -t DG_STREAM -T 0,2 -- -m 16068 -s 200000 > ->3901747 Messages / 10s > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> > --- > v2: use SKB_MAX_ALLOC instead of SKB_MAX_ORDER(0, 0) to not slow down > applications using up to 16000 bytes messages. Looks good, applied to net-next, thanks Eric! -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Patch
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index d510353..eadb902 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1442,6 +1442,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, long timeo; struct scm_cookie tmp_scm; int max_level; + int data_len = 0; if (NULL == siocb->scm) siocb->scm = &tmp_scm; @@ -1475,7 +1476,13 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, if (len > sk->sk_sndbuf - 32) goto out; - skb = sock_alloc_send_skb(sk, len, msg->msg_flags&MSG_DONTWAIT, &err); + if (len > SKB_MAX_ALLOC) + data_len = min_t(size_t, + len - SKB_MAX_ALLOC, + MAX_SKB_FRAGS * PAGE_SIZE); + + skb = sock_alloc_send_pskb(sk, len - data_len, data_len, + msg->msg_flags & MSG_DONTWAIT, &err); if (skb == NULL) goto out; @@ -1485,8 +1492,10 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, max_level = err + 1; unix_get_secdata(siocb->scm, skb); - skb_reset_transport_header(skb); - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + skb_put(skb, len - data_len); + skb->data_len = data_len; + skb->len = len; + err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len); if (err) goto out_free;
unix_dgram_sendmsg() currently builds linear skbs, and this can stress page allocator with high order page allocations. When memory gets fragmented, this can eventually fail. We can try to use order-2 allocations for skb head (SKB_MAX_ALLOC) plus up to 16 page fragments to lower pressure on buddy allocator. This patch has no effect on messages of less than 16064 bytes. (on 64bit arches with PAGE_SIZE=4096) For bigger messages (from 16065 to 81600 bytes), this patch brings reliability at the expense of performance penalty because of extra pages allocations. netperf -t DG_STREAM -T 0,2 -- -m 16064 -s 200000 ->4086040 Messages / 10s netperf -t DG_STREAM -T 0,2 -- -m 16068 -s 200000 ->3901747 Messages / 10s Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> --- v2: use SKB_MAX_ALLOC instead of SKB_MAX_ORDER(0, 0) to not slow down applications using up to 16000 bytes messages. net/unix/af_unix.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html