Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932729AbcCBBbE (ORCPT ); Tue, 1 Mar 2016 20:31:04 -0500 Received: from mail333.us4.mandrillapp.com ([205.201.137.77]:34623 "EHLO mail333.us4.mandrillapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932091AbcCAXyq convert rfc822-to-8bit (ORCPT ); Tue, 1 Mar 2016 18:54:46 -0500 DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=mandrill; d=linuxfoundation.org; b=IE5Gx9GxCC5vfiJOCNPM3ZI3CHBo7YCMTY3rt106FhEhPGQCC/dcZirf1ZCGiPM4XOHmRdnGtWGn gApLMuyKeOidhtoBi1u30/zP1K0Oh97LtDPjninls/GM29T6Oz4aFC4K75rAzPF2CNrwcFyLLjtI am3U65gtJ2L8r20Mebo=; From: Greg Kroah-Hartman Subject: [PATCH 4.4 021/342] net:Add sysctl_max_skb_frags X-Mailer: git-send-email 2.7.2 To: Cc: Greg Kroah-Hartman , , Hans Westgaard Ry , =?utf-8?Q?H=C3=A5kon=20Bugge?= , Eric Dumazet , "David S. Miller" Message-Id: <20160301234528.673334897@linuxfoundation.org> In-Reply-To: <20160301234527.990448862@linuxfoundation.org> References: <20160301234527.990448862@linuxfoundation.org> X-Report-Abuse: Please forward a copy of this message, including all headers, to abuse@mandrill.com X-Report-Abuse: You can also report abuse here: http://mandrillapp.com/contact/abuse?id=30481620.8f037b6a027840658813482f4d1e3b49 X-Mandrill-User: md_30481620 Date: Tue, 01 Mar 2016 23:53:50 +0000 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2940 Lines: 95 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Hans Westgaard Ry [ Upstream commit 5f74f82ea34c0da80ea0b49192bb5ea06e063593 ] Devices may have limits on the number of fragments in an skb they support. Current codebase uses a constant as maximum for number of fragments one skb can hold and use. When enabling scatter/gather and running traffic with many small messages the codebase uses the maximum number of fragments and may thereby violate the max for certain devices. The patch introduces a global variable as max number of fragments. Signed-off-by: Hans Westgaard Ry Reviewed-by: HÃ¥kon Bugge Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/linux/skbuff.h | 1 + net/core/skbuff.c | 2 ++ net/core/sysctl_net_core.c | 10 ++++++++++ net/ipv4/tcp.c | 4 ++-- 4 files changed, 15 insertions(+), 2 deletions(-) --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -219,6 +219,7 @@ struct sk_buff; #else #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1) #endif +extern int sysctl_max_skb_frags; typedef struct skb_frag_struct skb_frag_t; --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -79,6 +79,8 @@ struct kmem_cache *skbuff_head_cache __read_mostly; static struct kmem_cache *skbuff_fclone_cache __read_mostly; +int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS; +EXPORT_SYMBOL(sysctl_max_skb_frags); /** * skb_panic - private function for out-of-line support --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -26,6 +26,7 @@ static int zero = 0; static int one = 1; static int min_sndbuf = SOCK_MIN_SNDBUF; static int min_rcvbuf = SOCK_MIN_RCVBUF; +static int max_skb_frags = MAX_SKB_FRAGS; static int net_msg_warn; /* Unused, but still a sysctl */ @@ -392,6 +393,15 @@ static struct ctl_table net_core_table[] .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "max_skb_frags", + .data = &sysctl_max_skb_frags, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &one, + .extra2 = &max_skb_frags, + }, { } }; --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -939,7 +939,7 @@ new_segment: i = skb_shinfo(skb)->nr_frags; can_coalesce = skb_can_coalesce(skb, i, page, offset); - if (!can_coalesce && i >= MAX_SKB_FRAGS) { + if (!can_coalesce && i >= sysctl_max_skb_frags) { tcp_mark_push(tp, skb); goto new_segment; } @@ -1212,7 +1212,7 @@ new_segment: if (!skb_can_coalesce(skb, i, pfrag->page, pfrag->offset)) { - if (i == MAX_SKB_FRAGS || !sg) { + if (i == sysctl_max_skb_frags || !sg) { tcp_mark_push(tp, skb); goto new_segment; }