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 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.