From: Alistair Popple <apopple@nvidia.com>
To: <akpm@linux-foundation.org>, David Hildenbrand <david@redhat.com>
Cc: <willy@infradead.org>, <dhowells@redhat.com>, <hughd@google.com>,
<linux-kernel@vger.kernel.org>, <linux-mm@kvack.org>,
<jglisse@redhat.com>, <jgg@nvidia.com>, <rcampbell@nvidia.com>,
<jhubbard@nvidia.com>
Subject: Re: [PATCH v4] mm/migrate.c: Rework migration_entry_wait() to not take a pageref
Date: Tue, 23 Nov 2021 10:28:54 +1100 [thread overview]
Message-ID: <2895271.4lBpGFk6aU@nvdebian> (raw)
In-Reply-To: <d2697d9e-92b7-649f-5afa-313350578286@redhat.com>
On Tuesday, 23 November 2021 5:15:27 AM AEDT David Hildenbrand wrote:
[...]
> > +#ifdef CONFIG_MIGRATION
> > +/**
> > + * migration_entry_wait_on_locked - Wait for a migration entry to be removed
> > + * @folio: folio referenced by the migration entry.
> > + * @ptep: mapped pte pointer. This function will return with the ptep unmapped.
> > + * @ptl: already locked ptl. This function will drop the lock.
> > + *
> > + * Wait for a migration entry referencing the given page to be removed. This is
> > + * equivalent to put_and_wait_on_page_locked(page, TASK_UNINTERRUPTIBLE) except
> > + * this can be called without taking a reference on the page. Instead this
> > + * should be called while holding the ptl for the migration entry referencing
> > + * the page.
> > + *
> > + * Returns after unmapping and unlocking the pte/ptl with pte_unmap_unlock().
>
> You could maybe make it clear that callers have to pass the ptep only
> for PTE migration entries. For a PMD migration entry, pass NULL.
Will do.
> > + *
> > + * This follows the same logic as wait_on_page_bit_common() so see the comments
>
> s/wait_on_page_bit_common/folio_wait_bit_common/ ?
Evidently this escaped my s// when rebasing on top of folio's. Will fix.
> > + * there.
> > + */
> > +void migration_entry_wait_on_locked(struct folio *folio, pte_t *ptep,
> > + spinlock_t *ptl)
> > +{
> > + struct wait_page_queue wait_page;
> > + wait_queue_entry_t *wait = &wait_page.wait;
> > + bool thrashing = false;
> > + bool delayacct = false;
> > + unsigned long pflags;
> > + wait_queue_head_t *q;
> > +
> > + q = folio_waitqueue(folio);
> > + if (!folio_test_uptodate(folio) && folio_test_workingset(folio)) {
> > + if (!folio_test_swapbacked(folio)) {
> > + delayacct_thrashing_start();
> > + delayacct = true;
> > + }
> > + psi_memstall_enter(&pflags);
> > + thrashing = true;
> > + }
> > +
> > + init_wait(wait);
> > + wait->func = wake_page_function;
> > + wait_page.folio = folio;
> > + wait_page.bit_nr = PG_locked;
> > + wait->flags = 0;
> > +
> > + spin_lock_irq(&q->lock);
> > + folio_set_waiters(folio);
> > + if (!folio_trylock_flag(folio, PG_locked, wait))
> > + __add_wait_queue_entry_tail(q, wait);
> > + spin_unlock_irq(&q->lock);
> > +
> > + /*
> > + * If a migration entry exists for the page the migration path must hold
> > + * a valid reference to the page, and it must take the ptl to remove the
> > + * migration entry. So the page is valid until the ptl is dropped.
> > + */
> > + if (ptep)
> > + pte_unmap_unlock(ptep, ptl);
> > + else
> > + spin_unlock(ptl);
> > +
> > + for (;;) {
> > + unsigned int flags;
> > +
> > + set_current_state(TASK_UNINTERRUPTIBLE);
> > +
> > + /* Loop until we've been woken or interrupted */
> > + flags = smp_load_acquire(&wait->flags);
> > + if (!(flags & WQ_FLAG_WOKEN)) {
> > + if (signal_pending_state(TASK_UNINTERRUPTIBLE, current))
> > + break;
> > +
> > + io_schedule();
> > + continue;
> > + }
> > + break;
> > + }
> > +
> > + finish_wait(q, wait);
> > +
> > + if (thrashing) {
> > + if (delayacct)
> > + delayacct_thrashing_end();
> > + psi_memstall_leave(&pflags);
> > + }
> > +}
> > +#endif
> > +
>
> I'm fairly new to the glory details of core migration entry and page bit
> waiting code, but it makes sense to me and removing the temporary extra
> references is very nice! Feel free to add my
>
> Acked-by: David Hildenbrand <david@redhat.com>
Thanks for taking a look, really appreciate it!
- Alistair
prev parent reply other threads:[~2021-11-22 23:29 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-18 2:07 [PATCH v4] mm/migrate.c: Rework migration_entry_wait() to not take a pageref Alistair Popple
2021-11-22 18:15 ` David Hildenbrand
2021-11-22 23:28 ` Alistair Popple [this message]
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=2895271.4lBpGFk6aU@nvdebian \
--to=apopple@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=david@redhat.com \
--cc=dhowells@redhat.com \
--cc=hughd@google.com \
--cc=jgg@nvidia.com \
--cc=jglisse@redhat.com \
--cc=jhubbard@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=rcampbell@nvidia.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.