All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Williams <dan.j.williams@intel.com>
To: linux-fsdevel <linux-fsdevel@vger.kernel.org>
Cc: Jan Kara <jack@suse.cz>, linux-nvdimm <linux-nvdimm@lists.01.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	stable <stable@vger.kernel.org>,
	zwisler@kernel.org
Subject: Re: [PATCH] filesystem-dax: Fix dax_layout_busy_page() livelock
Date: Sat, 6 Oct 2018 23:02:50 -0700	[thread overview]
Message-ID: <CAPcyv4hcF-tbv4OBZ4NAs00PmRAH6mE3nzSpe5=AwNORyHnLWw@mail.gmail.com> (raw)
In-Reply-To: <153884891237.3128209.14619968108312095820.stgit@dwillia2-desk3.amr.corp.intel.com>

On Sat, Oct 6, 2018 at 11:14 AM Dan Williams <dan.j.williams@intel.com> wrote:
>
> In the presence of multi-order entries the typical
> pagevec_lookup_entries() pattern may loop forever:
>
>         while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
>                                 min(end - index, (pgoff_t)PAGEVEC_SIZE),
>                                 indices)) {
>                 ...
>                 for (i = 0; i < pagevec_count(&pvec); i++) {
>                         index = indices[i];
>                         ...
>                 }
>                 index++; /* BUG */
>         }
>
> The loop updates 'index' for each index found and then increments to the
> next possible page to continue the lookup. However, if the last entry in
> the pagevec is multi-order then the next possible page index is more
> than 1 page away. Fix this locally for the filesystem-dax case by
> checking for dax-multi-order entries. Going forward new users of
> multi-order entries need to be similarly careful, or we need a generic
> way to report the page increment in the radix iterator.
>
> Fixes: 5fac7408d828 ("mm, fs, dax: handle layout changes to pinned dax...")
> Cc: <stable@vger.kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Ross Zwisler <zwisler@kernel.org>
> Cc: Matthew Wilcox <willy@infradead.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  fs/dax.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/fs/dax.c b/fs/dax.c
> index 4becbf168b7f..c1472eede1f7 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -666,6 +666,8 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
>         while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
>                                 min(end - index, (pgoff_t)PAGEVEC_SIZE),
>                                 indices)) {
> +               pgoff_t nr_pages = 1;
> +
>                 for (i = 0; i < pagevec_count(&pvec); i++) {
>                         struct page *pvec_ent = pvec.pages[i];
>                         void *entry;
> @@ -680,8 +682,11 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
>
>                         xa_lock_irq(&mapping->i_pages);
>                         entry = get_unlocked_mapping_entry(mapping, index, NULL);
> -                       if (entry)
> +                       if (entry) {
>                                 page = dax_busy_page(entry);
> +                               /* account for multi-order entries */
> +                               nr_pages = 1UL << dax_radix_order(entry);
> +                       }

Thinking about this a bit further the next index will be at least
nr_pages away, but we don't want to accidentally skip over entries as
this patch might do. So nr_pages should only be adjusted by the entry
size if it is the last entry.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

WARNING: multiple messages have this Message-ID (diff)
From: Dan Williams <dan.j.williams@intel.com>
To: linux-fsdevel <linux-fsdevel@vger.kernel.org>
Cc: stable <stable@vger.kernel.org>, Jan Kara <jack@suse.cz>,
	zwisler@kernel.org, Matthew Wilcox <willy@infradead.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-nvdimm <linux-nvdimm@lists.01.org>
Subject: Re: [PATCH] filesystem-dax: Fix dax_layout_busy_page() livelock
Date: Sat, 6 Oct 2018 23:02:50 -0700	[thread overview]
Message-ID: <CAPcyv4hcF-tbv4OBZ4NAs00PmRAH6mE3nzSpe5=AwNORyHnLWw@mail.gmail.com> (raw)
In-Reply-To: <153884891237.3128209.14619968108312095820.stgit@dwillia2-desk3.amr.corp.intel.com>

On Sat, Oct 6, 2018 at 11:14 AM Dan Williams <dan.j.williams@intel.com> wrote:
>
> In the presence of multi-order entries the typical
> pagevec_lookup_entries() pattern may loop forever:
>
>         while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
>                                 min(end - index, (pgoff_t)PAGEVEC_SIZE),
>                                 indices)) {
>                 ...
>                 for (i = 0; i < pagevec_count(&pvec); i++) {
>                         index = indices[i];
>                         ...
>                 }
>                 index++; /* BUG */
>         }
>
> The loop updates 'index' for each index found and then increments to the
> next possible page to continue the lookup. However, if the last entry in
> the pagevec is multi-order then the next possible page index is more
> than 1 page away. Fix this locally for the filesystem-dax case by
> checking for dax-multi-order entries. Going forward new users of
> multi-order entries need to be similarly careful, or we need a generic
> way to report the page increment in the radix iterator.
>
> Fixes: 5fac7408d828 ("mm, fs, dax: handle layout changes to pinned dax...")
> Cc: <stable@vger.kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Ross Zwisler <zwisler@kernel.org>
> Cc: Matthew Wilcox <willy@infradead.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  fs/dax.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/fs/dax.c b/fs/dax.c
> index 4becbf168b7f..c1472eede1f7 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -666,6 +666,8 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
>         while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
>                                 min(end - index, (pgoff_t)PAGEVEC_SIZE),
>                                 indices)) {
> +               pgoff_t nr_pages = 1;
> +
>                 for (i = 0; i < pagevec_count(&pvec); i++) {
>                         struct page *pvec_ent = pvec.pages[i];
>                         void *entry;
> @@ -680,8 +682,11 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
>
>                         xa_lock_irq(&mapping->i_pages);
>                         entry = get_unlocked_mapping_entry(mapping, index, NULL);
> -                       if (entry)
> +                       if (entry) {
>                                 page = dax_busy_page(entry);
> +                               /* account for multi-order entries */
> +                               nr_pages = 1UL << dax_radix_order(entry);
> +                       }

Thinking about this a bit further the next index will be at least
nr_pages away, but we don't want to accidentally skip over entries as
this patch might do. So nr_pages should only be adjusted by the entry
size if it is the last entry.

  reply	other threads:[~2018-10-07  6:03 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-06 18:01 [PATCH] filesystem-dax: Fix dax_layout_busy_page() livelock Dan Williams
2018-10-06 18:01 ` Dan Williams
2018-10-07  6:02 ` Dan Williams [this message]
2018-10-07  6:02   ` Dan Williams

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='CAPcyv4hcF-tbv4OBZ4NAs00PmRAH6mE3nzSpe5=AwNORyHnLWw@mail.gmail.com' \
    --to=dan.j.williams@intel.com \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nvdimm@lists.01.org \
    --cc=stable@vger.kernel.org \
    --cc=willy@infradead.org \
    --cc=zwisler@kernel.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.