linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Duyck <alexander.duyck@gmail.com>
To: Yunsheng Lin <linyunsheng@huawei.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 <linux-mm@kvack.org>,  Jonathan Corbet <corbet@lwn.net>,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH RFC 04/10] mm: page_frag: introduce page_frag_alloc_abort() related API
Date: Mon, 28 Oct 2024 10:53:33 -0700	[thread overview]
Message-ID: <CAKgT0UfouCZpX04yzvCrB_UBmy47p+=xm5qViYowerR9dPcCbg@mail.gmail.com> (raw)
In-Reply-To: <20241028115850.3409893-5-linyunsheng@huawei.com>

On Mon, Oct 28, 2024 at 5:05 AM Yunsheng Lin <linyunsheng@huawei.com> wrote:
>
> For some case as tun_build_skb() without the needing of
> using complicated prepare & commit API, add the abort API to
> abort the operation of page_frag_alloc_*() related API for
> error handling knowing that no one else is taking extra
> reference to the just allocated fragment, and add abort_ref
> API to only abort the reference counting of the allocated
> fragment if it is already referenced by someone else.
>
> CC: Alexander Duyck <alexander.duyck@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: Linux-MM <linux-mm@kvack.org>
> Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
> ---
>  Documentation/mm/page_frags.rst |  7 +++++--
>  include/linux/page_frag_cache.h | 20 ++++++++++++++++++++
>  mm/page_frag_cache.c            | 21 +++++++++++++++++++++
>  3 files changed, 46 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/mm/page_frags.rst b/Documentation/mm/page_frags.rst
> index 34e654c2956e..339e641beb53 100644
> --- a/Documentation/mm/page_frags.rst
> +++ b/Documentation/mm/page_frags.rst
> @@ -114,9 +114,10 @@ fragsz if there is an alignment requirement for the size of the fragment.
>  .. kernel-doc:: include/linux/page_frag_cache.h
>     :identifiers: page_frag_cache_init page_frag_cache_is_pfmemalloc
>                  __page_frag_alloc_align page_frag_alloc_align page_frag_alloc
> +                page_frag_alloc_abort
>
>  .. kernel-doc:: mm/page_frag_cache.c
> -   :identifiers: page_frag_cache_drain page_frag_free
> +   :identifiers: page_frag_cache_drain page_frag_free page_frag_alloc_abort_ref
>
>  Coding examples
>  ===============
> @@ -143,8 +144,10 @@ Allocation & freeing API
>          goto do_error;
>
>      err = do_something(va, size);
> -    if (err)
> +    if (err) {
> +        page_frag_alloc_abort(nc, va, size);
>          goto do_error;
> +    }
>
>      ...
>
> diff --git a/include/linux/page_frag_cache.h b/include/linux/page_frag_cache.h
> index a2b1127e8ac8..c3347c97522c 100644
> --- a/include/linux/page_frag_cache.h
> +++ b/include/linux/page_frag_cache.h
> @@ -141,5 +141,25 @@ static inline void *page_frag_alloc(struct page_frag_cache *nc,
>  }
>
>  void page_frag_free(void *addr);
> +void page_frag_alloc_abort_ref(struct page_frag_cache *nc, void *va,
> +                              unsigned int fragsz);
> +
> +/**
> + * page_frag_alloc_abort - Abort the page fragment allocation.
> + * @nc: page_frag cache to which the page fragment is aborted back
> + * @va: virtual address of page fragment to be aborted
> + * @fragsz: size of the page fragment to be aborted
> + *
> + * It is expected to be called from the same context as the allocation API.
> + * Mostly used for error handling cases to abort the fragment allocation knowing
> + * that no one else is taking extra reference to the just aborted fragment, so
> + * that the aborted fragment can be reused.
> + */
> +static inline void page_frag_alloc_abort(struct page_frag_cache *nc, void *va,
> +                                        unsigned int fragsz)
> +{
> +       page_frag_alloc_abort_ref(nc, va, fragsz);
> +       nc->offset -= fragsz;
> +}
>
>  #endif
> diff --git a/mm/page_frag_cache.c b/mm/page_frag_cache.c
> index d014130fb893..4d5626da42ed 100644
> --- a/mm/page_frag_cache.c
> +++ b/mm/page_frag_cache.c
> @@ -201,3 +201,24 @@ void page_frag_free(void *addr)
>                 free_unref_page(page, compound_order(page));
>  }
>  EXPORT_SYMBOL(page_frag_free);
> +
> +/**
> + * page_frag_alloc_abort_ref - Abort the reference of allocated fragment.
> + * @nc: page_frag cache to which the page fragment is aborted back
> + * @va: virtual address of page fragment to be aborted
> + * @fragsz: size of the page fragment to be aborted
> + *
> + * It is expected to be called from the same context as the allocation API.
> + * Mostly used for error handling cases to abort the reference of allocated
> + * fragment if the fragment has been referenced for other usages, to aovid the
> + * atomic operation of page_frag_free() API.
> + */
> +void page_frag_alloc_abort_ref(struct page_frag_cache *nc, void *va,
> +                              unsigned int fragsz)
> +{
> +       VM_BUG_ON(va + fragsz !=
> +                 encoded_page_decode_virt(nc->encoded_page) + nc->offset);
> +
> +       nc->pagecnt_bias++;
> +}
> +EXPORT_SYMBOL(page_frag_alloc_abort_ref);

It isn't clear to me why you split this over two functions. It seems
like you could just update the offset in this lower function rather
than do it in the upper one since you are passing all the arguments
here anyway.


  reply	other threads:[~2024-10-28 17:54 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20241028115850.3409893-1-linyunsheng@huawei.com>
2024-10-28 11:58 ` [PATCH RFC 01/10] mm: page_frag: some minor refactoring before adding new API Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 02/10] net: rename skb_copy_to_page_nocache() helper Yunsheng Lin
2024-10-28 17:49   ` Alexander Duyck
2024-10-28 11:58 ` [PATCH RFC 03/10] mm: page_frag: update documentation for page_frag Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 04/10] mm: page_frag: introduce page_frag_alloc_abort() related API Yunsheng Lin
2024-10-28 17:53   ` Alexander Duyck [this message]
2024-10-29  9:39     ` Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 05/10] mm: page_frag: introduce refill prepare & commit API Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 06/10] mm: page_frag: introduce alloc_refill " Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 07/10] mm: page_frag: introduce probe related API Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 08/10] mm: page_frag: add testing for the newly added API Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 09/10] net: replace page_frag with page_frag_cache Yunsheng Lin
2024-10-28 11:58 ` [PATCH RFC 10/10] mm: page_frag: add an entry in MAINTAINERS for page_frag Yunsheng Lin
2024-10-28 23:27   ` Jakub Kicinski
2024-10-29  9:40     ` Yunsheng Lin
2024-10-29 14:33       ` Jakub Kicinski
2024-10-30 11:32         ` 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='CAKgT0UfouCZpX04yzvCrB_UBmy47p+=xm5qViYowerR9dPcCbg@mail.gmail.com' \
    --to=alexander.duyck@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=corbet@lwn.net \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.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