mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yunsheng Lin <linyunsheng@huawei.com>
To: Alexander Duyck <alexander.duyck@gmail.com>,
	Yunsheng Lin <yunshenglin0825@gmail.com>
Cc: <davem@davemloft.net>, <kuba@kernel.org>, <pabeni@redhat.com>,
	<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>, <linux-mm@kvack.org>
Subject: Re: [PATCH net-next v22 07/14] mm: page_frag: some minor refactoring before adding new API
Date: Mon, 21 Oct 2024 17:34:45 +0800	[thread overview]
Message-ID: <32e73dd8-5cc8-4211-ab5f-ab10281902e6@huawei.com> (raw)
In-Reply-To: <CAKgT0UeM15+HZor5_woJ4Fd_YrHVgrMM86wD4o5xGczQXC2aOg@mail.gmail.com>

On 2024/10/20 23:45, Alexander Duyck wrote:

...

> 
>>>
>>>
>>>> @@ -132,8 +156,6 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc,
>>>>                          return NULL;
>>>>                  }
>>>>
>>>> -               page = encoded_page_decode_page(encoded_page);
>>>> -
>>>>                  if (!page_ref_sub_and_test(page, nc->pagecnt_bias))
>>>>                          goto refill;
>>>>
>>>> @@ -148,15 +170,17 @@ void *__page_frag_alloc_align(struct page_frag_cache *nc,
>>>>
>>>>                  /* reset page count bias and offset to start of new frag */
>>>>                  nc->pagecnt_bias = PAGE_FRAG_CACHE_MAX_SIZE + 1;
>>>> +               nc->offset = 0;
>>>>                  offset = 0;
>>>>          }
>>>>
>>>> -       nc->pagecnt_bias--;
>>>> -       nc->offset = offset + fragsz;
>>>> +       pfrag->page = page;
>>>> +       pfrag->offset = offset;
>>>> +       pfrag->size = size - offset;
>>>
>>> I really think we should still be moving the nc->offset forward at
>>> least with each allocation. It seems like you end up doing two flavors
>>> of commit, one with and one without the decrement of the bias. So I
>>> would be okay with that being pulled out into some separate logic to
>>> avoid the extra increment in the case of merging the pages. However in
>>> both cases you need to move the offset, so I would recommend keeping
>>> that bit there as it would allow us to essentially call this multiple
>>> times without having to do a commit in between to keep the offset
>>> correct. With that your commit logic only has to verify nothing
>>> changes out from underneath us and then update the pagecnt_bias if
>>> needed.
>>
>> The problem is that we don't really know how much the nc->offset
>> need to be moved forward to and the caller needs the original offset
>> for skb_fill_page_desc() related calling when prepare API is used as
>> an example in 'Preparation & committing API' section of patch 13:
> 
> The thing is you really have 2 different APIs. You have one you were
> doing which was a alloc/abort approach and another that is a
> probe/commit approach. I think for the probe/commit you could probably
> get away with using an "alloc" type approach with a size of 0 which
> would correctly set the start of your offset and then you would need
> to update it later once you know the total size for your commit. For

It seems there are some issues with the above approach as below as I
can see for now:
1. when nc->encoded_page is 0, Calling the "alloc" type API with
fragsz being zero may still allocate a new page from allocator, which
seems to against the purpose of probe API, right?

2. It doesn't allow the caller to specify a fragsz for probing, instead
   it rely on the caller to check if the size of probed fragment is bigger
   enough for its use case.

> the probe/commit we could use the nc->offset as a kind of cookie to
> verify we are working with the expected page and offset.

I am not sure if I am following the above, but I should mention that
nc->offset is not updated for prepare/probe API because the original
offset might be used for calculating the truesize of the fragment
when commit API is called, and the offset returned to the caller might
need to be updated according to alignment requirement, so I am not sure
how nc->offset can be used to verify the exact offset here.

If it is realy about catching misuse of the page_frag API, it might be
better to add something like nc->last_offset to record the offset of
allocated fragment under some config like PAGE_FRAG_DEBUG, as there
are other ways that the caller might mess up here like messing up the
allocation context assumtion.

> 
> For the alloc/abort it would be something similar but more the
> reverse. With that one we would need to have the size + offset and
> then verify the current offset is equal to that before we allow
> reverting the previous nc->offset update. The current patch set is a
> bit too permissive on the abort in my opinion and should be verifying
> that we are updating the correct offset.

I am not sure if I understand what is your idea about how to do an
exact verifying for abort API here.
For abort API, it seems we can do an exact verifying if the 'va' is
also passed to the abort API as the nc->offset is already updated,
something like below:

static inline void page_frag_alloc_abort(struct page_frag_cache *nc,
					 void *va, unsigned int fragsz)
{
        VM_BUG_ON((nc->offset - fragsz) !=
		  (encoded_page_decode_virt(nc->encoded_page) - va));

        nc->pagecnt_bias++;
        nc->offset -= fragsz;
}

But it also might mean we need to put page_frag_alloc_abort() in
page_frag_cache.c instead of a inline helper in page_frag_cache.h, as
the encoded_page_decode_virt() is a static function in c file. Or put
encoded_page_decode_virt() in the h file.

  reply	other threads:[~2024-10-21  9:34 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-18 10:53 [PATCH net-next v22 00/14] Replace page_frag with page_frag_cache for sk_page_frag() Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 01/14] mm: page_frag: add a test module for page_frag Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 02/14] mm: move the page fragment allocator from page_alloc into its own file Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 03/14] mm: page_frag: use initial zero offset for page_frag_alloc_align() Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 04/14] mm: page_frag: avoid caller accessing 'page_frag_cache' directly Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 05/14] xtensa: remove the get_order() implementation Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 06/14] mm: page_frag: reuse existing space for 'size' and 'pfmemalloc' Yunsheng Lin
2024-10-18 16:43   ` Alexander Duyck
2024-10-18 10:53 ` [PATCH net-next v22 07/14] mm: page_frag: some minor refactoring before adding new API Yunsheng Lin
2024-10-18 17:26   ` Alexander Duyck
2024-10-19  8:29     ` Yunsheng Lin
2024-10-20 15:45       ` Alexander Duyck
2024-10-21  9:34         ` Yunsheng Lin [this message]
2024-10-18 10:53 ` [PATCH net-next v22 08/14] mm: page_frag: use __alloc_pages() to replace alloc_pages_node() Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 09/14] net: rename skb_copy_to_page_nocache() helper Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 10/14] mm: page_frag: introduce prepare/probe/commit API Yunsheng Lin
2024-10-18 18:03   ` Alexander Duyck
2024-10-19  8:33     ` Yunsheng Lin
2024-10-20 16:04       ` Alexander Duyck
2024-10-21  9:36         ` Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 11/14] mm: page_frag: add testing for the newly added prepare API Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 12/14] net: replace page_frag with page_frag_cache Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 13/14] mm: page_frag: update documentation for page_frag Yunsheng Lin
2024-10-20 10:02   ` Bagas Sanjaya
2024-10-21  9:32     ` Yunsheng Lin
2024-10-18 10:53 ` [PATCH net-next v22 14/14] mm: page_frag: add an entry in MAINTAINERS " Yunsheng Lin
2024-10-18 17:39 ` [PATCH net-next v22 00/14] Replace page_frag with page_frag_cache for sk_page_frag() Alexander Duyck
2024-10-19  8:27   ` Yunsheng Lin
2024-10-24  9:05     ` Paolo Abeni
2024-10-24 11:39       ` Yunsheng Lin
2024-10-27  3:42       ` 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=32e73dd8-5cc8-4211-ab5f-ab10281902e6@huawei.com \
    --to=linyunsheng@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexander.duyck@gmail.com \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=yunshenglin0825@gmail.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

all inboxes | Powered by JetHome®