Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1446682pxb; Wed, 10 Feb 2021 08:31:21 -0800 (PST) X-Google-Smtp-Source: ABdhPJyFYaB+dXY1EH/+hhm2O36Ylchp5qvq7XPl7M2hQDxmJVcT6L+JrsqcYmiIHTUjcy+UIl8O X-Received: by 2002:a17:906:f2cd:: with SMTP id gz13mr3733290ejb.83.1612974681347; Wed, 10 Feb 2021 08:31:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612974681; cv=none; d=google.com; s=arc-20160816; b=wXZy6AypkUkMsf3SfnAmhORt+IRxMJU8ewrN+q8hwWFFsOwCSb5METYJrk84RYCvXH pl7utvNeajsM58EtetrtbT7hIdsCLSQcncx7hW41R4rLiVk1Ks1Av83cMF/Lao/6xRW6 Vm3+hMOtZKyN5kKWO0ffu0nHfy5QMl3Lw8oXTfrmyBfv63Y4SY34410fHWeymlJ0QbUv DUImAJutMVDYtQHdx6s9e9/X+F6Syo9x1MDq/DtwLpq7G1gbPxWxeRYhfBN19b05xiug 36MZHim28C7IALgqHlV69+YmhP0wLaPXo8F9ndY1KQHF+3sONGr/sfM+OoSyK5HfG+mn FXsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:reply-to:cc:from:to :dkim-signature:date; bh=vxbPqVTP+yyafvrJZY9PHRZqLx4yQzye7I3rd2J7vYA=; b=x7HPfDM4a6sIhoA8RLjp+azxyz2SQG+SMAKL0j2U2MEyVUOkSM6WJUJp+Zdiw8Cl1B IhAJ39V+di7zfwjbNszt4EQ4zMqN1iHZ64XjuYRHkO0g2azFogJvcvSbN+VVC8SFnvtI nuW11RYW3xZ5bEQVRLppST4sYQi5/Kbsj1KUBMxIfhmKMXx3NJ0A7dlJqhA/ED1GABVl GOqPLyT/qchXcAc4JEoJ8EMsl3EUiU5XMxP16dHJG5esTJIB39P0gJOtvaZfI2gHd1OK mH5nv/PzQIYwIx6G7CGXGEtiUYUWP9c2EPyQsFuVmVtr5Z2EM0s5SuLyqZg73i8i6cRn ys9A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@pm.me header.s=protonmail header.b=EbxFHNC2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=pm.me Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a20si1638868edx.226.2021.02.10.08.30.57; Wed, 10 Feb 2021 08:31:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@pm.me header.s=protonmail header.b=EbxFHNC2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=pm.me Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232171AbhBJQaE (ORCPT + 99 others); Wed, 10 Feb 2021 11:30:04 -0500 Received: from mail2.protonmail.ch ([185.70.40.22]:26627 "EHLO mail2.protonmail.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232455AbhBJQ33 (ORCPT ); Wed, 10 Feb 2021 11:29:29 -0500 Date: Wed, 10 Feb 2021 16:28:35 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pm.me; s=protonmail; t=1612974524; bh=vxbPqVTP+yyafvrJZY9PHRZqLx4yQzye7I3rd2J7vYA=; h=Date:To:From:Cc:Reply-To:Subject:In-Reply-To:References:From; b=EbxFHNC20eEJDuv+NCounvy7JGbNTqrrASRJCqFaH1NPfAdd9noeNXRGDnYZx4zix LF2yc7A8pi/w+kp9fDgDgwuciz7cgX9HwseajCwWCrt8eDUfHDvZmM7LCYaKSZHeOS nM+bBLkkWw7zo5ltbIj10shwfB6izlJYG9wPgKzVxVpmUhq9POv+bfW5BJQRcba5Bg iIwWu06b6gEg5C3BB1w2E/e5nYRJyi0DOpXDskih0YMv8+9iaK8hEa8ogIa6Defy+D JaMWRYe9RHaT7EdoG8uN142USIrOri36vpQpk/Zh2bvIwUOaBIRApQWjaen6vAJ/SV n+Ww9u4hU6doQ== To: "David S. Miller" , Jakub Kicinski From: Alexander Lobakin Cc: Jonathan Lemon , Eric Dumazet , Dmitry Vyukov , Willem de Bruijn , Alexander Lobakin , Randy Dunlap , Kevin Hao , Pablo Neira Ayuso , Jakub Sitnicki , Marco Elver , Dexuan Cui , Paolo Abeni , Jesper Dangaard Brouer , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Taehee Yoo , Cong Wang , =?utf-8?Q?Bj=C3=B6rn_T=C3=B6pel?= , Miaohe Lin , Guillaume Nault , Yonghong Song , zhudi , Michal Kubecek , Marcelo Ricardo Leitner , Dmitry Safonov <0x7f454c46@gmail.com>, Yang Yingliang , Florian Westphal , Edward Cree , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Reply-To: Alexander Lobakin Subject: [PATCH v4 net-next 01/11] skbuff: move __alloc_skb() next to the other skb allocation functions Message-ID: <20210210162732.80467-2-alobakin@pm.me> In-Reply-To: <20210210162732.80467-1-alobakin@pm.me> References: <20210210162732.80467-1-alobakin@pm.me> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-1.2 required=10.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on mailout.protonmail.ch Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In preparation before reusing several functions in all three skb allocation variants, move __alloc_skb() next to the __netdev_alloc_skb() and __napi_alloc_skb(). No functional changes. Signed-off-by: Alexander Lobakin --- net/core/skbuff.c | 284 +++++++++++++++++++++++----------------------- 1 file changed, 142 insertions(+), 142 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d380c7b5a12d..a0f846872d19 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -119,148 +119,6 @@ static void skb_under_panic(struct sk_buff *skb, unsi= gned int sz, void *addr) =09skb_panic(skb, sz, addr, __func__); } =20 -/* - * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tell= s - * the caller if emergency pfmemalloc reserves are being used. If it is an= d - * the socket is later found to be SOCK_MEMALLOC then PFMEMALLOC reserves - * may be used. Otherwise, the packet data may be discarded until enough - * memory is free - */ -#define kmalloc_reserve(size, gfp, node, pfmemalloc) \ -=09 __kmalloc_reserve(size, gfp, node, _RET_IP_, pfmemalloc) - -static void *__kmalloc_reserve(size_t size, gfp_t flags, int node, -=09=09=09 unsigned long ip, bool *pfmemalloc) -{ -=09void *obj; -=09bool ret_pfmemalloc =3D false; - -=09/* -=09 * Try a regular allocation, when that fails and we're not entitled -=09 * to the reserves, fail. -=09 */ -=09obj =3D kmalloc_node_track_caller(size, -=09=09=09=09=09flags | __GFP_NOMEMALLOC | __GFP_NOWARN, -=09=09=09=09=09node); -=09if (obj || !(gfp_pfmemalloc_allowed(flags))) -=09=09goto out; - -=09/* Try again but now we are using pfmemalloc reserves */ -=09ret_pfmemalloc =3D true; -=09obj =3D kmalloc_node_track_caller(size, flags, node); - -out: -=09if (pfmemalloc) -=09=09*pfmemalloc =3D ret_pfmemalloc; - -=09return obj; -} - -/* =09Allocate a new skbuff. We do this ourselves so we can fill in a few - *=09'private' fields and also do memory statistics to find all the - *=09[BEEP] leaks. - * - */ - -/** - *=09__alloc_skb=09-=09allocate a network buffer - *=09@size: size to allocate - *=09@gfp_mask: allocation mask - *=09@flags: If SKB_ALLOC_FCLONE is set, allocate from fclone cache - *=09=09instead of head cache and allocate a cloned (child) skb. - *=09=09If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for - *=09=09allocations in case the data is required for writeback - *=09@node: numa node to allocate memory on - * - *=09Allocate a new &sk_buff. The returned buffer has no headroom and a - *=09tail room of at least size bytes. The object has a reference count - *=09of one. The return is the buffer. On a failure the return is %NULL. - * - *=09Buffers may only be allocated from interrupts using a @gfp_mask of - *=09%GFP_ATOMIC. - */ -struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, -=09=09=09 int flags, int node) -{ -=09struct kmem_cache *cache; -=09struct skb_shared_info *shinfo; -=09struct sk_buff *skb; -=09u8 *data; -=09bool pfmemalloc; - -=09cache =3D (flags & SKB_ALLOC_FCLONE) -=09=09? skbuff_fclone_cache : skbuff_head_cache; - -=09if (sk_memalloc_socks() && (flags & SKB_ALLOC_RX)) -=09=09gfp_mask |=3D __GFP_MEMALLOC; - -=09/* Get the HEAD */ -=09skb =3D kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); -=09if (!skb) -=09=09goto out; -=09prefetchw(skb); - -=09/* We do our best to align skb_shared_info on a separate cache -=09 * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives -=09 * aligned memory blocks, unless SLUB/SLAB debug is enabled. -=09 * Both skb->head and skb_shared_info are cache line aligned. -=09 */ -=09size =3D SKB_DATA_ALIGN(size); -=09size +=3D SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -=09data =3D kmalloc_reserve(size, gfp_mask, node, &pfmemalloc); -=09if (!data) -=09=09goto nodata; -=09/* kmalloc(size) might give us more room than requested. -=09 * Put skb_shared_info exactly at the end of allocated zone, -=09 * to allow max possible filling before reallocation. -=09 */ -=09size =3D SKB_WITH_OVERHEAD(ksize(data)); -=09prefetchw(data + size); - -=09/* -=09 * Only clear those fields we need to clear, not those that we will -=09 * actually initialise below. Hence, don't put any more fields after -=09 * the tail pointer in struct sk_buff! -=09 */ -=09memset(skb, 0, offsetof(struct sk_buff, tail)); -=09/* Account for allocated memory : skb + skb->head */ -=09skb->truesize =3D SKB_TRUESIZE(size); -=09skb->pfmemalloc =3D pfmemalloc; -=09refcount_set(&skb->users, 1); -=09skb->head =3D data; -=09skb->data =3D data; -=09skb_reset_tail_pointer(skb); -=09skb->end =3D skb->tail + size; -=09skb->mac_header =3D (typeof(skb->mac_header))~0U; -=09skb->transport_header =3D (typeof(skb->transport_header))~0U; - -=09/* make sure we initialize shinfo sequentially */ -=09shinfo =3D skb_shinfo(skb); -=09memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); -=09atomic_set(&shinfo->dataref, 1); - -=09if (flags & SKB_ALLOC_FCLONE) { -=09=09struct sk_buff_fclones *fclones; - -=09=09fclones =3D container_of(skb, struct sk_buff_fclones, skb1); - -=09=09skb->fclone =3D SKB_FCLONE_ORIG; -=09=09refcount_set(&fclones->fclone_ref, 1); - -=09=09fclones->skb2.fclone =3D SKB_FCLONE_CLONE; -=09} - -=09skb_set_kcov_handle(skb, kcov_common_handle()); - -out: -=09return skb; -nodata: -=09kmem_cache_free(cache, skb); -=09skb =3D NULL; -=09goto out; -} -EXPORT_SYMBOL(__alloc_skb); - /* Caller must provide SKB that is memset cleared */ static struct sk_buff *__build_skb_around(struct sk_buff *skb, =09=09=09=09=09 void *data, unsigned int frag_size) @@ -408,6 +266,148 @@ void *__netdev_alloc_frag_align(unsigned int fragsz, = unsigned int align_mask) } EXPORT_SYMBOL(__netdev_alloc_frag_align); =20 +/* + * kmalloc_reserve is a wrapper around kmalloc_node_track_caller that tell= s + * the caller if emergency pfmemalloc reserves are being used. If it is an= d + * the socket is later found to be SOCK_MEMALLOC then PFMEMALLOC reserves + * may be used. Otherwise, the packet data may be discarded until enough + * memory is free + */ +#define kmalloc_reserve(size, gfp, node, pfmemalloc) \ +=09 __kmalloc_reserve(size, gfp, node, _RET_IP_, pfmemalloc) + +static void *__kmalloc_reserve(size_t size, gfp_t flags, int node, +=09=09=09 unsigned long ip, bool *pfmemalloc) +{ +=09void *obj; +=09bool ret_pfmemalloc =3D false; + +=09/* +=09 * Try a regular allocation, when that fails and we're not entitled +=09 * to the reserves, fail. +=09 */ +=09obj =3D kmalloc_node_track_caller(size, +=09=09=09=09=09flags | __GFP_NOMEMALLOC | __GFP_NOWARN, +=09=09=09=09=09node); +=09if (obj || !(gfp_pfmemalloc_allowed(flags))) +=09=09goto out; + +=09/* Try again but now we are using pfmemalloc reserves */ +=09ret_pfmemalloc =3D true; +=09obj =3D kmalloc_node_track_caller(size, flags, node); + +out: +=09if (pfmemalloc) +=09=09*pfmemalloc =3D ret_pfmemalloc; + +=09return obj; +} + +/* =09Allocate a new skbuff. We do this ourselves so we can fill in a few + *=09'private' fields and also do memory statistics to find all the + *=09[BEEP] leaks. + * + */ + +/** + *=09__alloc_skb=09-=09allocate a network buffer + *=09@size: size to allocate + *=09@gfp_mask: allocation mask + *=09@flags: If SKB_ALLOC_FCLONE is set, allocate from fclone cache + *=09=09instead of head cache and allocate a cloned (child) skb. + *=09=09If SKB_ALLOC_RX is set, __GFP_MEMALLOC will be used for + *=09=09allocations in case the data is required for writeback + *=09@node: numa node to allocate memory on + * + *=09Allocate a new &sk_buff. The returned buffer has no headroom and a + *=09tail room of at least size bytes. The object has a reference count + *=09of one. The return is the buffer. On a failure the return is %NULL. + * + *=09Buffers may only be allocated from interrupts using a @gfp_mask of + *=09%GFP_ATOMIC. + */ +struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, +=09=09=09 int flags, int node) +{ +=09struct kmem_cache *cache; +=09struct skb_shared_info *shinfo; +=09struct sk_buff *skb; +=09u8 *data; +=09bool pfmemalloc; + +=09cache =3D (flags & SKB_ALLOC_FCLONE) +=09=09? skbuff_fclone_cache : skbuff_head_cache; + +=09if (sk_memalloc_socks() && (flags & SKB_ALLOC_RX)) +=09=09gfp_mask |=3D __GFP_MEMALLOC; + +=09/* Get the HEAD */ +=09skb =3D kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node); +=09if (!skb) +=09=09goto out; +=09prefetchw(skb); + +=09/* We do our best to align skb_shared_info on a separate cache +=09 * line. It usually works because kmalloc(X > SMP_CACHE_BYTES) gives +=09 * aligned memory blocks, unless SLUB/SLAB debug is enabled. +=09 * Both skb->head and skb_shared_info are cache line aligned. +=09 */ +=09size =3D SKB_DATA_ALIGN(size); +=09size +=3D SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +=09data =3D kmalloc_reserve(size, gfp_mask, node, &pfmemalloc); +=09if (!data) +=09=09goto nodata; +=09/* kmalloc(size) might give us more room than requested. +=09 * Put skb_shared_info exactly at the end of allocated zone, +=09 * to allow max possible filling before reallocation. +=09 */ +=09size =3D SKB_WITH_OVERHEAD(ksize(data)); +=09prefetchw(data + size); + +=09/* +=09 * Only clear those fields we need to clear, not those that we will +=09 * actually initialise below. Hence, don't put any more fields after +=09 * the tail pointer in struct sk_buff! +=09 */ +=09memset(skb, 0, offsetof(struct sk_buff, tail)); +=09/* Account for allocated memory : skb + skb->head */ +=09skb->truesize =3D SKB_TRUESIZE(size); +=09skb->pfmemalloc =3D pfmemalloc; +=09refcount_set(&skb->users, 1); +=09skb->head =3D data; +=09skb->data =3D data; +=09skb_reset_tail_pointer(skb); +=09skb->end =3D skb->tail + size; +=09skb->mac_header =3D (typeof(skb->mac_header))~0U; +=09skb->transport_header =3D (typeof(skb->transport_header))~0U; + +=09/* make sure we initialize shinfo sequentially */ +=09shinfo =3D skb_shinfo(skb); +=09memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); +=09atomic_set(&shinfo->dataref, 1); + +=09if (flags & SKB_ALLOC_FCLONE) { +=09=09struct sk_buff_fclones *fclones; + +=09=09fclones =3D container_of(skb, struct sk_buff_fclones, skb1); + +=09=09skb->fclone =3D SKB_FCLONE_ORIG; +=09=09refcount_set(&fclones->fclone_ref, 1); + +=09=09fclones->skb2.fclone =3D SKB_FCLONE_CLONE; +=09} + +=09skb_set_kcov_handle(skb, kcov_common_handle()); + +out: +=09return skb; +nodata: +=09kmem_cache_free(cache, skb); +=09skb =3D NULL; +=09goto out; +} +EXPORT_SYMBOL(__alloc_skb); + /** *=09__netdev_alloc_skb - allocate an skbuff for rx on a specific device *=09@dev: network device to receive on --=20 2.30.1