All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Mike Snitzer" <snitzer@kernel.org>,
	"Matthew Wilcox" <willy@infradead.org>, "Jan Kara" <jack@suse.cz>,
	linux-mm@kvack.org, "Christian Brauner" <brauner@kernel.org>
Cc: "Chuck Lever" <cel@kernel.org>,
	"Jeff Layton" <jlayton@kernel.org>,
	"Anna Schumaker" <anna@kernel.org>
Subject: Re: [PATCH v11 4/7] mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it
Date: Thu, 12 Nov 2026 01:56:48 +0000	[thread overview]
Message-ID: <sashiko-outbox-210121@kernel.org> (raw)
In-Reply-To: <20261111015607.46338-5-snitzer@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] mm: double WB_DONTCACHE_DIRTY accounting in
  folio_mark_dropbehind()
--

commit 99c7597afc26e4465bf2ced6117179f389f8476b
Author: Mike Snitzer <snitzer@kernel.org>

mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it

This commit adds folio_mark_dropbehind() to set PG_dropbehind on a locked
folio and account it in WB_DONTCACHE_DIRTY if the folio is already dirty.

> diff --git a/mm/filemap.c b/mm/filemap.c
> index 98ce955404127..a54d0fbd37222 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -1654,6 +1654,38 @@ void folio_end_dropbehind(struct folio *folio)
>  }
>  EXPORT_SYMBOL_GPL(folio_end_dropbehind);
>  
> +/**
> + * folio_mark_dropbehind - mark an existing folio dropbehind
> + * @folio: the folio, locked by the caller
> + *
> + * Mark @folio so that the writeback that cleans it drops it.  If the folio
> + * is already counted as dirty, which with the i_pages lock held means both
> + * PG_dirty and the dirty tag are set, add it to WB_DONTCACHE_DIRTY so that
> + * the clean that subtracts it leaves the counter balanced.
> + */
> +void folio_mark_dropbehind(struct folio *folio)
> +{
> +	struct address_space *mapping = folio->mapping;
> +	unsigned long flags;
> +
> +	VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
> +
> +	if (folio_test_dropbehind(folio))
> +		return;
> +	if (!mapping || !mapping_can_writeback(mapping)) {
> +		folio_set_dropbehind(folio);
> +		return;
> +	}
> +	xa_lock_irqsave(&mapping->i_pages, flags);
> +	folio_set_dropbehind(folio);
> +	if (folio_test_dirty(folio) &&
> +	    xa_get_mark(&mapping->i_pages, folio->index, PAGECACHE_TAG_DIRTY))
> +		wb_stat_mod(inode_to_wb(mapping->host), WB_DONTCACHE_DIRTY,
> +			    folio_nr_pages(folio));
> +	xa_unlock_irqrestore(&mapping->i_pages, flags);
> +}
> +EXPORT_SYMBOL_GPL(folio_mark_dropbehind);

[Severity: Medium]
Can this double-account WB_DONTCACHE_DIRTY when racing with an unlocked
dirtier on a folio that still has a leftover PAGECACHE_TAG_DIRTY mark?

__folio_cancel_dirty() clears PG_dirty and uncounts the folio without
clearing PAGECACHE_TAG_DIRTY in mapping->i_pages.  Because callers such as
zap_present_folio_ptes() -> folio_mark_dirty() -> filemap_dirty_folio()
dirty mapped folios under the PTE lock without holding the folio lock,
they can set PG_dirty before acquiring mapping->i_pages.xa_lock:

CPU0 (holds folio lock)           CPU1 (holds PTE lock)
__folio_cancel_dirty(folio)
  folio_test_clear_dirty(folio)
  folio_account_cleaned(folio)
  /* PAGECACHE_TAG_DIRTY stays set */
                                  filemap_dirty_folio(mapping, folio)
                                    folio_test_set_dirty(folio)
folio_mark_dropbehind(folio)
  xa_lock_irqsave(&mapping->i_pages)
  folio_set_dropbehind(folio)
  /* PG_dirty && TAG_DIRTY both set */
  wb_stat_mod(..., WB_DONTCACHE_DIRTY, +nr)
  xa_unlock_irqrestore(&mapping->i_pages)
                                    __folio_mark_dirty(folio, mapping, ...)
                                      xa_lock_irqsave(&mapping->i_pages)
                                      folio_account_dirtied(folio, mapping)
                                        if (folio_test_dropbehind(folio))
                                          wb_stat_mod(...,
                                            WB_DONTCACHE_DIRTY, +nr)
                                            <-- counted twice

When the folio is later cleaned, folio_clear_dirty_for_io() or
folio_account_cleaned() only subtracts folio_nr_pages(folio) once,
leaving WB_DONTCACHE_DIRTY permanently inflated and causing
wb_check_start_dontcache() to trigger extra writeback.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261111015607.46338-1-snitzer@kernel.org?part=4


  reply	other threads:[~2026-11-12  1:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  1:56 [PATCH v11 0/7] mm, iomap, NFSD: stop DONTCACHE writes reading back shared pages Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 1/7] mm: move clearing the dropbehind flag of a found folio into a helper Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 2/7] mm: take a folio off WB_DONTCACHE_DIRTY only if it was counted there Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 3/7] mm: expose WB_DONTCACHE_DIRTY in bdi debugfs stats Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 4/7] mm: add folio_mark_dropbehind() to mark a folio dropbehind and account it Mike Snitzer
2026-11-12  1:56   ` sashiko-bot [this message]
2026-11-12 19:00     ` Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 5/7] mm, iomap: keep a partially covered page until a DONTCACHE write completes it Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 6/7] mm, iomap: let a DONTCACHE writer complete its shared pages itself Mike Snitzer
2026-11-11  1:56 ` [PATCH v11 7/7] NFSD: drop a shared boundary page only once both WRITEs have written it Mike Snitzer

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=sashiko-outbox-210121@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anna@kernel.org \
    --cc=brauner@kernel.org \
    --cc=cel@kernel.org \
    --cc=jack@suse.cz \
    --cc=jlayton@kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=snitzer@kernel.org \
    --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.