linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Alexander H Duyck <alexander.duyck@gmail.com>
To: Yunsheng Lin <linyunsheng@huawei.com>,
	davem@davemloft.net, kuba@kernel.org,  pabeni@redhat.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	linux-mm@kvack.org
Subject: Re: [PATCH net-next v9 07/13] mm: page_frag: some minor refactoring before adding new API
Date: Tue, 02 Jul 2024 08:30:16 -0700	[thread overview]
Message-ID: <ce969484bc8deee1438a019f19b97618937b0047.camel@gmail.com> (raw)
In-Reply-To: <20240625135216.47007-8-linyunsheng@huawei.com>

On Tue, 2024-06-25 at 21:52 +0800, Yunsheng Lin wrote:
> Refactor common codes from __page_frag_alloc_va_align()
> to __page_frag_cache_refill(), so that the new API can
> make use of them.
> 
> CC: Alexander Duyck <alexander.duyck@gmail.com>
> Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>

I am generally not a fan of the concept behind this patch. I really
think we should keep the page_frag_cache_refill function to just
allocating the page, or in this case the encoded_va and populating only
that portion of the struct.

> ---
>  mm/page_frag_cache.c | 61 ++++++++++++++++++++++----------------------
>  1 file changed, 31 insertions(+), 30 deletions(-)
> 
> diff --git a/mm/page_frag_cache.c b/mm/page_frag_cache.c
> index a3316dd50eff..4fd421d4f22c 100644
> --- a/mm/page_frag_cache.c
> +++ b/mm/page_frag_cache.c
> @@ -29,10 +29,36 @@ static void *page_frag_cache_current_va(struct page_frag_cache *nc)
>  static struct page *__page_frag_cache_refill(struct page_frag_cache *nc,
>  					     gfp_t gfp_mask)
>  {
> -	struct page *page = NULL;
> +	struct encoded_va *encoded_va = nc->encoded_va;
>  	gfp_t gfp = gfp_mask;
>  	unsigned int order;
> +	struct page *page;
> +
> +	if (unlikely(!encoded_va))
> +		goto alloc;
> +
> +	page = virt_to_page(encoded_va);
> +	if (!page_ref_sub_and_test(page, nc->pagecnt_bias))
> +		goto alloc;
> +
> +	if (unlikely(encoded_page_pfmemalloc(encoded_va))) {
> +		VM_BUG_ON(compound_order(page) !=
> +			  encoded_page_order(encoded_va));
> +		free_unref_page(page, encoded_page_order(encoded_va));
> +		goto alloc;
> +	}
> +
> +	/* OK, page count is 0, we can safely set it */
> +	set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1);

Why not just make this block of code a function onto itself? You put an
if statement at the top that essentially is just merging two functions
into one. Perhaps this logic could be __page_frag_cache_recharge which
would return an error if the page is busy or the wrong type. Then
acting on that you could switch to the refill attempt.

Also thinking about it more the set_page_count in this function and
page_ref_add in the other can probably be merged into the recharge and
refill functions since they are acting directly on the encoded page and
not interacting with the other parts of the page_frag_cache.

> +
> +	/* reset page count bias and remaining of new frag */
> +	nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1;
> +	nc->remaining = page_frag_cache_page_size(encoded_va);

These two parts are more or less agnostic to the setup and could be
applied to refill or recharge. Also one thought occurs to me. You were
encoding "order" into the encoded VA. Why use that when your choices
are either PAGE_FRAG_CACHE_MAX_SIZE or PAGE_SIZE. It should be a single
bit and doesn't need to be a fully byte to store that. That would allow
you to reduce this down to just 2 bits, one for pfmemalloc and one for
max order vs order 0.

> +
> +	return page;
>  
> +alloc:
> +	page = NULL;
>  #if (PAGE_SIZE < PAGE_FRAG_CACHE_MAX_SIZE)
>  	gfp_mask = (gfp_mask & ~__GFP_DIRECT_RECLAIM) |  __GFP_COMP |
>  		   __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC;
> @@ -89,40 +115,15 @@ void *__page_frag_alloc_va_align(struct page_frag_cache *nc,
>  				 unsigned int fragsz, gfp_t gfp_mask,
>  				 unsigned int align_mask)
>  {
> -	struct encoded_va *encoded_va = nc->encoded_va;
> -	struct page *page;
> -	int remaining;
> +	int remaining = nc->remaining & align_mask;
>  	void *va;
>  
> -	if (unlikely(!encoded_va)) {
> -refill:
> -		if (unlikely(!__page_frag_cache_refill(nc, gfp_mask)))
> -			return NULL;
> -
> -		encoded_va = nc->encoded_va;
> -	}
> -
> -	remaining = nc->remaining & align_mask;
>  	remaining -= fragsz;
>  	if (unlikely(remaining < 0)) {

I see, so this is why you were using the memset calls everywhere.

> -		page = virt_to_page(encoded_va);
> -		if (!page_ref_sub_and_test(page, nc->pagecnt_bias))
> -			goto refill;
> -
> -		if (unlikely(encoded_page_pfmemalloc(encoded_va))) {
> -			VM_BUG_ON(compound_order(page) !=
> -				  encoded_page_order(encoded_va));
> -			free_unref_page(page, encoded_page_order(encoded_va));
> -			goto refill;
> -		}
> -
> -		/* OK, page count is 0, we can safely set it */
> -		set_page_count(page, PAGE_FRAG_CACHE_MAX_SIZE + 1);
> +		if (unlikely(!__page_frag_cache_refill(nc, gfp_mask)))
> +			return NULL;
>  
> -		/* reset page count bias and remaining of new frag */
> -		nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1;
> -		nc->remaining = remaining = page_frag_cache_page_size(encoded_va);
> -		remaining -= fragsz;
> +		remaining = nc->remaining - fragsz;
>  		if (unlikely(remaining < 0)) {
>  			/*
>  			 * The caller is trying to allocate a fragment




  reply	other threads:[~2024-07-02 15:30 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240625135216.47007-1-linyunsheng@huawei.com>
2024-06-25 13:52 ` [PATCH net-next v9 01/13] mm: page_frag: add a test module for page_frag Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 02/13] mm: move the page fragment allocator from page_alloc into its own file Yunsheng Lin
2024-07-01 23:10   ` Alexander H Duyck
2024-07-02 12:27     ` Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 03/13] mm: page_frag: use initial zero offset for page_frag_alloc_align() Yunsheng Lin
2024-07-01 23:27   ` Alexander H Duyck
2024-07-02 12:28     ` Yunsheng Lin
2024-07-02 16:00       ` Alexander Duyck
2024-07-03 11:25         ` Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 04/13] mm: page_frag: add '_va' suffix to page_frag API Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 05/13] mm: page_frag: avoid caller accessing 'page_frag_cache' directly Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 06/13] mm: page_frag: reuse existing space for 'size' and 'pfmemalloc' Yunsheng Lin
2024-07-02  0:08   ` Alexander H Duyck
2024-07-02 12:35     ` Yunsheng Lin
2024-07-02 14:55       ` Alexander H Duyck
2024-07-03 12:33         ` Yunsheng Lin
2024-07-10 15:28           ` Alexander H Duyck
2024-07-11  8:16             ` Yunsheng Lin
2024-07-11 16:49               ` Alexander Duyck
2024-07-12  8:42                 ` Yunsheng Lin
2024-07-12 16:55                   ` Alexander Duyck
2024-07-13  5:20                     ` Yunsheng Lin
2024-07-13 16:55                       ` Alexander Duyck
     [not found]                         ` <12ff13d9-1f3d-4c1b-a972-2efb6f247e31@gmail.com>
2024-07-15 17:55                           ` Alexander Duyck
2024-07-16 12:58                             ` Yunsheng Lin
2024-07-17 12:31                               ` Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 07/13] mm: page_frag: some minor refactoring before adding new API Yunsheng Lin
2024-07-02 15:30   ` Alexander H Duyck [this message]
2024-07-03 12:36     ` Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 08/13] mm: page_frag: use __alloc_pages() to replace alloc_pages_node() Yunsheng Lin
2024-06-25 13:52 ` [PATCH net-next v9 10/13] mm: page_frag: introduce prepare/probe/commit API Yunsheng Lin
2024-06-28 22:35   ` Alexander H Duyck
2024-06-29 11:15     ` Yunsheng Lin
2024-06-29 17:37       ` Alexander Duyck
     [not found]         ` <0a80e362-1eb7-40b0-b1b9-07ec5a6506ea@gmail.com>
2024-06-30 14:35           ` Alexander Duyck
2024-06-30 15:05             ` Yunsheng Lin
2024-07-03 12:40               ` Yunsheng Lin
2024-07-07 17:12                 ` Alexander Duyck
2024-07-08 10:58                   ` Yunsheng Lin
2024-07-08 14:30                     ` Alexander Duyck
2024-07-09  6:57                       ` Yunsheng Lin
2024-07-09 13:40                         ` Alexander Duyck
2024-06-25 13:52 ` [PATCH net-next v9 12/13] mm: page_frag: update documentation for page_frag Yunsheng Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ce969484bc8deee1438a019f19b97618937b0047.camel@gmail.com \
    --to=alexander.duyck@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linyunsheng@huawei.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).