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.
next prev parent 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