linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Yang Shi <shy828301@gmail.com>
To: Peter Xu <peterx@redhat.com>
Cc: David Hildenbrand <david@redhat.com>,
	kernel test robot <oliver.sang@intel.com>,
	 Jason Gunthorpe <jgg@nvidia.com>,
	Vivek Kasireddy <vivek.kasireddy@intel.com>,
	 Rik van Riel <riel@surriel.com>,
	oe-lkp@lists.linux.dev, lkp@intel.com,
	 linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	 Matthew Wilcox <willy@infradead.org>,
	Christopher Lameter <cl@linux.com>,
	linux-mm@kvack.org
Subject: Re: [linus:master] [mm] efa7df3e3b: kernel_BUG_at_include/linux/page_ref.h
Date: Fri, 31 May 2024 17:01:18 -0700	[thread overview]
Message-ID: <CAHbLzkrRw-xf819gYJwRQ=-u971LQYnB2FNJMkN=s6u-pJ4Z8g@mail.gmail.com> (raw)
In-Reply-To: <ZlpcRnuZUEYJJ0JA@x1n>

On Fri, May 31, 2024 at 4:25 PM Peter Xu <peterx@redhat.com> wrote:
>
> On Fri, May 31, 2024 at 07:46:41PM +0200, David Hildenbrand wrote:
> > try_grab_folio()->try_get_folio()->folio_ref_try_add_rcu()
> >
> > Is called (mm-unstable) from:
> >
> > (1) gup_fast function, here IRQs are disable
> > (2) gup_hugepte(), possibly problematic
> > (3) memfd_pin_folios(), possibly problematic
> > (4) __get_user_pages(), likely problematic
> >
> > (1) should be fine.
> >
> > (2) is possibly problematic on the !fast path. If so, due to commit
> >     a12083d721d7 ("mm/gup: handle hugepd for follow_page()") ? CCing Peter.
> >
> > (3) is possibly wrong. CCing Vivek.
> >
> > (4) is what we hit here
>
> I guess it was overlooked because try_grab_folio() didn't have any comment
> or implication on RCU or IRQ internal helpers being used, hence a bit
> confusing.  E.g. it has different context requirement on try_grab_page(),
> even though they look like sister functions.  It might be helpful to have a
> better name, something like try_grab_folio_rcu() in this case.
>
> Btw, none of above cases (2-4) have real bug, but we're looking at some way
> to avoid triggering the sanity check, am I right?  I hope besides the host
> splash I didn't overlook any other side effect this issue would cause, and
> the splash IIUC should so far be benign, as either gup slow (2,4) or the
> newly added memfd_pin_folios() (3) look like to have the refcount stablized
> anyway.
>
> Yang's patch in the other email looks sane to me, just that then we'll add
> quite some code just to avoid this sanity check in paths 2-4 which seems
> like an slight overkill.
>
> One thing I'm thinking is whether folio_ref_try_add_rcu() can get rid of
> its RCU limitation. It boils down to whether we can use atomic_add_unless()
> on TINY_RCU / UP setup too?  I mean, we do plenty of similar things
> (get_page_unless_zero, etc.) in generic code and I don't understand why
> here we need to treat folio_ref_try_add_rcu() specially.
>
> IOW, the assertions here we added:
>
>         VM_BUG_ON(!in_atomic() && !irqs_disabled());
>
> Is because we need atomicity of below sequences:
>
>         VM_BUG_ON_FOLIO(folio_ref_count(folio) == 0, folio);
>         folio_ref_add(folio, count);
>
> But atomic ops avoids it.

Yeah, I didn't think of why atomic can't do it either. But is it
written in this way because we want to catch the refcount == 0 case
since it means a severe bug? Did we miss something?

>
> This chunk of code was (mostly) originally added in 2008 in commit
> e286781d5f2e ("mm: speculative page references").
>
> In short, I'm wondering whether something like below would make sense and
> easier:
>
> ===8<===
> diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
> index 1acf5bac7f50..c89a67d239d1 100644
> --- a/include/linux/page_ref.h
> +++ b/include/linux/page_ref.h
> @@ -258,26 +258,9 @@ static inline bool folio_try_get(struct folio *folio)
>         return folio_ref_add_unless(folio, 1, 0);
>  }
>
> -static inline bool folio_ref_try_add_rcu(struct folio *folio, int count)
> -{
> -#ifdef CONFIG_TINY_RCU
> -       /*
> -        * The caller guarantees the folio will not be freed from interrupt
> -        * context, so (on !SMP) we only need preemption to be disabled
> -        * and TINY_RCU does that for us.
> -        */
> -# ifdef CONFIG_PREEMPT_COUNT
> -       VM_BUG_ON(!in_atomic() && !irqs_disabled());
> -# endif
> -       VM_BUG_ON_FOLIO(folio_ref_count(folio) == 0, folio);
> -       folio_ref_add(folio, count);
> -#else
> -       if (unlikely(!folio_ref_add_unless(folio, count, 0))) {
> -               /* Either the folio has been freed, or will be freed. */
> -               return false;
> -       }
> -#endif
> -       return true;
> +static inline bool folio_ref_try_add(struct folio *folio, int count)
> +{
> +       return folio_ref_add_unless(folio, count, 0);
>  }
>
>  /**
> @@ -305,7 +288,7 @@ static inline bool folio_ref_try_add_rcu(struct folio *folio, int count)
>   */
>  static inline bool folio_try_get_rcu(struct folio *folio)
>  {
> -       return folio_ref_try_add_rcu(folio, 1);
> +       return folio_ref_try_add(folio, 1);
>  }
>
>  static inline int page_ref_freeze(struct page *page, int count)
> diff --git a/mm/gup.c b/mm/gup.c
> index e17466fd62bb..17f89e8d31f1 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -78,7 +78,7 @@ static inline struct folio *try_get_folio(struct page *page, int refs)
>         folio = page_folio(page);
>         if (WARN_ON_ONCE(folio_ref_count(folio) < 0))
>                 return NULL;
> -       if (unlikely(!folio_ref_try_add_rcu(folio, refs)))
> +       if (unlikely(!folio_ref_try_add(folio, refs)))
>                 return NULL;
>
>         /*
> ===8<===
>
> So instead of adding new code, we fix it by removing some.  There might be
> some implication on TINY_RCU / UP config on using the atomic_add_unless()
> to replace one atomic_add(), but I'm not sure whether that's a major issue.
>
> The benefit is try_get_folio() then don't need a renaming then, because the
> rcu implication just went away.
>
> Thanks,
>
> --
> Peter Xu
>


  reply	other threads:[~2024-06-01  0:01 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-31  8:24 kernel test robot
2024-05-31 16:50 ` Yang Shi
     [not found]   ` <890e5a79-8574-4a24-90ab-b9888968d5e5@redhat.com>
2024-05-31 18:07     ` Yang Shi
2024-05-31 18:13       ` Yang Shi
2024-05-31 18:24         ` David Hildenbrand
2024-05-31 18:30           ` Yang Shi
2024-05-31 18:38             ` David Hildenbrand
2024-05-31 19:06               ` Yang Shi
2024-05-31 20:57                 ` Yang Shi
2024-06-03 14:02                   ` Oliver Sang
2024-06-03 16:54                     ` Yang Shi
2024-06-04 23:53                       ` Yang Shi
2024-06-06  2:15                         ` Oliver Sang
2024-06-06  3:44                           ` Yang Shi
2024-06-12  6:01                             ` Oliver Sang
2024-06-25 20:34                               ` Yang Shi
2024-06-25 20:41                                 ` David Hildenbrand
2024-06-25 20:53                                   ` Yang Shi
2024-05-31 23:24     ` Peter Xu
2024-06-01  0:01       ` Yang Shi [this message]
2024-06-01  0:59         ` Yang Shi
     [not found]           ` <0edfcfed-e8c4-4c46-bbce-528c07084792@redhat.com>
2024-06-03 15:08             ` Peter Xu
     [not found]               ` <8da12503-839d-459f-a2fa-4abd6d21935d@redhat.com>
     [not found]                 ` <Zl4m-sAhZknHOHdb@x1n>
2024-06-03 20:37                   ` David Hildenbrand
2024-06-03 20:44                     ` Yang Shi
2024-06-03 21:01                       ` David Hildenbrand
     [not found]                     ` <Zl4vlGJsbHiahYil@x1n>
2024-06-03 21:05                       ` David Hildenbrand
2024-06-03 22:43                         ` Paul E. McKenney
2024-06-04 17:35                           ` Yang Shi

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='CAHbLzkrRw-xf819gYJwRQ=-u971LQYnB2FNJMkN=s6u-pJ4Z8g@mail.gmail.com' \
    --to=shy828301@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=david@redhat.com \
    --cc=jgg@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lkp@intel.com \
    --cc=oe-lkp@lists.linux.dev \
    --cc=oliver.sang@intel.com \
    --cc=peterx@redhat.com \
    --cc=riel@surriel.com \
    --cc=vivek.kasireddy@intel.com \
    --cc=willy@infradead.org \
    /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