public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arjan van de Ven <arjan@linux.intel.com>
To: linux-mm@kvack.org
Cc: syzbot+9722a25de70a85ff48a1@syzkaller.appspotmail.com,
	akpm@linux-foundation.org, baolin.wang@linux.alibaba.com,
	hughd@google.com, linux-kernel@vger.kernel.org,
	syzkaller-bugs@googlegroups.com
Subject: Re: [syzbot] [mm?] BUG: sleeping function called from invalid context in shmem_undo_range
Date: Thu, 23 Apr 2026 19:34:54 -0700	[thread overview]
Message-ID: <20260424023524.322251-1-arjan@linux.intel.com> (raw)
In-Reply-To: <69eab803.a00a0220.17a17.004b.GAE@google.com>

This email is created by automation to help kernel developers
deal with a large volume of AI generated bug reports by decoding
oopses into more actionable information.


Decoded Backtrace

shmem_undo_range (mm/shmem.c:1108-1151) -- crash site
------------------------------------------------------
1108 static void shmem_undo_range(struct inode *inode, loff_t lstart,
1109                               uoff_t lend, bool unfalloc)
1110 {
1111     struct address_space *mapping = inode->i_mapping;
1112     struct shmem_inode_info *info = SHMEM_I(inode);
1113     pgoff_t start = (lstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
1114     pgoff_t end = (lend + 1) >> PAGE_SHIFT;
1115     struct folio_batch fbatch;
1116     pgoff_t indices[FOLIO_BATCH_SIZE];
1117     struct folio *folio;
1118     bool same_folio;
1119     long nr_swaps_freed = 0;
1120     pgoff_t index;
1121     int i;
...
1129     folio_batch_init(&fbatch);
1130     index = start;
1131     while (index < end && find_lock_entries(mapping, &index,
1132             end - 1, &fbatch, indices)) {
1133         for (i = 0; i < folio_batch_count(&fbatch); i++) {
1134             folio = fbatch.folios[i];
1135             if (xa_is_value(folio)) {
...
1143             }
1144             if (!unfalloc || !folio_test_uptodate(folio))
1145                 truncate_inode_folio(mapping, folio);
1146             folio_unlock(folio);
1147         }
1148         folio_batch_remove_exceptionals(&fbatch);
1149         folio_batch_release(&fbatch);
1150         cond_resched();   /* <-- BUG fires here; RCU nest depth=1 */
1151     }

filename_unlinkat (fs/namei.c:5526-5587) -- top-level caller
-------------------------------------------------------------
5526 int filename_unlinkat(int dfd, struct filename *name)
5527 {
...
5545     error = mnt_want_write(path.mnt);  /* lock #0 (sb_writers) */
5546     if (error)
5547         goto exit_path_put;
5548 retry_deleg:
5549     dentry = start_dirop(path.dentry, &last, lookup_flags);
...
5563     inode = dentry->d_inode;
5564     ihold(inode);
5565     error = security_path_unlink(&path, dentry);
5566     if (error)
5567         goto exit_end_dirop;
5568     error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode,
5569                        dentry, &delegated_inode);
5570 exit_end_dirop:
5571     end_dirop(dentry);
5572     iput(inode);   /* triggers shmem_evict_inode -> shmem_undo_range */
...
5579     mnt_drop_write(path.mnt);
...
5587 }


Tentative Analysis

The crash is triggered by running rm(1) on a tmpfs/shmem file. The call
chain is:

  sys_unlink -> filename_unlinkat -> iput -> iput_final -> evict
    -> shmem_evict_inode -> shmem_truncate_range -> shmem_undo_range
    -> cond_resched()   <-- BUG fires here

At crash time, two locks are held (in acquisition order):

  #0 sb_writers#5  --  acquired at filename_unlinkat+0x1ad
                       (fs/namei.c:5545 -- mnt_want_write)
  #1 rcu_read_lock --  acquired at rcu_lock_acquire.constprop.0
                       (include/linux/rcupdate.h:300)

Lock #1 (rcu_read_lock) was acquired AFTER mnt_want_write (lock #0 is
always recorded first in the lockdep list) and before the iput() call
at line 5572.  That window contains start_dirop(), security_path_unlink()
and vfs_unlink() (which calls fsnotify_unlink() and d_delete_notify() on
the success path).

On a PREEMPT(full) kernel, rcu_read_lock() increments
current->rcu_read_lock_nesting instead of disabling preemption.
cond_resched() -> __cond_resched() -> __might_resched() checks that
counter, finds it is 1 (not 0), and fires the BUG.

The same leaked rcu_read_lock persists all the way back to userspace
("lock held when returning to user space!"), and a timer interrupt
firing during the syscall produces a third warning:
"Voluntary context switch within RCU read-side critical section!"

All three messages are symptoms of a single rcu_read_lock() call that
is never matched by an rcu_read_unlock() somewhere between
mnt_want_write and iput in filename_unlinkat.


Potential Solution

Find the rcu_read_lock() call that is missing its matching
rcu_read_unlock() in the vfs_unlink() / fsnotify_unlink() /
d_delete_notify() code path.  Adding a WARN_ON(rcu_read_lock_held())
to iput() (alongside the existing might_sleep() check) should produce
a backtrace pointing at the exact acquisition site on the next
reproduction.


More information

Oops-Analysis: http://oops.fenrus.org/reports/lkml/69eab803.a00a0220.17a17.004b.GAE_google.com/report.html
Assisted-by: GitHub Copilot:claude-sonnet-4.6 linux-kernel-oops-x86.

  reply	other threads:[~2026-04-24  2:34 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-24  0:23 [syzbot] [mm?] BUG: sleeping function called from invalid context in shmem_undo_range syzbot
2026-04-24  2:34 ` Arjan van de Ven [this message]
2026-04-24 10:42   ` Andrew Morton

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=20260424023524.322251-1-arjan@linux.intel.com \
    --to=arjan@linux.intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=syzbot+9722a25de70a85ff48a1@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    /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