[merged mm-stable] mm-shmem-downgrade-final-i_blocks-check-in-shmem_evict_inode-to-pr_warn.patch removed from -mm tree
Andrew Morton <[email protected]>
| Newsgroups | org.kernel.vger.mm-commits |
|---|---|
| Message-ID | <[email protected]> |
The quilt patch titled
Subject: mm/shmem: downgrade final i_blocks check in shmem_evict_inode() to pr_warn()
has been removed from the -mm tree. Its filename was
mm-shmem-downgrade-final-i_blocks-check-in-shmem_evict_inode-to-pr_warn.patch
This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Jiacheng Yu <[email protected]>
Subject: mm/shmem: downgrade final i_blocks check in shmem_evict_inode() to pr_warn()
Date: Tue, 28 Jul 2026 09:10:14 +0000
shmem_evict_inode() ends with WARN_ON(inode->i_blocks) as a final
consistency check of shmem's block accounting. When it fires, the
inode-local counters die with the inode; what may linger is a small
residue in accounting kept outside the inode, such as per-mount or
per-user charges. No data is lost, and no corruption follows.
On kernels running with panic_on_warn=1, this accounting inconsistency
escalates to a full machine panic, which is disproportionate to the
impact.
Downgrade the WARN_ON() to a pr_warn() that reports the inode together
with its accounting counters (i_blocks, alloced, swapped, nrpages),
keeping the inconsistency visible in the logs.
The accounting bugs this check has caught over the years -- the swapout
race described in commit 0f3c42f522dc ("tmpfs: change final i_blocks BUG
to WARNING") and the error recovery race fixed in commit 267a4c76bbdb
("tmpfs: fix shmem_evict_inode() warnings on i_blocks") -- are real and
should still be fixed; this change only removes the disproportionate
escalation.
One way to hit this race: soft_offline_in_use_page()'s fast path drops a
clean, unmapped shmem folio via mapping_evict_folio(), where the
xas_store() and the nrpages decrement are not atomic against a concurrent
shmem_evict_inode(); the final shmem_recalc_inode() can then read the
pre-decrement nrpages, compute freed = 0, and leave one page charged.
Same class as the races in 0f3c42f522dc and 267a4c76bbdb, this time in the
under-count direction; reproduced on 7.2-rc4 with
madvise(MADV_SOFT_OFFLINE) racing MAP_FIXED replacement of a
shared-anonymous VMA.
[[email protected]: drop redundant casts in shmem_evict_inode() pr_warn]
Link: https://lore.kernel.org/[email protected]
Link: https://lore.kernel.org/[email protected]
Fixes: 0f3c42f522dc ("tmpfs: change final i_blocks BUG to WARNING")
Signed-off-by: Jiacheng Yu <[email protected]>
Cc: Baolin Wang <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Yongqiang Liu <[email protected]>
Cc: Christian Brauner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---
mm/shmem.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/mm/shmem.c~mm-shmem-downgrade-final-i_blocks-check-in-shmem_evict_inode-to-pr_warn
+++ a/mm/shmem.c
@@ -1440,7 +1440,10 @@ static void shmem_evict_inode(struct ino
simple_xattrs_free(&sbinfo->xa_cache, &info->xattrs, sbinfo->max_inodes ? &freed : NULL);
shmem_free_inode(inode->i_sb, freed);
- WARN_ON(inode->i_blocks);
+ if (inode->i_blocks)
+ pr_warn("%s: ino=%llu i_blocks=%llu alloced=%lu swapped=%lu nrpages=%lu\n",
+ __func__, inode->i_ino, inode->i_blocks,
+ info->alloced, info->swapped, inode->i_mapping->nrpages);
clear_inode(inode);
#ifdef CONFIG_TMPFS_QUOTA
dquot_free_inode(inode);
_
Patches currently in -mm which might be from [email protected] are