From patchwork Thu Mar 28 13:38:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608541 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70AEAC54E67 for ; Thu, 28 Mar 2024 13:40:50 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DFE436B0082; Thu, 28 Mar 2024 09:40:49 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DAE7D6B0085; Thu, 28 Mar 2024 09:40:49 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C76056B0087; Thu, 28 Mar 2024 09:40:49 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id A57166B0082 for ; Thu, 28 Mar 2024 09:40:49 -0400 (EDT) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 60A50C0A9D for ; Thu, 28 Mar 2024 13:40:49 +0000 (UTC) X-FDA: 81946558218.22.958FE08 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf08.hostedemail.com (Postfix) with ESMTP id D2A6916002A for ; Thu, 28 Mar 2024 13:40:45 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf08.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633247; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1mZb441prnLIWBf88thZZIiE+IgI/ozzV6po0oi/dlI=; b=w8SSW1x7e1QsjvEGW3IetUmnZQsPWNaoVELRubQfIZWvS5ZxEcP4ptz4ciEu0hGSfbNau+ 4DtxQYxcPYd63p4IkR/2sanYEkgjtxes/CkxBGrBmkfe2Qg2BU2YQIIHPNv4imUF4qzQfB 1NKNa6D2DiDGYWu8yNO7viv5w+2ZB9U= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf08.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633247; a=rsa-sha256; cv=none; b=fnrU7FbsjOo7qcAscRfW/JpwZDWe1XmhKXVJ85bnRB4IdlYFpl8NutNeH5T7TPvYWTBdom cmSl0EixSXImrd4kKwMmIVpIRN0FyjZ/o6vCbTVuSgi4EuaojWLCutkaYD8+YGcYkdAK5X M043l2D9W6VsxCAIMHiQKRMXlq8CzCc= Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4V54Nb63b1zXjvm; Thu, 28 Mar 2024 21:37:51 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id A17DE1400CD; Thu, 28 Mar 2024 21:40:40 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:40 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , David Howells , Andrew Morton , Subject: [PATCH RFC 01/10] mm: Move the page fragment allocator from page_alloc into its own file Date: Thu, 28 Mar 2024 21:38:30 +0800 Message-ID: <20240328133839.13620-2-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: D2A6916002A X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: 7aymacp3dk8gje1ghm3ny79n33izaos9 X-HE-Tag: 1711633245-233327 X-HE-Meta: U2FsdGVkX1+52oDA900yN+kjAAEcZRxMNLq/g6nPgk5EuuSx0fsevQY0mInZLqXQ8cAqakXdLg04GgTKT17YGWT6B6m9xfp92Bw+jce2XrsS8/IGisWATtafyv1Ky3CDx06RXYUhqwiN5xLBLn9ay+TN40WTETGHuzMF9KGOhWXpG2YOA38xst+jicLDu4b6Jajmb2/5HmRk5Ve7DQfiR2AmF6nHudsw8Bk7UnTklIEkhmbMVQxxnkXiGc0QbedppW883hiz1xv1Q1aLsTzY84gLTq7LRMZz2BpLZxz8a2m8RQqPSaqjPR1NZmMGvDvw1GiZ5pABTtCxN1DstjRX6Gxj1XdEtNVE5iRY6aW4s4vGsKSC+4NffDmIZjn2mZJO7vjrYc8qWcw2SPzV9I2EfdWwC0ECJkKBo1md/MbrweArEq401IhPwCKwbUEJxzpmUMn2cKU/ETZegCvMY9aEKfSlwJLGlvy6EgJXS9m6l7LRM8pXCHhsoepTRt6GMd2DVNVkLnviIX73BMwksKcrXaMFTDVAInmDnQneLmiJ/LTV5oXM8semPaVCZ7v9qhN9QfgNBMlBa3odgVfzXAQKhim2W6NimTmp15uv81PxdLqZyt1QwGxtOTZi75rlkzIep7dV1HtTzCPqIVJnKfZpU96cf0EONhHy++GYO5a3FSfDlw49spKqfENUfr9q13hzPqiUHAea8JhRKUjNdnuy26H2VzmvtPwBLtqvHBWtwop2TVnl5rG63K7HXxbVDyd4eQwaOiDDWTt/y4o9aAHC8xvxNQtcW5upwy8QTJbDz3UWbD6vh72ZwpBcMnAN2cXM8EA0gcT49QUzWVOZPNGLu9xcl0RnWUBf0A7A+0sBzA3SVNKeBx+rv1i0ua2AoiQK7duAvq+dQuw= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Inspired by [1], but use free_unref_page() to replace free_the_page() instead of __free_pages(), use VM_BUG_ON() to catch that we can use free_unref_page() directly, also add its own header file. As the API is only used by the networking, it may make sense to move it to the networking directory like the page_pool does in the future if we can make the free_unref_page() callable outside of the mm subsystem. And we can utilize that to decouple the 'struct page' in the networking subsystem in the future. 1. https://lore.kernel.org/all/20230411160902.4134381-3-dhowells@redhat.com/ CC: David Howells Signed-off-by: Yunsheng Lin --- include/linux/gfp.h | 22 ----- include/linux/mm_types.h | 18 ---- include/linux/page_frag_cache.h | 47 ++++++++++ include/linux/skbuff.h | 1 + mm/Makefile | 1 + mm/page_alloc.c | 136 ----------------------------- mm/page_frag_alloc.c | 149 ++++++++++++++++++++++++++++++++ 7 files changed, 198 insertions(+), 176 deletions(-) create mode 100644 include/linux/page_frag_cache.h create mode 100644 mm/page_frag_alloc.c diff --git a/include/linux/gfp.h b/include/linux/gfp.h index c775ea3c6015..5afeab2b906f 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -310,28 +310,6 @@ __meminit void *alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask) __al extern void __free_pages(struct page *page, unsigned int order); extern void free_pages(unsigned long addr, unsigned int order); -struct page_frag_cache; -void page_frag_cache_drain(struct page_frag_cache *nc); -extern void __page_frag_cache_drain(struct page *page, unsigned int count); -void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask, unsigned int align_mask); - -static inline void *page_frag_alloc_align(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask, - unsigned int align) -{ - WARN_ON_ONCE(!is_power_of_2(align)); - return __page_frag_alloc_align(nc, fragsz, gfp_mask, -align); -} - -static inline void *page_frag_alloc(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask) -{ - return __page_frag_alloc_align(nc, fragsz, gfp_mask, ~0u); -} - -extern void page_frag_free(void *addr); - #define __free_page(page) __free_pages((page), 0) #define free_page(addr) free_pages((addr), 0) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 5240bd7bca33..78a92b4475a7 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -504,9 +504,6 @@ static_assert(sizeof(struct ptdesc) <= sizeof(struct page)); */ #define STRUCT_PAGE_MAX_SHIFT (order_base_2(sizeof(struct page))) -#define PAGE_FRAG_CACHE_MAX_SIZE __ALIGN_MASK(32768, ~PAGE_MASK) -#define PAGE_FRAG_CACHE_MAX_ORDER get_order(PAGE_FRAG_CACHE_MAX_SIZE) - /* * page_private can be used on tail pages. However, PagePrivate is only * checked by the VM on the head page. So page_private on the tail pages @@ -525,21 +522,6 @@ static inline void *folio_get_private(struct folio *folio) return folio->private; } -struct page_frag_cache { - void * va; -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - __u16 offset; - __u16 size; -#else - __u32 offset; -#endif - /* we maintain a pagecount bias, so that we dont dirty cache line - * containing page->_refcount every time we allocate a fragment. - */ - unsigned int pagecnt_bias; - bool pfmemalloc; -}; - typedef unsigned long vm_flags_t; /* diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h new file mode 100644 index 000000000000..04810d8d6a7d --- /dev/null +++ b/include/linux/page_frag_cache.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_PAGE_FRAG_CACHE_H +#define _LINUX_PAGE_FRAG_CACHE_H + +#include + +#define PAGE_FRAG_CACHE_MAX_SIZE __ALIGN_MASK(32768, ~PAGE_MASK) +#define PAGE_FRAG_CACHE_MAX_ORDER get_order(PAGE_FRAG_CACHE_MAX_SIZE) + +struct page_frag_cache { + void *va; +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + __u16 offset; + __u16 size; +#else + __u32 offset; +#endif + /* we maintain a pagecount bias, so that we dont dirty cache line + * containing page->_refcount every time we allocate a fragment. + */ + unsigned int pagecnt_bias; + bool pfmemalloc; +}; + +void page_frag_cache_drain(struct page_frag_cache *nc); +void __page_frag_cache_drain(struct page *page, unsigned int count); +void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask, unsigned int align_mask); + +static inline void *page_frag_alloc_align(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask, + unsigned int align) +{ + WARN_ON_ONCE(!is_power_of_2(align)); + return __page_frag_alloc_align(nc, fragsz, gfp_mask, -align); +} + +static inline void *page_frag_alloc(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask) +{ + return page_frag_alloc_align(nc, fragsz, gfp_mask, ~0u); +} + +void page_frag_free(void *addr); + +#endif diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b945af8a6208..7f68199fee34 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #if IS_ENABLED(CONFIG_NF_CONNTRACK) #include diff --git a/mm/Makefile b/mm/Makefile index e4b5b75aaec9..6083f3dd7cc3 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -60,6 +60,7 @@ page-alloc-$(CONFIG_SHUFFLE_PAGE_ALLOCATOR) += shuffle.o memory-hotplug-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o obj-y += page-alloc.o +obj-y += page_frag_alloc.o obj-y += init-mm.o obj-y += memblock.o obj-y += $(memory-hotplug-y) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 14d39f34d336..2308360d78eb 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4675,142 +4675,6 @@ void free_pages(unsigned long addr, unsigned int order) EXPORT_SYMBOL(free_pages); -/* - * Page Fragment: - * An arbitrary-length arbitrary-offset area of memory which resides - * within a 0 or higher order page. Multiple fragments within that page - * are individually refcounted, in the page's reference counter. - * - * The page_frag functions below provide a simple allocation framework for - * page fragments. This is used by the network stack and network device - * drivers to provide a backing region of memory for use as either an - * sk_buff->head, or to be used in the "frags" portion of skb_shared_info. - */ -static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, - gfp_t gfp_mask) -{ - struct page *page = NULL; - gfp_t gfp = gfp_mask; - -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - gfp_mask = (gfp_mask & ~__GFP_DIRECT_RECLAIM) | __GFP_COMP | - __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC; - page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, - PAGE_FRAG_CACHE_MAX_ORDER); - nc->size = page ? PAGE_FRAG_CACHE_MAX_SIZE : PAGE_SIZE; -#endif - if (unlikely(!page)) - page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); - - nc->va = page ? page_address(page) : NULL; - - return page; -} - -void page_frag_cache_drain(struct page_frag_cache *nc) -{ - if (!nc->va) - return; - - __page_frag_cache_drain(virt_to_head_page(nc->va), nc->pagecnt_bias); - nc->va = NULL; -} -EXPORT_SYMBOL(page_frag_cache_drain); - -void __page_frag_cache_drain(struct page *page, unsigned int count) -{ - VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); - - if (page_ref_sub_and_test(page, count)) - free_the_page(page, compound_order(page)); -} -EXPORT_SYMBOL(__page_frag_cache_drain); - -void *__page_frag_alloc_align(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask, - unsigned int align_mask) -{ - unsigned int size = PAGE_SIZE; - struct page *page; - int offset; - - if (unlikely(!nc->va)) { -refill: - page = __page_frag_cache_refill(nc, gfp_mask); - if (!page) - return NULL; - -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size; -#endif - /* Even if we own the page, we do not use atomic_set(). - * This would break get_page_unless_zero() users. - */ - page_ref_add(page, PAGE_FRAG_CACHE_MAX_SIZE); - - /* reset page count bias and offset to start of new frag */ - nc->pfmemalloc = page_is_pfmemalloc(page); - nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; - nc->offset = size; - } - - offset = nc->offset - fragsz; - if (unlikely(offset < 0)) { - page = virt_to_page(nc->va); - - if (!page_ref_sub_and_test(page, nc->pagecnt_bias)) - goto refill; - - if (unlikely(nc->pfmemalloc)) { - free_the_page(page, compound_order(page)); - goto refill; - } - -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size; -#endif - /* OK, page count is 0, we can safely set it */ - set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1); - - /* reset page count bias and offset to start of new frag */ - nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; - offset = size - fragsz; - if (unlikely(offset < 0)) { - /* - * The caller is trying to allocate a fragment - * with fragsz > PAGE_SIZE but the cache isn't big - * enough to satisfy the request, this may - * happen in low memory conditions. - * We don't release the cache page because - * it could make memory pressure worse - * so we simply return NULL here. - */ - return NULL; - } - } - - nc->pagecnt_bias--; - offset &= align_mask; - nc->offset = offset; - - return nc->va + offset; -} -EXPORT_SYMBOL(__page_frag_alloc_align); - -/* - * Frees a page fragment allocated out of either a compound or order 0 page. - */ -void page_frag_free(void *addr) -{ - struct page *page = virt_to_head_page(addr); - - if (unlikely(put_page_testzero(page))) - free_the_page(page, compound_order(page)); -} -EXPORT_SYMBOL(page_frag_free); - static void *make_alloc_exact(unsigned long addr, unsigned int order, size_t size) { diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c new file mode 100644 index 000000000000..a0f90ba25200 --- /dev/null +++ b/mm/page_frag_alloc.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Page fragment allocator + * + * Page Fragment: + * An arbitrary-length arbitrary-offset area of memory which resides within a + * 0 or higher order page. Multiple fragments within that page are + * individually refcounted, in the page's reference counter. + * + * The page_frag functions provide a simple allocation framework for page + * fragments. This is used by the network stack and network device drivers to + * provide a backing region of memory for use as either an sk_buff->head, or to + * be used in the "frags" portion of skb_shared_info. + */ + +#include +#include +#include +#include +#include "internal.h" + +static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, + gfp_t gfp_mask) +{ + struct page *page = NULL; + gfp_t gfp = gfp_mask; + +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + gfp_mask = (gfp_mask & ~__GFP_DIRECT_RECLAIM) | __GFP_COMP | + __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC; + page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, + PAGE_FRAG_CACHE_MAX_ORDER); + nc->size = page ? PAGE_FRAG_CACHE_MAX_SIZE : PAGE_SIZE; +#endif + if (unlikely(!page)) + page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); + + nc->va = page ? page_address(page) : NULL; + + return page; +} + +void page_frag_cache_drain(struct page_frag_cache *nc) +{ + if (!nc->va) + return; + + __page_frag_cache_drain(virt_to_head_page(nc->va), nc->pagecnt_bias); + nc->va = NULL; +} +EXPORT_SYMBOL(page_frag_cache_drain); + +void __page_frag_cache_drain(struct page *page, unsigned int count) +{ + VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); + + /* ensure we can call free_unref_page() directly as we are bypassing + * the pcp_allowed_order() checking. + */ + VM_BUG_ON(PAGE_FRAG_CACHE_MAX_ORDER > PAGE_ALLOC_COSTLY_ORDER); + + if (page_ref_sub_and_test(page, count)) + free_unref_page(page, compound_order(page)); +} +EXPORT_SYMBOL(__page_frag_cache_drain); + +void *__page_frag_alloc_align(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask, + unsigned int align_mask) +{ + unsigned int size = PAGE_SIZE; + struct page *page; + int offset; + + if (unlikely(!nc->va)) { +refill: + page = __page_frag_cache_refill(nc, gfp_mask); + if (!page) + return NULL; + +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + /* if size can vary use size else just use PAGE_SIZE */ + size = nc->size; +#endif + /* Even if we own the page, we do not use atomic_set(). + * This would break get_page_unless_zero() users. + */ + page_ref_add(page, PAGE_FRAG_CACHE_MAX_SIZE); + + /* reset page count bias and offset to start of new frag */ + nc->pfmemalloc = page_is_pfmemalloc(page); + nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; + nc->offset = size; + } + + offset = nc->offset - fragsz; + if (unlikely(offset < 0)) { + page = virt_to_page(nc->va); + + if (!page_ref_sub_and_test(page, nc->pagecnt_bias)) + goto refill; + + if (unlikely(nc->pfmemalloc)) { + free_unref_page(page, compound_order(page)); + goto refill; + } + +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + /* if size can vary use size else just use PAGE_SIZE */ + size = nc->size; +#endif + /* OK, page count is 0, we can safely set it */ + set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1); + + /* reset page count bias and offset to start of new frag */ + nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; + offset = size - fragsz; + if (unlikely(offset < 0)) { + /* + * The caller is trying to allocate a fragment + * with fragsz > PAGE_SIZE but the cache isn't big + * enough to satisfy the request, this may + * happen in low memory conditions. + * We don't release the cache page because + * it could make memory pressure worse + * so we simply return NULL here. + */ + return NULL; + } + } + + nc->pagecnt_bias--; + offset &= align_mask; + nc->offset = offset; + + return nc->va + offset; +} +EXPORT_SYMBOL(__page_frag_alloc_align); + +/* + * Frees a page fragment allocated out of either a compound or order 0 page. + */ +void page_frag_free(void *addr) +{ + struct page *page = virt_to_head_page(addr); + + if (unlikely(put_page_testzero(page))) + free_unref_page(page, compound_order(page)); +} +EXPORT_SYMBOL(page_frag_free); From patchwork Thu Mar 28 13:38:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608542 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91FDAC54E64 for ; Thu, 28 Mar 2024 13:40:51 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 266826B0085; Thu, 28 Mar 2024 09:40:51 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 215EE6B0087; Thu, 28 Mar 2024 09:40:51 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0DE836B0088; Thu, 28 Mar 2024 09:40:51 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id E346F6B0085 for ; Thu, 28 Mar 2024 09:40:50 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id A3D7BC0D19 for ; Thu, 28 Mar 2024 13:40:50 +0000 (UTC) X-FDA: 81946558260.08.6240B96 Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) by imf07.hostedemail.com (Postfix) with ESMTP id F2F834000C for ; Thu, 28 Mar 2024 13:40:47 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf07.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.191 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633248; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1+LR3anLhgNyfy1DdepUw5hxaFlR/GVCDkeZbq8UPPk=; b=DON26GkZAzUl22aNqHsya8yGTHiDrwFZfqMMThHYAJmHHKVjsAtuSobBDkk31wNJFjVcx5 H7OhS4bFW2E9AFv60Squu46nfaeMuVcuJ7x4heInUOqi5t2zkHmw3519RSjgdwND2T31h3 TVpa2zykATbjiT19Mc/rXr7c8UjcBAs= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf07.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.191 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633248; a=rsa-sha256; cv=none; b=kwNY+KFHIs23z9eE+GrAwZlvRPUFxkxCJg4T2EtMyxnHz4dnJtmpx+OsCoLg92+lesMYN5 C27KAi1bYzuSUlDEgq87PaLo7VSGheQtUWze8O+n0EJ7vp0byBekV09eI4q3N7bK86mrF+ UmYfTQQ6H67dlxBnbMa1KQWlpc6cVKY= Received: from mail.maildlp.com (unknown [172.19.88.234]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4V54RG48H3z1GDX7; Thu, 28 Mar 2024 21:40:10 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id A7813140258; Thu, 28 Mar 2024 21:40:42 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:42 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Alexander Duyck , Andrew Morton , Subject: [PATCH RFC 02/10] mm: page_frag: use initial zero offset for page_frag_alloc_align() Date: Thu, 28 Mar 2024 21:38:31 +0800 Message-ID: <20240328133839.13620-3-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: F2F834000C X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: 38f99xeqszr6h8tkw6zpqus749wewf36 X-HE-Tag: 1711633247-948529 X-HE-Meta: U2FsdGVkX1/L6AnQa3VsN9mLIQz2jrsqsaZvQAxRKnh4PyWmxRjg3d9zPP5cIPkUUYjumtn3aQxwn+yzAF+pBmpg4ZX3+zyvi4NSSRphX1x2cqS4WgIIKYaceNSnNbFHSbataw8EToQDQCTX8EH5oyVntyEA5Dm6z19INI+Mj0gEAhwDzgdBKD+P2PWoR82aBEwKs2jY0EDOZIISC5tjikHtK5y+94eERUCd7NizBTVwt8BByk4VADKGUNNCUclg8a5InOLQ8BIbo5TU0MjEJtm9+Xt7vTFGtvEPh2S1uLbGzCrr0uxSpwEYGHdflWcbrv1tHUAJ2a99w/pCfCTINQETzgiJvjDvL1hNcHn0opF8A0Jrl+NigYbMbEjvcSe+IyqtfMJ9royrfjXuulYBXrUMDLk5LrRvXFvxtyY8M6HoXGfyaOcTsFxDI2oj2hCyAOPwi5MORT3oRf0EoBPlB8STTej8HHdiZCYau7LInf+jh6iITNw/j5xOTFlsw9ZZ8lMe3m5PZ9asG2qI9kA9RDJelN1qWkZkjcKwVfdCUiqGKkodVtS48xkwN9JVo3fCKYcCqWJeArMEVyO5CjIOJpYbAoQ4WIeHaZ4dxm3fIV0lBI5f1ZmY59TvIakE6HyEy5MoVLBKNIH0WD0njsW7jLC8n8wE7V+JIRMpzAn3FVOy2Xt72VxPq2L4COimqpvgWqprktct7ljNNz2zrYKrKi8PYHiZYSV8zU4qi/UNSZVI7zbOFgvjuV/O5i8VOnw3PYTmI1+buQ1T90LfyW9SRgLxv+bwV6Q4n4w/lHFRgreXGdmDAa6FxHqhxd5fRChzvUvs2T4xgFTj9rlrbCwXeYIMTD+hRUWhN1b8EumrAhGgyQPqT+eyCKyKwdw8+vroPioWgOJZd6sU7h5UmDMWobu+Qwpr34yC2ft3PyPKm9ch7Fv2X37HuKOw53pHd+skKQGuysWKpMFF6COPVQ4 37h+08m1 6FiSZEqJkw+lRxoU+IwiRF7GT5beJQoFzBzaI+mIBQH6b3osVtjuRubYi9ZZZhrsL6aYNzQ8BRv05FRHE5kDlEztEBujgiAndJMhBE/GRYYTZLm727T1BRe+oWRUFV7ZUvqT0e06pR0/W1Ix9c/dOu+hvRv3OM85+HxqvRVW9FqxeIrt8613ugEV5dmxUPgutuKdTuhynJzvhwETzMuGcI4RacdVdmZNyCDordjyhkBRl9YmsWweStTy0eAh4klVGplkRBb2FCul4XYOY1bjUf50aTLENYfGN11s2djnSNqw+/zE4LPIvm+cDRcjkhP25OaVwkGSkuaaEJRkmL7KVtYrXwQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: We are above to use page_frag_alloc_*() API to not just allocate memory for skb->data, but also use them to do the memory allocation for skb frag too. Currently the implementation of page_frag in mm subsystem is running the offset as a countdown rather than count-up value, there may have several advantages to that as mentioned in [1], but it may have some disadvantages, for example, it may disable skb frag coaleasing and more correct cache prefetching We have a trade-off to make in order to have a unified implementation and API for page_frag, so use a initial zero offset in this patch, and the following patch will try to make some optimization to aovid the disadvantages as much as possible. 1. https://lore.kernel.org/all/f4abe71b3439b39d17a6fb2d410180f367cadf5c.camel@gmail.com/ CC: Alexander Duyck Signed-off-by: Yunsheng Lin --- mm/page_frag_alloc.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index a0f90ba25200..3e3e88d9af90 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -67,9 +67,8 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz, gfp_t gfp_mask, unsigned int align_mask) { - unsigned int size = PAGE_SIZE; + unsigned int size, offset; struct page *page; - int offset; if (unlikely(!nc->va)) { refill: @@ -77,10 +76,6 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, if (!page) return NULL; -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size; -#endif /* Even if we own the page, we do not use atomic_set(). * This would break get_page_unless_zero() users. */ @@ -89,11 +84,18 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, /* reset page count bias and offset to start of new frag */ nc->pfmemalloc = page_is_pfmemalloc(page); nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; - nc->offset = size; + nc->offset = 0; } - offset = nc->offset - fragsz; - if (unlikely(offset < 0)) { +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + /* if size can vary use size else just use PAGE_SIZE */ + size = nc->size; +#else + size = PAGE_SIZE; +#endif + + offset = ALIGN(nc->offset, -align_mask); + if (unlikely(offset + fragsz > size)) { page = virt_to_page(nc->va); if (!page_ref_sub_and_test(page, nc->pagecnt_bias)) @@ -104,17 +106,13 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, goto refill; } -#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) - /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size; -#endif /* OK, page count is 0, we can safely set it */ set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1); /* reset page count bias and offset to start of new frag */ nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; - offset = size - fragsz; - if (unlikely(offset < 0)) { + offset = 0; + if (unlikely(fragsz > size)) { /* * The caller is trying to allocate a fragment * with fragsz > PAGE_SIZE but the cache isn't big @@ -129,8 +127,7 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, } nc->pagecnt_bias--; - offset &= align_mask; - nc->offset = offset; + nc->offset = offset + fragsz; return nc->va + offset; } From patchwork Thu Mar 28 13:38:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608543 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17EC2CD128A for ; Thu, 28 Mar 2024 13:40:54 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5C2126B0087; Thu, 28 Mar 2024 09:40:52 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 572AC6B0088; Thu, 28 Mar 2024 09:40:52 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 43AC76B0089; Thu, 28 Mar 2024 09:40:52 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 2BEB06B0087 for ; Thu, 28 Mar 2024 09:40:52 -0400 (EDT) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id F2C9AA148D for ; Thu, 28 Mar 2024 13:40:51 +0000 (UTC) X-FDA: 81946558302.06.A573470 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf19.hostedemail.com (Postfix) with ESMTP id 7F07C1A0004 for ; Thu, 28 Mar 2024 13:40:49 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=none; spf=pass (imf19.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633250; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w3eutPa8+J3GtGWmS2jAMzEFzjhLyhM72IWycQnj/E4=; b=v4sA7n0RxISWxsIo5Gc++xpMujuHZ1ifierYN2B3DE3mmMI0iaeqvMWedm54a0g6UNZ//L UaeBxFNXYCaa3Tv0H4NeA2IN6GWbm+sDBrePjNQYVoddL36uBzbzsi8Ku8gYp0D43hQKZ2 7VgPHIrCc/11555SDPMdASqPu97nOXI= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633250; a=rsa-sha256; cv=none; b=0CARkY5zBOvzuP+B+7CBxCUvVQGXmlJVJ73zzoWDOmGl0eCLTZaKjjw8pWHBbnhSe5Pp3G mA5lSIAlvP3ulbWnvG87tOpUvyRRQARy23pn1NVy/iyIGnjp10Ma3p/H0gwGjOfe6+ft8d fQ+XnrZzoWIc0Tbo1k+QhovLvI1+A68= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=none; spf=pass (imf19.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4V54Qx0XM7zPpdT; Thu, 28 Mar 2024 21:39:53 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id 690D61400CD; Thu, 28 Mar 2024 21:40:45 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:45 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Andrew Morton , Eric Dumazet , David Howells , Marc Dionne , , Subject: [PATCH RFC 03/10] mm: page_frag: change page_frag_alloc_* API to accept align param Date: Thu, 28 Mar 2024 21:38:32 +0800 Message-ID: <20240328133839.13620-4-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: 7F07C1A0004 X-Rspam-User: X-Rspamd-Server: rspam11 X-Stat-Signature: 4f64abtbsq5roe6wks9baa1ppkshs6yr X-HE-Tag: 1711633249-550481 X-HE-Meta: U2FsdGVkX1+FMcSbaWVsRIXzGmLaivKNCx/fInpAbA4ceVKF53T0/hbrtrhkolwHtM7lF46utrhKeLp5BbZTk2w9t9Ykru9u7AaIG0mu2MWbiTbWV0nto5u7DIyHLO8AeV1ayR336L6h0IQljEsDZLD2yhfTfT35JLFsNR/kD5JDGu8HgYho6CIzqkItVatyflar0X9mTrPhFJ4ohFv9LTXuxDTlTMrLo8zJfm/I54IJaCssi9j5xxIdJax7EWbu3lWJxY9Q4EZOW+tLNZ48Z3rWFNCL3467boOUBd2c/IqVhBjBGdwIyEjU5Y/k78b0f0GQOEjuiRPvHs8z+qxvIONSsAmcmELCoJaMKrdg5Eiwn0oYvqK0SLs+Ejuob1DgHF8rWzggoQ31E/S7Cjf3MFvH5odIIgxx47aTBMv5lagVHxdGJUE9XG1NSPFY53ijGkloOrGI90XtNDvv21eKKIMBySYOkJ0hN4iDlCwjTXdt20+Hg5oGuviYs3SxMQ9VW/U8ydAvH/Wpb65nNojWGvIM30QLrcItoZ24HnwGdGLkeObhg/mntusoJ8a8Aq71ekqFET5XAti/quzBUCSL1F6K0JEsZxZOAkrybBC6AaqTDznNNESyyw/V4Z0U8T1HXh23K8S9v1rMoVrwviAJKD379meRDs5sB6/rfVldnkHmAtdMNZx7RT2FTOKyytzZKz4b0BSlmIlCMZ8eKyq4c7IGvjzVM4DnIMQ3DFLs3QrNX7YwV9k08j3oROYKx8W2ox5gm3jyLfqpL7m1PS8a7dLztt34HkS/xRohEHbBxpWCYJ+TwEYJIpnyxAAxaroIeAi2YU6njpbMZFt267+xNxO0XkLiETcyrUuBxtD9yiCQoY1opusupLwxN3s7yjgVmcp6I/ZwqrioFlvmiJOza8fXMHvJlQymXEvPgYLDjxfSgbHGvtS252ixY0UwtYKWssorxc9771IXSH71ZbE 8Pafg+yP jR43DUdOC2hfa6zoTOaGiAUSh4WAy1B2Tg5zdyGd0YC3+DpyoKWlPZSiiX1UuZVsuvTHTc/I3U51zzXDPcs/6K47TkWnkKzJ9imC9DB9KEIxMjOA0rNk5YPFw5ivZAR2TwJUdJ/HBxpSAPgnxKTeVlLBXBZOfEt4eATeCMe4FWYEJwtj2QqvnMcnkRY0Bm24Ukgga X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: When page_frag_alloc_* API doesn't need data alignment, the ALIGN() operation is unnecessary, so change page_frag_alloc_* API to accept align param instead of align_mask param, and do the ALIGN()'ing in the inline helper when needed. Signed-off-by: Yunsheng Lin --- include/linux/page_frag_cache.h | 20 ++++++++++++-------- include/linux/skbuff.h | 12 ++++++------ mm/page_frag_alloc.c | 9 ++++----- net/core/skbuff.c | 12 +++++------- net/rxrpc/txbuf.c | 5 +++-- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index 04810d8d6a7d..cc0ede0912f3 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -25,21 +25,25 @@ struct page_frag_cache { void page_frag_cache_drain(struct page_frag_cache *nc); void __page_frag_cache_drain(struct page *page, unsigned int count); -void *__page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask, unsigned int align_mask); +void *page_frag_alloc(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask); + +static inline void *__page_frag_alloc_align(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask, + unsigned int align) +{ + nc->offset = ALIGN(nc->offset, align); + + return page_frag_alloc(nc, fragsz, gfp_mask); +} static inline void *page_frag_alloc_align(struct page_frag_cache *nc, unsigned int fragsz, gfp_t gfp_mask, unsigned int align) { WARN_ON_ONCE(!is_power_of_2(align)); - return __page_frag_alloc_align(nc, fragsz, gfp_mask, -align); -} -static inline void *page_frag_alloc(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask) -{ - return page_frag_alloc_align(nc, fragsz, gfp_mask, ~0u); + return __page_frag_alloc_align(nc, fragsz, gfp_mask, align); } void page_frag_free(void *addr); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7f68199fee34..074cdd29f782 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3264,7 +3264,7 @@ static inline void skb_queue_purge(struct sk_buff_head *list) unsigned int skb_rbtree_purge(struct rb_root *root); void skb_errqueue_purge(struct sk_buff_head *list); -void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask); +void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align); /** * netdev_alloc_frag - allocate a page fragment @@ -3275,14 +3275,14 @@ void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask); */ static inline void *netdev_alloc_frag(unsigned int fragsz) { - return __netdev_alloc_frag_align(fragsz, ~0u); + return __netdev_alloc_frag_align(fragsz, 1u); } static inline void *netdev_alloc_frag_align(unsigned int fragsz, unsigned int align) { WARN_ON_ONCE(!is_power_of_2(align)); - return __netdev_alloc_frag_align(fragsz, -align); + return __netdev_alloc_frag_align(fragsz, align); } struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, @@ -3342,18 +3342,18 @@ static inline void skb_free_frag(void *addr) page_frag_free(addr); } -void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align_mask); +void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align); static inline void *napi_alloc_frag(unsigned int fragsz) { - return __napi_alloc_frag_align(fragsz, ~0u); + return __napi_alloc_frag_align(fragsz, 1u); } static inline void *napi_alloc_frag_align(unsigned int fragsz, unsigned int align) { WARN_ON_ONCE(!is_power_of_2(align)); - return __napi_alloc_frag_align(fragsz, -align); + return __napi_alloc_frag_align(fragsz, align); } struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index 3e3e88d9af90..39c744c892ed 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -63,9 +63,8 @@ void __page_frag_cache_drain(struct page *page, unsigned int count) } EXPORT_SYMBOL(__page_frag_cache_drain); -void *__page_frag_alloc_align(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask, - unsigned int align_mask) +void *page_frag_alloc(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask) { unsigned int size, offset; struct page *page; @@ -94,7 +93,7 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, size = PAGE_SIZE; #endif - offset = ALIGN(nc->offset, -align_mask); + offset = nc->offset; if (unlikely(offset + fragsz > size)) { page = virt_to_page(nc->va); @@ -131,7 +130,7 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc, return nc->va + offset; } -EXPORT_SYMBOL(__page_frag_alloc_align); +EXPORT_SYMBOL(page_frag_alloc); /* * Frees a page fragment allocated out of either a compound or order 0 page. diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 17617c29be2d..4c88d7f541e4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -305,18 +305,17 @@ void napi_get_frags_check(struct napi_struct *napi) local_bh_enable(); } -void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) +void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align) { struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); fragsz = SKB_DATA_ALIGN(fragsz); - return __page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, - align_mask); + return __page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, align); } EXPORT_SYMBOL(__napi_alloc_frag_align); -void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) +void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align) { void *data; @@ -324,15 +323,14 @@ void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask) if (in_hardirq() || irqs_disabled()) { struct page_frag_cache *nc = this_cpu_ptr(&netdev_alloc_cache); - data = __page_frag_alloc_align(nc, fragsz, GFP_ATOMIC, - align_mask); + data = __page_frag_alloc_align(nc, fragsz, GFP_ATOMIC, align); } else { struct napi_alloc_cache *nc; local_bh_disable(); nc = this_cpu_ptr(&napi_alloc_cache); data = __page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, - align_mask); + align); local_bh_enable(); } return data; diff --git a/net/rxrpc/txbuf.c b/net/rxrpc/txbuf.c index e0679658d9de..eb640875bf07 100644 --- a/net/rxrpc/txbuf.c +++ b/net/rxrpc/txbuf.c @@ -32,9 +32,10 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_ hoff = round_up(sizeof(*whdr), data_align) - sizeof(*whdr); total = hoff + sizeof(*whdr) + data_size; + data_align = max_t(size_t, data_align, L1_CACHE_BYTES); mutex_lock(&call->conn->tx_data_alloc_lock); - buf = __page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp, - ~(data_align - 1) & ~(L1_CACHE_BYTES - 1)); + buf = page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp, + data_align); mutex_unlock(&call->conn->tx_data_alloc_lock); if (!buf) { kfree(txb); From patchwork Thu Mar 28 13:38:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608544 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 009B0C54E67 for ; Thu, 28 Mar 2024 13:40:58 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7E3EC6B0088; Thu, 28 Mar 2024 09:40:58 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 7BB4A6B008C; Thu, 28 Mar 2024 09:40:58 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 636EB6B0092; Thu, 28 Mar 2024 09:40:58 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 41F756B0088 for ; Thu, 28 Mar 2024 09:40:58 -0400 (EDT) Received: from smtpin02.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id F3AAC40C55 for ; Thu, 28 Mar 2024 13:40:57 +0000 (UTC) X-FDA: 81946558554.02.22ECCFD Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) by imf05.hostedemail.com (Postfix) with ESMTP id 427DC100008 for ; Thu, 28 Mar 2024 13:40:54 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf05.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.190 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633256; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ALVJaIArbDD2KQxrmUeMSOWhAkBNMWk3XnP448DKja4=; b=zwLCUpICtvUKvjp6I9NYHyjBAZQeCdbyCCKxkD/A8KhG6yyeB4y2LPZi0/0QaTqZ8OGjBl AqOun4z+4rTWAr9fTnTFu/8mekRomxi+zVv0NG4HfqHPQ8mkeWzkcy/As2oNmvhUi88zsC Dd6FSUapG07mcE+QD9bC3fK8yqfWcu4= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf05.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.190 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633256; a=rsa-sha256; cv=none; b=noxr9maHQzW4ZUwMTP0ZVxX1ZKQlAAbwGY0baol0Ei0wFxwWhlEP7qIZMrBlOBPcXXh+V2 t6n4DHtFwBuS2F7bzOZsQJ/bpKy6Kj/56FojXClB/8GdlXwDQagu7Kbfr5WFxafI0H9Lbw 07pqnpYP8H1mK/7yIqkFq9gxwulVjO0= Received: from mail.maildlp.com (unknown [172.19.163.44]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4V54Pj5dqyz1xrSD; Thu, 28 Mar 2024 21:38:49 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id 715951402CA; Thu, 28 Mar 2024 21:40:51 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:50 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Jeroen de Borst , Praveen Kaligineedi , Shailend Chand , Eric Dumazet , Jesse Brandeburg , Tony Nguyen , Sunil Goutham , Geetha sowjanya , Subbaraya Sundeep , hariprasad , Felix Fietkau , Sean Wang , Mark Lee , Lorenzo Bianconi , Matthias Brugger , AngeloGioacchino Del Regno , Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , "Michael S. Tsirkin" , Jason Wang , Andrew Morton , Alexei Starovoitov , Daniel Borkmann , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , David Howells , Marc Dionne , Trond Myklebust , Anna Schumaker , Chuck Lever , Jeff Layton , Neil Brown , Olga Kornievskaia , Dai Ngo , Tom Talpey , , , , , , , , , , Subject: [PATCH RFC 04/10] mm: page_frag: add '_va' suffix to page_frag API Date: Thu, 28 Mar 2024 21:38:33 +0800 Message-ID: <20240328133839.13620-5-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 427DC100008 X-Stat-Signature: apxnp87zxccuu48pwy55c6t7bmp48rgk X-Rspam-User: X-HE-Tag: 1711633254-884238 X-HE-Meta: U2FsdGVkX1+altGa/9eYUdK+UhmKjfOsdo5Ctj/xAUYOle0zJAHFp0huRSImF8nGn/zad13ueX3srpMQh9nHdGcC1kb3TMRD2vF34vFz9+c426YdQaoiNLlSx0lUuM0Os6zeE1wubSlBvUw+yM/daIQMuFaXZWflgvCyvLBJkBPIRCLisOluqPBOKX5bf9O9S4mjPRIDOmm762Oj3eMSRIxoO1wk0i7qN5oBCpdez867CTbhi4icf5exsNEQZuurTpgrC6YTfrZrp9B/9nspILQjDc+4t1vgbuvwN/MiNxvOU1lfd8FkroUNwWY5lYCi+k7Bc7xl9yVz+9JHhIYWDGzFY0jxrcDMwjwDZpvEm7mtqgDtotgFAE3OZZCIxQf3L9WVD8e/TM24fbfx2x3FiwejH79STQQFAjWYc1BixkBfE6kpyJjCPKOcqiaXY3oiPLMvQ5qSxXxzcWtf3ZL68jziIqcOBXEdMQCAPjWlUM20L0xFGMGlPVgVuOhDC6G/pKQSYLc4AxPfis6EenTlCeiE8CYkRWQMPSDSNME/9hhl5OhIdWS6GTCZbT0kVOW+VkKz0TJ0wf5pT0ggcqwIFgJKS/I1pNBlhxdamhCpLurO2vfrJMT1BYyhz5kuhg/TC6dfY8p3sqtXrfG7x4ny0/20XbSz5DJEZ7m8RKx1WsBU5B2xIUdWk5MZg62HadVU/9e+NZ4pQict34UicW34ezDk/gpu4BA4v6xFtJGgBSzGqtF6C7iDyU32mu/8xMOS2f3JrYE32QP7i1bZpXlRHJL0Le579hSrH0VK6xO9R5roFLe4jJrEIBn4Atw4ZRcoi01pJkdqY59UtdX7e9woCZOqQ4Swes4WwwRaJhwbaS1rmMb+dYL/Nq3tQ2SLU4Q0Nbh+ezipYdXe3J6vRiqkntleV91ckbPkbi7H3jj1IzVoeIDiK1+pRzqCcllKEFgMYKxw5EU5v3q/ePq4tdA s7GDVd7s 7IRmohwiS9528NNGBPiFtlzw4Ztd6ARRyvexcRKUeVHnJJHMTkPt/99qxdEzRLL0KpWAuVgYNn8O6Fi3h/baVQWJAMTYi5jQlCF/NUOjf7t8RhTTwJQ1N4yRexkbLbu/LFelHbJmVsy+ILpqyygHOOFeHkIhEK4atelsVAMA5V+ejCRaFptI12qzQJxgAx4drlRQB7GC6iRkY2u8eDaE4mY1ePzKosSlfHEMkCbSC217u9l1MK/7wauGc6LlSzjsFjGR8zYRKQhDVAoA= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Currently most of the API for page_frag API is returning 'virtual address' as output or expecting 'virtual address' as input, in order to differentiate the API handling between 'virtual address' and 'struct page', add '_va' suffix to the corresponding API mirroring the page_pool_alloc_va() API of the page_pool. Signed-off-by: Yunsheng Lin --- drivers/net/ethernet/google/gve/gve_rx.c | 4 ++-- drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +- drivers/net/ethernet/intel/ice/ice_txrx.h | 2 +- drivers/net/ethernet/intel/ice/ice_txrx_lib.c | 2 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++-- .../marvell/octeontx2/nic/otx2_common.c | 2 +- drivers/net/ethernet/mediatek/mtk_wed_wo.c | 4 ++-- drivers/nvme/host/tcp.c | 8 +++---- drivers/nvme/target/tcp.c | 22 ++++++++--------- drivers/vhost/net.c | 6 ++--- include/linux/page_frag_cache.h | 24 ++++++++++--------- include/linux/skbuff.h | 2 +- kernel/bpf/cpumap.c | 2 +- mm/page_frag_alloc.c | 10 ++++---- net/core/skbuff.c | 15 ++++++------ net/core/xdp.c | 2 +- net/rxrpc/txbuf.c | 15 ++++++------ net/sunrpc/svcsock.c | 4 ++-- 18 files changed, 67 insertions(+), 63 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index 20f5a9e7fae9..58091de93430 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -687,7 +687,7 @@ static int gve_xdp_redirect(struct net_device *dev, struct gve_rx_ring *rx, total_len = headroom + SKB_DATA_ALIGN(len) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - frame = page_frag_alloc(&rx->page_cache, total_len, GFP_ATOMIC); + frame = page_frag_alloc_va(&rx->page_cache, total_len, GFP_ATOMIC); if (!frame) { u64_stats_update_begin(&rx->statss); rx->xdp_alloc_fails++; @@ -700,7 +700,7 @@ static int gve_xdp_redirect(struct net_device *dev, struct gve_rx_ring *rx, err = xdp_do_redirect(dev, &new, xdp_prog); if (err) - page_frag_free(frame); + page_frag_free_va(frame); return err; } diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 97d41d6ebf1f..87f23995b657 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -126,7 +126,7 @@ ice_unmap_and_free_tx_buf(struct ice_tx_ring *ring, struct ice_tx_buf *tx_buf) dev_kfree_skb_any(tx_buf->skb); break; case ICE_TX_BUF_XDP_TX: - page_frag_free(tx_buf->raw_buf); + page_frag_free_va(tx_buf->raw_buf); break; case ICE_TX_BUF_XDP_XMIT: xdp_return_frame(tx_buf->xdpf); diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h index af955b0e5dc5..65ad1757824f 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.h +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -148,7 +148,7 @@ static inline int ice_skb_pad(void) * @ICE_TX_BUF_DUMMY: dummy Flow Director packet, unmap and kfree() * @ICE_TX_BUF_FRAG: mapped skb OR &xdp_buff frag, only unmap DMA * @ICE_TX_BUF_SKB: &sk_buff, unmap and consume_skb(), update stats - * @ICE_TX_BUF_XDP_TX: &xdp_buff, unmap and page_frag_free(), stats + * @ICE_TX_BUF_XDP_TX: &xdp_buff, unmap and page_frag_free_va(), stats * @ICE_TX_BUF_XDP_XMIT: &xdp_frame, unmap and xdp_return_frame(), stats * @ICE_TX_BUF_XSK_TX: &xdp_buff on XSk queue, xsk_buff_free(), stats */ diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c index f8f1d2bdc1be..312f351ac601 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c @@ -279,7 +279,7 @@ ice_clean_xdp_tx_buf(struct device *dev, struct ice_tx_buf *tx_buf, switch (tx_buf->type) { case ICE_TX_BUF_XDP_TX: - page_frag_free(tx_buf->raw_buf); + page_frag_free_va(tx_buf->raw_buf); break; case ICE_TX_BUF_XDP_XMIT: xdp_return_frame_bulk(tx_buf->xdpf, bq); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 9c960017a6de..f781c5f202c9 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -303,7 +303,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_q_vector *q_vector, /* free the skb */ if (ring_is_xdp(tx_ring)) - page_frag_free(tx_buffer->data); + page_frag_free_va(tx_buffer->data); else napi_consume_skb(tx_buffer->skb, napi_budget); @@ -2413,7 +2413,7 @@ static void ixgbevf_clean_tx_ring(struct ixgbevf_ring *tx_ring) /* Free all the Tx ring sk_buffs */ if (ring_is_xdp(tx_ring)) - page_frag_free(tx_buffer->data); + page_frag_free_va(tx_buffer->data); else dev_kfree_skb_any(tx_buffer->skb); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index a85ac039d779..8eb5820b8a70 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -553,7 +553,7 @@ static int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, *dma = dma_map_single_attrs(pfvf->dev, buf, pool->rbsize, DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); if (unlikely(dma_mapping_error(pfvf->dev, *dma))) { - page_frag_free(buf); + page_frag_free_va(buf); return -ENOMEM; } diff --git a/drivers/net/ethernet/mediatek/mtk_wed_wo.c b/drivers/net/ethernet/mediatek/mtk_wed_wo.c index 7063c78bd35f..c4228719f8a4 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c +++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c @@ -142,8 +142,8 @@ mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, dma_addr_t addr; void *buf; - buf = page_frag_alloc(&q->cache, q->buf_size, - GFP_ATOMIC | GFP_DMA32); + buf = page_frag_alloc_va(&q->cache, q->buf_size, + GFP_ATOMIC | GFP_DMA32); if (!buf) break; diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 3692b56cb58d..ceb0d2d1497a 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -492,7 +492,7 @@ static void nvme_tcp_exit_request(struct blk_mq_tag_set *set, { struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); - page_frag_free(req->pdu); + page_frag_free_va(req->pdu); } static int nvme_tcp_init_request(struct blk_mq_tag_set *set, @@ -506,7 +506,7 @@ static int nvme_tcp_init_request(struct blk_mq_tag_set *set, struct nvme_tcp_queue *queue = &ctrl->queues[queue_idx]; u8 hdgst = nvme_tcp_hdgst_len(queue); - req->pdu = page_frag_alloc(&queue->pf_cache, + req->pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(struct nvme_tcp_cmd_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!req->pdu) @@ -1323,7 +1323,7 @@ static void nvme_tcp_free_async_req(struct nvme_tcp_ctrl *ctrl) { struct nvme_tcp_request *async = &ctrl->async_req; - page_frag_free(async->pdu); + page_frag_free_va(async->pdu); } static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl) @@ -1332,7 +1332,7 @@ static int nvme_tcp_alloc_async_req(struct nvme_tcp_ctrl *ctrl) struct nvme_tcp_request *async = &ctrl->async_req; u8 hdgst = nvme_tcp_hdgst_len(queue); - async->pdu = page_frag_alloc(&queue->pf_cache, + async->pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(struct nvme_tcp_cmd_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!async->pdu) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 2aa5762e9f50..a236e9fe145d 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1461,24 +1461,24 @@ static int nvmet_tcp_alloc_cmd(struct nvmet_tcp_queue *queue, c->queue = queue; c->req.port = queue->port->nport; - c->cmd_pdu = page_frag_alloc(&queue->pf_cache, + c->cmd_pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(*c->cmd_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!c->cmd_pdu) return -ENOMEM; c->req.cmd = &c->cmd_pdu->cmd; - c->rsp_pdu = page_frag_alloc(&queue->pf_cache, + c->rsp_pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(*c->rsp_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!c->rsp_pdu) goto out_free_cmd; c->req.cqe = &c->rsp_pdu->cqe; - c->data_pdu = page_frag_alloc(&queue->pf_cache, + c->data_pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(*c->data_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!c->data_pdu) goto out_free_rsp; - c->r2t_pdu = page_frag_alloc(&queue->pf_cache, + c->r2t_pdu = page_frag_alloc_va(&queue->pf_cache, sizeof(*c->r2t_pdu) + hdgst, GFP_KERNEL | __GFP_ZERO); if (!c->r2t_pdu) goto out_free_data; @@ -1493,20 +1493,20 @@ static int nvmet_tcp_alloc_cmd(struct nvmet_tcp_queue *queue, return 0; out_free_data: - page_frag_free(c->data_pdu); + page_frag_free_va(c->data_pdu); out_free_rsp: - page_frag_free(c->rsp_pdu); + page_frag_free_va(c->rsp_pdu); out_free_cmd: - page_frag_free(c->cmd_pdu); + page_frag_free_va(c->cmd_pdu); return -ENOMEM; } static void nvmet_tcp_free_cmd(struct nvmet_tcp_cmd *c) { - page_frag_free(c->r2t_pdu); - page_frag_free(c->data_pdu); - page_frag_free(c->rsp_pdu); - page_frag_free(c->cmd_pdu); + page_frag_free_va(c->r2t_pdu); + page_frag_free_va(c->data_pdu); + page_frag_free_va(c->rsp_pdu); + page_frag_free_va(c->cmd_pdu); } static int nvmet_tcp_alloc_cmds(struct nvmet_tcp_queue *queue) diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index c64ded183f8d..96d5ca299552 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -682,8 +682,8 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq, return -ENOSPC; buflen += SKB_DATA_ALIGN(len + pad); - buf = page_frag_alloc_align(&net->pf_cache, buflen, GFP_KERNEL, - SMP_CACHE_BYTES); + buf = page_frag_alloc_va_align(&net->pf_cache, buflen, GFP_KERNEL, + SMP_CACHE_BYTES); if (unlikely(!buf)) return -ENOMEM; @@ -730,7 +730,7 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq, return 0; err: - page_frag_free(buf); + page_frag_free_va(buf); return ret; } diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index cc0ede0912f3..9d5d86b2d3ab 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -25,27 +25,29 @@ struct page_frag_cache { void page_frag_cache_drain(struct page_frag_cache *nc); void __page_frag_cache_drain(struct page *page, unsigned int count); -void *page_frag_alloc(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask); +void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask); -static inline void *__page_frag_alloc_align(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask, - unsigned int align) +static inline void *__page_frag_alloc_va_align(struct page_frag_cache *nc, + unsigned int fragsz, + gfp_t gfp_mask, + unsigned int align) { nc->offset = ALIGN(nc->offset, align); - return page_frag_alloc(nc, fragsz, gfp_mask); + return page_frag_alloc_va(nc, fragsz, gfp_mask); } -static inline void *page_frag_alloc_align(struct page_frag_cache *nc, - unsigned int fragsz, gfp_t gfp_mask, - unsigned int align) +static inline void *page_frag_alloc_va_align(struct page_frag_cache *nc, + unsigned int fragsz, + gfp_t gfp_mask, + unsigned int align) { WARN_ON_ONCE(!is_power_of_2(align)); - return __page_frag_alloc_align(nc, fragsz, gfp_mask, align); + return __page_frag_alloc_va_align(nc, fragsz, gfp_mask, align); } -void page_frag_free(void *addr); +void page_frag_free_va(void *addr); #endif diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 074cdd29f782..70d657a7b309 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3339,7 +3339,7 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, static inline void skb_free_frag(void *addr) { - page_frag_free(addr); + page_frag_free_va(addr); } void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align); diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c index a8e34416e960..3a6a237e7dd3 100644 --- a/kernel/bpf/cpumap.c +++ b/kernel/bpf/cpumap.c @@ -322,7 +322,7 @@ static int cpu_map_kthread_run(void *data) /* Bring struct page memory area to curr CPU. Read by * build_skb_around via page_is_pfmemalloc(), and when - * freed written by page_frag_free call. + * freed written by page_frag_free_va call. */ prefetchw(page); } diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index 39c744c892ed..7f639af4e518 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -63,8 +63,8 @@ void __page_frag_cache_drain(struct page *page, unsigned int count) } EXPORT_SYMBOL(__page_frag_cache_drain); -void *page_frag_alloc(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask) +void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask) { unsigned int size, offset; struct page *page; @@ -130,16 +130,16 @@ void *page_frag_alloc(struct page_frag_cache *nc, unsigned int fragsz, return nc->va + offset; } -EXPORT_SYMBOL(page_frag_alloc); +EXPORT_SYMBOL(page_frag_alloc_va); /* * Frees a page fragment allocated out of either a compound or order 0 page. */ -void page_frag_free(void *addr) +void page_frag_free_va(void *addr) { struct page *page = virt_to_head_page(addr); if (unlikely(put_page_testzero(page))) free_unref_page(page, compound_order(page)); } -EXPORT_SYMBOL(page_frag_free); +EXPORT_SYMBOL(page_frag_free_va); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4c88d7f541e4..aa3adaa2c466 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -311,7 +311,7 @@ void *__napi_alloc_frag_align(unsigned int fragsz, unsigned int align) fragsz = SKB_DATA_ALIGN(fragsz); - return __page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, align); + return __page_frag_alloc_va_align(&nc->page, fragsz, GFP_ATOMIC, align); } EXPORT_SYMBOL(__napi_alloc_frag_align); @@ -323,14 +323,15 @@ void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align) if (in_hardirq() || irqs_disabled()) { struct page_frag_cache *nc = this_cpu_ptr(&netdev_alloc_cache); - data = __page_frag_alloc_align(nc, fragsz, GFP_ATOMIC, align); + data = __page_frag_alloc_va_align(nc, fragsz, GFP_ATOMIC, + align); } else { struct napi_alloc_cache *nc; local_bh_disable(); nc = this_cpu_ptr(&napi_alloc_cache); - data = __page_frag_alloc_align(&nc->page, fragsz, GFP_ATOMIC, - align); + data = __page_frag_alloc_va_align(&nc->page, fragsz, GFP_ATOMIC, + align); local_bh_enable(); } return data; @@ -740,12 +741,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, if (in_hardirq() || irqs_disabled()) { nc = this_cpu_ptr(&netdev_alloc_cache); - data = page_frag_alloc(nc, len, gfp_mask); + data = page_frag_alloc_va(nc, len, gfp_mask); pfmemalloc = nc->pfmemalloc; } else { local_bh_disable(); nc = this_cpu_ptr(&napi_alloc_cache.page); - data = page_frag_alloc(nc, len, gfp_mask); + data = page_frag_alloc_va(nc, len, gfp_mask); pfmemalloc = nc->pfmemalloc; local_bh_enable(); } @@ -834,7 +835,7 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, } else { len = SKB_HEAD_ALIGN(len); - data = page_frag_alloc(&nc->page, len, gfp_mask); + data = page_frag_alloc_va(&nc->page, len, gfp_mask); pfmemalloc = nc->page.pfmemalloc; } diff --git a/net/core/xdp.c b/net/core/xdp.c index 41693154e426..245a2d011aeb 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c @@ -391,7 +391,7 @@ void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct, page_pool_put_full_page(page->pp, page, napi_direct); break; case MEM_TYPE_PAGE_SHARED: - page_frag_free(data); + page_frag_free_va(data); break; case MEM_TYPE_PAGE_ORDER0: page = virt_to_page(data); /* Assumes order0 page*/ diff --git a/net/rxrpc/txbuf.c b/net/rxrpc/txbuf.c index eb640875bf07..f2fa98360789 100644 --- a/net/rxrpc/txbuf.c +++ b/net/rxrpc/txbuf.c @@ -34,8 +34,8 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_ data_align = max_t(size_t, data_align, L1_CACHE_BYTES); mutex_lock(&call->conn->tx_data_alloc_lock); - buf = page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp, - data_align); + buf = page_frag_alloc_va_align(&call->conn->tx_data_alloc, total, gfp, + data_align); mutex_unlock(&call->conn->tx_data_alloc_lock); if (!buf) { kfree(txb); @@ -97,17 +97,18 @@ struct rxrpc_txbuf *rxrpc_alloc_ack_txbuf(struct rxrpc_call *call, size_t sack_s if (!txb) return NULL; - buf = page_frag_alloc(&call->local->tx_alloc, - sizeof(*whdr) + sizeof(*ack) + 1 + 3 + sizeof(*trailer), gfp); + buf = page_frag_alloc_va(&call->local->tx_alloc, + sizeof(*whdr) + sizeof(*ack) + 1 + 3 + sizeof(*trailer), gfp); if (!buf) { kfree(txb); return NULL; } if (sack_size) { - buf2 = page_frag_alloc(&call->local->tx_alloc, sack_size, gfp); + buf2 = page_frag_alloc_va(&call->local->tx_alloc, sack_size, + gfp); if (!buf2) { - page_frag_free(buf); + page_frag_free_va(buf); kfree(txb); return NULL; } @@ -181,7 +182,7 @@ static void rxrpc_free_txbuf(struct rxrpc_txbuf *txb) rxrpc_txbuf_free); for (i = 0; i < txb->nr_kvec; i++) if (txb->kvec[i].iov_base) - page_frag_free(txb->kvec[i].iov_base); + page_frag_free_va(txb->kvec[i].iov_base); kfree(txb); atomic_dec(&rxrpc_nr_txbuf); } diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 545017a3daa4..055ed38cef97 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1231,8 +1231,8 @@ static int svc_tcp_sendmsg(struct svc_sock *svsk, struct svc_rqst *rqstp, /* The stream record marker is copied into a temporary page * fragment buffer so that it can be included in rq_bvec. */ - buf = page_frag_alloc(&svsk->sk_frag_cache, sizeof(marker), - GFP_KERNEL); + buf = page_frag_alloc_va(&svsk->sk_frag_cache, sizeof(marker), + GFP_KERNEL); if (!buf) return -ENOMEM; memcpy(buf, &marker, sizeof(marker)); From patchwork Thu Mar 28 13:38:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608545 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4126C54E64 for ; Thu, 28 Mar 2024 13:41:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 329A76B008C; Thu, 28 Mar 2024 09:41:00 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2B5906B0092; Thu, 28 Mar 2024 09:41:00 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 105856B0095; Thu, 28 Mar 2024 09:41:00 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id E9F3E6B008C for ; Thu, 28 Mar 2024 09:40:59 -0400 (EDT) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id BB021A026C for ; Thu, 28 Mar 2024 13:40:59 +0000 (UTC) X-FDA: 81946558638.17.5E7E709 Received: from szxga07-in.huawei.com (szxga07-in.huawei.com [45.249.212.35]) by imf29.hostedemail.com (Postfix) with ESMTP id 6139712000B for ; Thu, 28 Mar 2024 13:40:56 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=none; spf=pass (imf29.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.35 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633257; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vbKHpGj9C7ZPz3kFxumqcrbCmjjN1o6Ndlst9Wj+Kfs=; b=PFF2CoatIrT7qyCmihuKt4iM/ElJoaFuPMdsZJRPdS7n+eEOOOqtPv9+5qu9QW8RRvI58E 2TInY8HhKthtrBBOjJjKMtDSwVWRIy+Vwmz7dDvjy71ij3ibtSpJkndwCdsuIHMySQZAaD CTuiuAXgwj7ZGNbv1FzSoCcssWgT4uE= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633257; a=rsa-sha256; cv=none; b=KqtPbnlLqlT6Db8siYC1EXAV5AIjnnP8tS4KlplUGGej1/f3hhI4sbQVvtSJjIXRblG1lZ px2UJMVSb6R/lNPoLHb8iORdYaBU9YVoCThYYfgT/WciT8SMMUtrPTmYtI1yuHiI0hpdDL 3l6O1aDssfVfURXUynmqruyWAlCwobA= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=none; spf=pass (imf29.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.35 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.17]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4V54P074DJz1R8gB; Thu, 28 Mar 2024 21:38:12 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id D62381A0172; Thu, 28 Mar 2024 21:40:53 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:53 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Andrew Morton , Eric Dumazet , Subject: [PATCH RFC 05/10] mm: page_frag: add two inline helper for page_frag API Date: Thu, 28 Mar 2024 21:38:34 +0800 Message-ID: <20240328133839.13620-6-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: 6139712000B X-Rspam-User: X-Stat-Signature: ju9bodw5t4x8akncspdan3q69xb99p9r X-Rspamd-Server: rspam03 X-HE-Tag: 1711633256-736348 X-HE-Meta: U2FsdGVkX1/4cSyXj+PTLbgeYGRHQaCFNDMwVqaC0nFp/5/pCDZ1VdlV9jKFxoRBc9szBRk2heIxLJJMkJjt+n+hSIX4u0RkBuzgI19Exzl67XACzTHLfwF5Do4c0pZ1c5aBEgBc4Z4bUGHWpY3Ialy9gkcDgw+iN/Sm8MsC8HBTgyPY337oGiA/eE+N3soR9t6ygxoSM7A++TTDrGePsZzYOiEZpV0BlJTIwax1y2PUh3Znxpr0DAr0Bssu8wJ2hEvhD3ZJRfKYBfGOHxvtkossDPUm4IizE8sWpDelGeVXMlE5dwiZ5Ijc0lrDG9p06zx0nAsESlp7mTX3fBPHLTYhgzw/u1NJTwfv2sle8A4KRwjkoiQfGrYGLDh8iy26YXXQOTGggyta2B5Xc9NPYWOJ4Qro2VmjtXete7qLphJ/8iSgpYaq9Bax306JV4b6v8LR5jeO68X5PoIWlz2LOZJzkysq/4572z7dyp3BM+iRCOPjmkr9oA/zmVFZXiiurI5K51+hO6fUN3lIT/TNVc/yCds/hNRrBB7tPt4X8FYNpLKZKTlh9mRb660Q+avt0ze73d8wPe3vfladzUu8DcpMZxgYul1s+B5CjPOc6qqIPusPYYcXP5ce418STrGf2cvFXtrUocFG8ExIJJDdkaGlp/NkfPFTmHmszKo57fpulTt1O8UZP/jooB3YreonufvnTGBRRRKIZbmW8XgfuMzda9kj83oP8L3a0rnvEivi3wbJzsdVsPyZKynEkkl7SufK6hBPPihkrWT04SQzdbRise+Dpq/FAd8qfUTeA5vW1C882/5voBPtdoTt3YxNDskRrW0bYvgooiKUi0CE4P017EN0XGppT5g3ED29vnImULIe4nNQuL4wBLw239rSLdzBr2Rd+qRJ72j46buVMOIbWxsbaQNgC141ANQEJbVSPgD1Ai/M6IXFeRacbRaiyUynXLsB3TB1dgfXwrX YDwh3kcD qK53N4AIao3gbAfmGRNqNFIBJ5yyvTS34eMxNfhfmZ0Lnk/FDzQtsANDIanTOEUn53xF2knTIsmdY/EB/I9ADQPTFBpvrjM4HCW+DXVWRlatEqjaCDZSbGFPk8azAC3gSJtQ4QGnCTmwa6fJcZjsGj68bixft3qyvQUbJpQ++ny1F4tM5xEMH1P6n9ZJKig5mq3P7 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add two inline helpers for page_frag API to avoid calling accessing the field of 'struct page_frag_cache'. Signed-off-by: Yunsheng Lin --- include/linux/page_frag_cache.h | 10 ++++++++++ net/core/skbuff.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index 9d5d86b2d3ab..fe5faa80b6c3 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -23,6 +23,16 @@ struct page_frag_cache { bool pfmemalloc; }; +static inline void page_frag_cache_init(struct page_frag_cache *nc) +{ + nc->va = NULL; +} + +static inline bool page_frag_cache_is_pfmemalloc(struct page_frag_cache *nc) +{ + return !!nc->pfmemalloc; +} + void page_frag_cache_drain(struct page_frag_cache *nc); void __page_frag_cache_drain(struct page *page, unsigned int count); void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index aa3adaa2c466..e6bc0dec7463 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -742,12 +742,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, if (in_hardirq() || irqs_disabled()) { nc = this_cpu_ptr(&netdev_alloc_cache); data = page_frag_alloc_va(nc, len, gfp_mask); - pfmemalloc = nc->pfmemalloc; + pfmemalloc = page_frag_cache_is_pfmemalloc(nc); } else { local_bh_disable(); nc = this_cpu_ptr(&napi_alloc_cache.page); data = page_frag_alloc_va(nc, len, gfp_mask); - pfmemalloc = nc->pfmemalloc; + pfmemalloc = page_frag_cache_is_pfmemalloc(nc); local_bh_enable(); } From patchwork Thu Mar 28 13:38:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608546 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F4A0C54E67 for ; Thu, 28 Mar 2024 13:41:03 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C9F276B0095; Thu, 28 Mar 2024 09:41:01 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C521B6B0096; Thu, 28 Mar 2024 09:41:01 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B19456B0098; Thu, 28 Mar 2024 09:41:01 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 94B326B0095 for ; Thu, 28 Mar 2024 09:41:01 -0400 (EDT) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 6458D14069E for ; Thu, 28 Mar 2024 13:41:01 +0000 (UTC) X-FDA: 81946558722.22.532CA4B Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) by imf12.hostedemail.com (Postfix) with ESMTP id 063E94000E for ; Thu, 28 Mar 2024 13:40:58 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=none; spf=pass (imf12.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.191 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633259; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gRd8uG7vDon8UIOOd8j8PGsSlhcHwIdSJGe8YCIjnFU=; b=TcQwmoGcbrejoCEGY2SW1B1x2vOJ7mhlY8RuofPvG0LczHok1h3QRl46CtLjiDvuzrJVLq c8TkVDTsCl/PJ2Hp357BJFrPdxxCkGOE41tGbs97Be3ARIbDDsmIta7a0RtSmPL/rKBCYw Ude8EjBzsm0movyKbjlcP/mGP/iFnM4= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=none; spf=pass (imf12.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.191 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633259; a=rsa-sha256; cv=none; b=MR0HVmncPhd3zcGHbxBmvwg3GLe9Dx27bOQdRfZvnuZMwpWjSP+IqSUo0zNJMXs9gdTISL XoabfL/+SDW87uxIjo2c4SqT+Hm1g92is0UI8h/brjOI93ClMazvqV7JTsqKqk4C3ly6qS MKbXHaHXDBCKefkpLe+MV9dz8FtaYdc= Received: from mail.maildlp.com (unknown [172.19.88.234]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4V54P32lZ6z1h4Kn; Thu, 28 Mar 2024 21:38:15 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id B5FBC140258; Thu, 28 Mar 2024 21:40:55 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:55 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Andrew Morton , Subject: [PATCH RFC 06/10] mm: page_frag: reuse MSB of 'size' field for pfmemalloc Date: Thu, 28 Mar 2024 21:38:35 +0800 Message-ID: <20240328133839.13620-7-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: 063E94000E X-Rspam-User: X-Stat-Signature: x9q3eyzin6pt688st4xd7xxh1hk6o897 X-Rspamd-Server: rspam01 X-HE-Tag: 1711633258-967368 X-HE-Meta: U2FsdGVkX1+ZyEHrF890W3VJz2bw74pbOjp+/M0sRABNaOULzDyQ114GKJsMl+u1LZ3fK0Ph4DBOrPlXpjSlk+v+Z5IXJvdAZZAWXkTlQYJvqv2vVlkR1//g4oyuEMJEpZk7qmHvGXywYR2VjEXRkRi0ecif4HBfGbPL+6Y2lNhC7uhDSig1wSBA1/1teGPbkatO8id9qe/o+Hz8ZJOiRY/lYtrS53qRxbfS09tqhG139PUoCcKpcChhDIF+LT72LTnW1SkVvHyGrKbalM+oIWG+m5JQDlm2VNNQ4ow37l1w8FVaghpXjwxeKE7nwNY3qyFkxhiIpwhUXXucxTccT4gaqlUzddQfZBLsjWrEZySslA2xuXYsrTMgFzgdjv3sktNFjQtZvopmq7MDhhMQMkpbsrkhx0A/VZGImZR1Gh0hH4uUnLOYaf90CUo8MmYIwi/p28688kLn8f4oPPI26qJ87VuLomFv0dbnVrdkwB9En8Gu4i6YPDOAnirPjzS4AuqX0VjNPFV5Pyh6bvjyAtO6tDBssXNI/p6Ej4PoZLGYEM9rkHIbLSkPgE93+RELNB79bbDRKlLmB2rvT4k3DhvnXUoRHSAu41ZW4bSBcP0fI1akUiufPuLgEWP3F7KiFlSaKlKCeDginL9RMucNXrtTcH7iYMmvT3Mfka1n2TqWXCR2MNpa3S7NTzQ4CjNfF6gREdiqw74ykgj2zRnwZniTdDDhrFKHwtu9/mABWwl3w/jQSYk+rvOIOX6HwopTzxipj8Qz4SV1ysQ8O74AreDk3IYVi+Sn28FkWx9RktR80MkZHdTg+1MOLQpw62lee85aBKuI49PAAWpsXBShaJ/MWVDInbnYtDQL7qq7KbNRftw9DqIsS1RZ3gbE9VtS3eNYrx59Acs= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The '(PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE)' case is for the system with page size less than 32KB, which is 0x8000 bytes requiring 16 bits space, change 'size' to 'size_mask' to avoid using the MSB, and change 'pfmemalloc' field to reuse the that MSB, so that we remove the orginal space needed by 'pfmemalloc'. For another case, the MSB of 'offset' is reused for 'pfmemalloc'. Signed-off-by: Yunsheng Lin --- include/linux/page_frag_cache.h | 13 ++++++++----- mm/page_frag_alloc.c | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index fe5faa80b6c3..40a7d6da9ef0 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -12,15 +12,16 @@ struct page_frag_cache { void *va; #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) __u16 offset; - __u16 size; + __u16 size_mask:15; + __u16 pfmemalloc:1; #else - __u32 offset; + __u32 offset:31; + __u32 pfmemalloc:1; #endif /* we maintain a pagecount bias, so that we dont dirty cache line * containing page->_refcount every time we allocate a fragment. */ unsigned int pagecnt_bias; - bool pfmemalloc; }; static inline void page_frag_cache_init(struct page_frag_cache *nc) @@ -43,7 +44,9 @@ static inline void *__page_frag_alloc_va_align(struct page_frag_cache *nc, gfp_t gfp_mask, unsigned int align) { - nc->offset = ALIGN(nc->offset, align); + unsigned int offset = nc->offset; + + nc->offset = ALIGN(offset, align); return page_frag_alloc_va(nc, fragsz, gfp_mask); } @@ -53,7 +56,7 @@ static inline void *page_frag_alloc_va_align(struct page_frag_cache *nc, gfp_t gfp_mask, unsigned int align) { - WARN_ON_ONCE(!is_power_of_2(align)); + WARN_ON_ONCE(!is_power_of_2(align) || align >= PAGE_SIZE); return __page_frag_alloc_va_align(nc, fragsz, gfp_mask, align); } diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index 7f639af4e518..a02e57a439f0 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -29,7 +29,8 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC; page = alloc_pages_node(NUMA_NO_NODE, gfp_mask, PAGE_FRAG_CACHE_MAX_ORDER); - nc->size = page ? PAGE_FRAG_CACHE_MAX_SIZE : PAGE_SIZE; + nc->size_mask = page ? PAGE_FRAG_CACHE_MAX_SIZE - 1 : PAGE_SIZE - 1; + VM_BUG_ON(page && nc->size_mask != PAGE_FRAG_CACHE_MAX_SIZE - 1); #endif if (unlikely(!page)) page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); @@ -88,7 +89,7 @@ void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size; + size = nc->size_mask + 1; #else size = PAGE_SIZE; #endif From patchwork Thu Mar 28 13:38:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608547 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0FA1CD1284 for ; Thu, 28 Mar 2024 13:41:05 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1F1DE6B0098; Thu, 28 Mar 2024 09:41:05 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1A2536B0099; Thu, 28 Mar 2024 09:41:05 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 01B7A6B009A; Thu, 28 Mar 2024 09:41:04 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id CB6686B0098 for ; Thu, 28 Mar 2024 09:41:04 -0400 (EDT) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 9D25DA0140 for ; Thu, 28 Mar 2024 13:41:04 +0000 (UTC) X-FDA: 81946558848.13.A4AF702 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by imf24.hostedemail.com (Postfix) with ESMTP id 0464F18002F for ; Thu, 28 Mar 2024 13:41:01 +0000 (UTC) Authentication-Results: imf24.hostedemail.com; dkim=none; spf=pass (imf24.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.187 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633262; a=rsa-sha256; cv=none; b=28goA/3l9gKw7a7Mj0ZaGYZIHLq25cdLp37YR9qUb1W2D5bftoh5BFVUIz2P3+mX+cgfZ7 jP3Aqiyipj+mORy0CDkDOh9uVR0owr28g660YQ12upLeljDzFmYPrsbMfyCSd/1P2HYeST P0+/B0cZjc0Yprf1eweIngYjvwPpUyE= ARC-Authentication-Results: i=1; imf24.hostedemail.com; dkim=none; spf=pass (imf24.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.187 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633262; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w4kQekiS03AKW+jku5NPBM/1NO5oEvu58K65xm21xKA=; b=naw6KbzKZNF6wHhKDUljrMwedb2fGrndZTUnBvASfmsje7f07BMFt+rcG1smAiFEumMU7K GWT9x8vRJkD3AeHH6cMgdnP8KDivLgEJqkQlru3032c/43XTbUQRjuBt9P3rY/Cx2dYFKE z8OMeSwGsrnK6bNeja3FI0jlk177+fQ= Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4V54P4204YzwQ0X; Thu, 28 Mar 2024 21:38:16 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id BDDE91400CD; Thu, 28 Mar 2024 21:40:57 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:40:57 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Andrew Morton , Subject: [PATCH RFC 07/10] mm: page_frag: reuse existing bit field of 'va' for pagecnt_bias Date: Thu, 28 Mar 2024 21:38:36 +0800 Message-ID: <20240328133839.13620-8-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspam-User: X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 0464F18002F X-Stat-Signature: rf1f3gkqfpwk8puxy71j7m9851jy87ja X-HE-Tag: 1711633261-28627 X-HE-Meta: U2FsdGVkX1+OEbh2lLaV4jeof3UQOd8xmQHU2x7KBQxycMARQZpBbPcJURlKWcCj5DHd1HHKKOQL6bU3Qp0XJJvRSWIBX9GRvqRYCPkn6tJb9S1yadZ/2oEdHSu9WySRodChFhR5OJ6VRhnbI0iOZ/g0DNOz0Ft5uEsiGfQgUImgbP8oEFPkidqDDmGEYFoJ64OQQl8BLQBE0fR7U9s4Ni5mzOEdTgjr5A5cIy5Jet7zLOyxVfyx6pzp8yTWum4C0M7fC5iU+XKNAx17vnFkdUX3n/N+CnCpG3j/jCLM8mVtNLhfkoQs2dc94pykp/sLRmeJ2xQkhey8RRATIrqbFuIeDZ+RZvIZKXZJzCCuMJO+zK+FLgj3E5bp1G8IrS+8eZamp9YF0nQ9TiaEK2Fn2XgHiOWwNdQYxHtgWYbTU3622kJQKnWIIS6ep3jYs1vo2t8Q0RiHyRpGtTMDiHz0HcX+Sd/nPHFgWMVTK1oexQC5NCdraykYOLlGj1RTBTZVkZOm61YeT65DGAbmICyYFB1Is4A5TtvCWOMwSp7/C7yZtoITi6xie7NxEL2Zq32NcmDdQoqLMy80WMrtQLiGZTixJBPrhkBmKTYbQxo8T9CiJZkKwnK+t0WKrqMFOeUByNzYx52O5ETTy/mji5dUWOzuiYIVzK+UfE6y6mlyb1e0KB3NfeVompBf0yuY8snxNyU2DrWgg8UghPgjBW31CTKgxAobBsZoBmah1sXZQ3ieTfWUs420crxk0CKV7UwnYjtqjva3nKNlFjrrblV1AI2yUHyXxRf5eoZ7ZIThDTpQPJzpuYD8urgsgRRElvs72HH2vsa6ix/7adB9w1xycDIlkIXoo1nWQF4ID2IqClIpDq2NxQAw07m06/LM2hXcQDHmfADqz32FMeAy9lx3E0B2IeRUdy1epZ8BG3AHMucn0KEUk9BreoVgYYJPCwFV1taKslTe1/lmkQWSM27 oP9c6JDD MXgfBN3nQk9ubkgPiu3u6Qpft73pQJVQ6JI/MztvTuM2eyAr+LKxjOUQ5NBJaQXnZMKeXEMWoUDD0UtDQylRDBWLaEYo4eUNvASWuWVxTG/F90yqDnqxCYvgx7EqD90aB/taz4aP8Afgpltmpp3IUyBcM3onuLqnVNOA0gJPsiCXOz+b/ob6eGQ1IFbM7MYiLdfm1 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: As alignment of 'va' is always aligned with the order of the page allocated, we can reuse the LSB bits for the pagecount bias, and remove the orginal space needed by 'pagecnt_bias'. Also limit the 'fragsz' to be at least the size of 'usigned int' to match the limited pagecnt_bias. Signed-off-by: Yunsheng Lin --- include/linux/page_frag_cache.h | 20 +++++++---- mm/page_frag_alloc.c | 63 +++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index 40a7d6da9ef0..a97a1ac017d6 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -9,7 +9,18 @@ #define PAGE_FRAG_CACHE_MAX_ORDER get_order(PAGE_FRAG_CACHE_MAX_SIZE) struct page_frag_cache { - void *va; + union { + void *va; + /* we maintain a pagecount bias, so that we dont dirty cache + * line containing page->_refcount every time we allocate a + * fragment. As 'va' is always aligned with the order of the + * page allocated, we can reuse the LSB bits for the pagecount + * bias, and its bit width happens to be indicated by the + * 'size_mask' below. + */ + unsigned long pagecnt_bias; + + }; #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) __u16 offset; __u16 size_mask:15; @@ -18,10 +29,6 @@ struct page_frag_cache { __u32 offset:31; __u32 pfmemalloc:1; #endif - /* we maintain a pagecount bias, so that we dont dirty cache line - * containing page->_refcount every time we allocate a fragment. - */ - unsigned int pagecnt_bias; }; static inline void page_frag_cache_init(struct page_frag_cache *nc) @@ -56,7 +63,8 @@ static inline void *page_frag_alloc_va_align(struct page_frag_cache *nc, gfp_t gfp_mask, unsigned int align) { - WARN_ON_ONCE(!is_power_of_2(align) || align >= PAGE_SIZE); + WARN_ON_ONCE(!is_power_of_2(align) || align >= PAGE_SIZE || + fragsz < sizeof(unsigned int)); return __page_frag_alloc_va_align(nc, fragsz, gfp_mask, align); } diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index a02e57a439f0..ae1393d0619a 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -18,8 +18,8 @@ #include #include "internal.h" -static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, - gfp_t gfp_mask) +static bool __page_frag_cache_refill(struct page_frag_cache *nc, + gfp_t gfp_mask) { struct page *page = NULL; gfp_t gfp = gfp_mask; @@ -35,9 +35,26 @@ static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, if (unlikely(!page)) page = alloc_pages_node(NUMA_NO_NODE, gfp, 0); - nc->va = page ? page_address(page) : NULL; + if (unlikely(!page)) { + nc->va = NULL; + return false; + } + + nc->va = page_address(page); - return page; +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + VM_BUG_ON(nc->pagecnt_bias & nc->size_mask); + page_ref_add(page, nc->size_mask - 1); + nc->pagecnt_bias |= nc->size_mask; +#else + VM_BUG_ON(nc->pagecnt_bias & (PAGE_SIZE - 1)); + page_ref_add(page, PAGE_SIZE - 2); + nc->pagecnt_bias |= (PAGE_SIZE - 1); +#endif + + nc->pfmemalloc = page_is_pfmemalloc(page); + nc->offset = 0; + return true; } void page_frag_cache_drain(struct page_frag_cache *nc) @@ -67,38 +84,31 @@ EXPORT_SYMBOL(__page_frag_cache_drain); void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, gfp_t gfp_mask) { - unsigned int size, offset; + unsigned long size_mask; + unsigned int offset; struct page *page; + void *va; if (unlikely(!nc->va)) { refill: - page = __page_frag_cache_refill(nc, gfp_mask); - if (!page) + if (!__page_frag_cache_refill(nc, gfp_mask)) return NULL; - - /* Even if we own the page, we do not use atomic_set(). - * This would break get_page_unless_zero() users. - */ - page_ref_add(page, PAGE_FRAG_CACHE_MAX_SIZE); - - /* reset page count bias and offset to start of new frag */ - nc->pfmemalloc = page_is_pfmemalloc(page); - nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; - nc->offset = 0; } #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) /* if size can vary use size else just use PAGE_SIZE */ - size = nc->size_mask + 1; + size_mask = nc->size_mask; #else - size = PAGE_SIZE; + size_mask = PAGE_SIZE - 1; #endif + va = (void *)((unsigned long)nc->va & ~size_mask); offset = nc->offset; - if (unlikely(offset + fragsz > size)) { - page = virt_to_page(nc->va); - if (!page_ref_sub_and_test(page, nc->pagecnt_bias)) + if (unlikely(offset + fragsz > (size_mask + 1))) { + page = virt_to_page(va); + + if (!page_ref_sub_and_test(page, nc->pagecnt_bias & size_mask)) goto refill; if (unlikely(nc->pfmemalloc)) { @@ -107,12 +117,11 @@ void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, } /* OK, page count is 0, we can safely set it */ - set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1); + set_page_count(page, size_mask); + nc->pagecnt_bias |= size_mask; - /* reset page count bias and offset to start of new frag */ - nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1; offset = 0; - if (unlikely(fragsz > size)) { + if (unlikely(fragsz > (size_mask + 1))) { /* * The caller is trying to allocate a fragment * with fragsz > PAGE_SIZE but the cache isn't big @@ -129,7 +138,7 @@ void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, nc->pagecnt_bias--; nc->offset = offset + fragsz; - return nc->va + offset; + return va + offset; } EXPORT_SYMBOL(page_frag_alloc_va); From patchwork Thu Mar 28 13:38:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yunsheng Lin X-Patchwork-Id: 13608548 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 97BC5C54E64 for ; Thu, 28 Mar 2024 13:41:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F11986B0099; Thu, 28 Mar 2024 09:41:06 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id EC2556B009A; Thu, 28 Mar 2024 09:41:06 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D141C6B009B; Thu, 28 Mar 2024 09:41:06 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id B2B296B0099 for ; Thu, 28 Mar 2024 09:41:06 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 5CD46C0A9D for ; Thu, 28 Mar 2024 13:41:06 +0000 (UTC) X-FDA: 81946558932.11.2F93D93 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) by imf10.hostedemail.com (Postfix) with ESMTP id 10FAFC001F for ; Thu, 28 Mar 2024 13:41:03 +0000 (UTC) Authentication-Results: imf10.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf10.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.190 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711633264; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yCYDp/XbyUd0jUC8G9YQwMvOnUflWEyDFLqBUw4b2iM=; b=LYnY+kaNfKMGY5WtXrqMqF8qSS58SakwEb+w4UeMCYzXInm7Jj/HrAtYuxe6KqjTqJO6yV O2ut6PbpM31zQlx8h5zrlULn4GmYIRcr2REcMvWAAFlY8Bst445rm6GeZdWEhOQ13IVmSn dfq+exADDxhGEdRJD2M+MAAVkYAAk90= ARC-Authentication-Results: i=1; imf10.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf10.hostedemail.com: domain of linyunsheng@huawei.com designates 45.249.212.190 as permitted sender) smtp.mailfrom=linyunsheng@huawei.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711633264; a=rsa-sha256; cv=none; b=Wd61ZGdcn96Z8KaMEZZ19hc0vFpNZ4L0P8c7uyVHofmwdec8FtW0Nb/6NlqHpnTD75dTcd h17MKr1Kb32hCqXN7dq0y7t26deiED3P9C+0EDOS+QL1aUzLn8hsPOZSoZSh2TrZ4zausc F5etKIjL16txQWNdioA75vmBxcR/L1o= Received: from mail.maildlp.com (unknown [172.19.163.44]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4V54Pv4MbXz1xrhm; Thu, 28 Mar 2024 21:38:59 +0800 (CST) Received: from dggpemm500005.china.huawei.com (unknown [7.185.36.74]) by mail.maildlp.com (Postfix) with ESMTPS id 4BF871402CA; Thu, 28 Mar 2024 21:41:01 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by dggpemm500005.china.huawei.com (7.185.36.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 28 Mar 2024 21:41:01 +0800 From: Yunsheng Lin To: , , CC: , , Yunsheng Lin , Andrew Morton , Subject: [PATCH RFC 09/10] mm: page_frag: introduce prepare/commit API for page_frag Date: Thu, 28 Mar 2024 21:38:38 +0800 Message-ID: <20240328133839.13620-10-linyunsheng@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20240328133839.13620-1-linyunsheng@huawei.com> References: <20240328133839.13620-1-linyunsheng@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500005.china.huawei.com (7.185.36.74) X-Rspamd-Queue-Id: 10FAFC001F X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: m9jqfcd4qioof4cqdtoesqymjirp1d1e X-HE-Tag: 1711633263-319468 X-HE-Meta: U2FsdGVkX18ixDNt4KB0+U1xGsBilSHk4HLLDqpCNdwC6zn0KJ7vdoVuTsN7S39OupJnbzV/4aHAOoJA7GNJwbxZ4wnQzp3wR4fQtrlrrgQEoFW55f4GRwgBCSN8mMyeJEKD+0qRnDzmRTzSo6XfdaMlALCAiF5uZKJY7y2ynLcSWVHkqUm9vSsy27LP+kBZVYmPSjPf7l8cijsYIWFviaOL9uZ/NcZcf2mNcWRaO366uriDuh9EjKJc/OHn2yoX3aFKaTdFeNSy+FxwdYucWY+9ePIEJqFb1MNu1hm7shtu5L4hiD9iopErPVpj5yhPMmq1TE9kBiDM5ZzWufCMtk07eT7+eoa8/XeGOSCgJKWFBbCEaAX+689j9/rmpvZn8y2cjcEwo0O3DS7HWWvA46e+3Wb+ZfKRgFnwSMXDj+YdsG2qx6kr8VzRR43vB5PvUu2bMme0//iIV+xuNzAYvqqRvZzDx97sc6ku2O1IiTOjBaogMMAT3f6f9kgzWAkcA7Cui/4F8TO+RkV551suaqVv61dGKIcfeYh8Xu9GVMZ/q7e3MI40hsrHtCEa84QXcvcL9sTRwuP3/knvWqOUo5XkBaYBRNUdcKvE8cPdgRWveaJimQTdwQx1eiX2cwNgXkObppWt1prEdyKsAk4uow/DU9wib4EGzinDUkOV2EVtkAOr/Zy9SYAtWR1KiPEirzSSL19DhCYaPQYSg66eovbjjHhSAvqZ7sfKifAyfRKMcAgSpRDE7BgEJ0eDqet/4JUx9BiEdr0l/7r7i5JNIdEJ6HS4Y8hbvUVKNhz0fttg9t9K5Pi3sVWrzqoGbkWz9LGi/li6kDIC8EW4TOr9SJva41uMjYmjy8R3JmEEMGzKkUaisok7auXlNQVvm7Y2IThFxbNeAPg= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: There are many use cases that need minimum memory in order for forward progressing, but can do better if there is more memory available. Currently skb_page_frag_refill() API is used to solve the above usecases, as mentioned in [1], its implementation is similar to the one in mm subsystem. To unify those two page_frag implementations, introduce a prepare API to ensure minimum memory is satisfied and return how much the actual memory is available to the caller. And the caller can decide how much memory to use by calling commit API, or not calling the commit API if deciding to not use any memory. 1. https://lore.kernel.org/all/20240228093013.8263-1-linyunsheng@huawei.com/ Signed-off-by: Yunsheng Lin --- include/linux/page_frag_cache.h | 72 ++++++++++++++++++++++++++++++++- mm/page_frag_alloc.c | 13 +++--- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h index a97a1ac017d6..3f17c0eba7fa 100644 --- a/include/linux/page_frag_cache.h +++ b/include/linux/page_frag_cache.h @@ -43,8 +43,76 @@ static inline bool page_frag_cache_is_pfmemalloc(struct page_frag_cache *nc) void page_frag_cache_drain(struct page_frag_cache *nc); void __page_frag_cache_drain(struct page *page, unsigned int count); -void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask); +void *__page_frag_alloc_prepare(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask); + +static inline void *page_frag_alloc_va(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask) +{ + void *va; + + va = __page_frag_alloc_prepare(nc, fragsz, gfp_mask); + if (unlikely(!va)) + return NULL; + + va += nc->offset; + nc->pagecnt_bias--; + nc->offset = nc->offset + fragsz; + + return va; +} + +static inline void *page_frag_alloc_prepare(struct page_frag_cache *nc, + unsigned int *offset, + unsigned int *size, + gfp_t gfp_mask) +{ + void *va; + + va = __page_frag_alloc_prepare(nc, *size, gfp_mask); + if (unlikely(!va)) + return NULL; + + *offset = nc->offset; + +#if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE) + *size = nc->size_mask - *offset + 1; +#else + *size = PAGE_SIZE - *offset; +#endif + + return va; +} + +static inline void *page_frag_alloc_prepare_align(struct page_frag_cache *nc, + unsigned int *offset, + unsigned int *size, + unsigned int align, + gfp_t gfp_mask) +{ + unsigned int old_offset = nc->offset; + + WARN_ON_ONCE(!is_power_of_2(align) || align >= PAGE_SIZE || + *size < sizeof(unsigned int)); + + nc->offset = ALIGN(old_offset, align); + return page_frag_alloc_prepare(nc, offset, size, gfp_mask); +} + +static inline void page_frag_alloc_commit(struct page_frag_cache *nc, + unsigned int offset, + unsigned int size) +{ + nc->pagecnt_bias--; + nc->offset = offset + size; +} + +static inline void page_frag_alloc_commit_noref(struct page_frag_cache *nc, + unsigned int offset, + unsigned int size) +{ + nc->offset = offset + size; +} static inline void *__page_frag_alloc_va_align(struct page_frag_cache *nc, unsigned int fragsz, diff --git a/mm/page_frag_alloc.c b/mm/page_frag_alloc.c index ae1393d0619a..c4d4fc10a850 100644 --- a/mm/page_frag_alloc.c +++ b/mm/page_frag_alloc.c @@ -81,8 +81,8 @@ void __page_frag_cache_drain(struct page *page, unsigned int count) } EXPORT_SYMBOL(__page_frag_cache_drain); -void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, - gfp_t gfp_mask) +void *__page_frag_alloc_prepare(struct page_frag_cache *nc, unsigned int fragsz, + gfp_t gfp_mask) { unsigned long size_mask; unsigned int offset; @@ -120,7 +120,7 @@ void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, set_page_count(page, size_mask); nc->pagecnt_bias |= size_mask; - offset = 0; + nc->offset = 0; if (unlikely(fragsz > (size_mask + 1))) { /* * The caller is trying to allocate a fragment @@ -135,12 +135,9 @@ void *page_frag_alloc_va(struct page_frag_cache *nc, unsigned int fragsz, } } - nc->pagecnt_bias--; - nc->offset = offset + fragsz; - - return va + offset; + return va; } -EXPORT_SYMBOL(page_frag_alloc_va); +EXPORT_SYMBOL(__page_frag_alloc_prepare); /* * Frees a page fragment allocated out of either a compound or order 0 page.