Linux Btrfs filesystem development
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: Christian Borntraeger <borntraeger@linux.ibm.com>,
	Chris Mason <clm@fb.com>, David Sterba <dsterba@suse.com>,
	Qu Wenruo <wqu@suse.com>
Cc: linux-btrfs@vger.kernel.org,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: Lockdep circular dependency: btrfs_swap_activate() calls sysfs_notify()
Date: Fri, 31 Jul 2026 20:42:07 +0930	[thread overview]
Message-ID: <11be35c2-7ede-4c83-b21f-39e52c3b04a2@gmx.com> (raw)
In-Reply-To: <782c4d5c-d93b-42b3-b4ca-58deb3d8a894@linux.ibm.com>



在 2026/7/31 20:27, Christian Borntraeger 写道:
> One or more of the following files ( btrfs-swapon-kernfs-repro.sh ) 
> violates IBM policy and all attachment(s) have been removed from the 
> message.

If the bash script, as an attachment, violates the policy, can you just 
paste the content as a reply?

As I still have some uncertainty on the LLM explanation.
A concrete reproducer would allow us to do our own experiments and get 
everything more clear.

Otherwise really appreciated all your reports, no matter if it's 
generated by LLM or not, as so far your reports are 100% real bugs.

Thanks,
Qu

> 
> **********************************************************************
> We had the calltrace at the bottom of this mail in our CI logs
> I also attached an AI generated reproducer that triggers this easily.
> 
> For convenience, here is what AI came up with analysing the log, but
> I would like your take on it. Let me know if you want to see the
> AI proposed fix.
> 
> ----
> 
> btrfs_swap_activate() takes the inode's i_mmap_lock for write very
> early (inode.c:10120) and holds it across the entire function; the
> comment there explains the intent, which is to keep mmap writes from
> racing with the delalloc flush and the extent range lock.
> 
> There are three btrfs_exclop_finish() calls inside that window:
> 
>    fs/btrfs/inode.c:10181   error path, swapfile on a rw subvolume
>                             with an active snapshot
>    fs/btrfs/inode.c:10202   error path, could not lock the snapshot drew
>                             lock
>    fs/btrfs/inode.c:10399   the common "out:" path -- taken on both
>                             success and failure
> 
> and btrfs_exclop_finish() (fs/btrfs/fs.c:224) ends with an unconditional
> sysfs_notify().  So the offending edge is taken on *every* successful
> swapon of a btrfs swap file, not only on an error path.
> 
> The sysfs_notify() itself does nothing but a kernfs lookup plus a poll
> wakeup for userspace watching the "exclusive_operation" attribute.  It
> has no dependency whatsoever on i_mmap_lock, or on the inode at all.
> 
> 
> Both kernfs_rwsem acquisitions in the cycle are read acquisitions
> ({++++}), so the two of them alone cannot deadlock.  A real hang needs a
> third task waiting to take kernfs_rwsem for write, because rwsem
> write-fairness makes a later down_read() block behind a queued writer:
> 
>    T_swapon:  holds i_mmap_lock(write)
>               blocks in down_read(kernfs_rwsem)   [queued behind T_w]
>    T_w:       blocks in down_write(kernfs_rwsem)  [waiting for T_dir]
>               e.g. any sysfs node create/remove -- device hotplug,
>               module load, cgroup or block-device attribute changes
>    T_dir:     holds kernfs_rwsem(read) in kernfs_fop_readdir
>               faults on the user dirent buffer -> mmap_lock
>               -> btrfs_page_mkwrite -> down_read(i_mmap_lock)
>               blocks behind T_swapon's write holder
> 
>    -> three-way deadlock.
> 
> That is a narrow race, which is consistent with this having gone
> unnoticed for years, but every step of it is ordinary system activity.
> The dependency is genuine and worth fixing rather than annotating away.
> 
> Suggested fix is to get the sysfs_notify() out from under i_mmap_lock
> 
> 
> real life log found in our CI:
> ----------------------------
> LOCKDEP_CIRCULAR (suite: tela-distro, case: tests/test_mempig/test_mempig)
> WARNING: possible circular locking dependency detected
> 7.2.0-20260730.rc5.git10.af7a8a7752eb.300.fc44.s390x+debug #1 Not tainted
> ------------------------------------------------------
> swapon/172010 is trying to acquire lock:
> 000002ea80a485a0 (&root->kernfs_rwsem){++++}-{3:3}, at: 
> kernfs_find_and_get_ns+0x3c/0x80
> but task is already holding lock:
> 000002ebc465d270 (&ei->i_mmap_lock){++++}-{3:3}, at: 
> btrfs_swap_activate+0x9a/0x1240
> which lock already depends on the new lock.
> the existing dependency chain (in reverse order) is:
> -> #3 (&ei->i_mmap_lock){++++}-{3:3}:
>         lock_acquire+0x150/0x3f0
>         down_read+0x5a/0x280
>         btrfs_page_mkwrite+0x258/0x870
>         do_page_mkwrite+0x60/0x160
>         do_wp_page+0x128/0x750
>         __handle_mm_fault+0x1be/0x590
>         handle_mm_fault+0xa2/0x370
>         do_exception+0x292/0x590
>         __do_pgm_check+0x168/0x430
>         pgm_check_handler+0x114/0x160
> -> #2 (sb_pagefaults){.+.+}-{0:0}:
>         lock_acquire+0x150/0x3f0
>         percpu_down_read_internal.constprop.0+0x54/0x120
>         btrfs_page_mkwrite+0xa6/0x870
>         do_page_mkwrite+0x60/0x160
>         do_fault+0x132/0x4a0
>         __handle_mm_fault+0x1be/0x590
>         handle_mm_fault+0xa2/0x370
>         do_exception+0x1a0/0x590
>         __do_pgm_check+0x168/0x430
>         pgm_check_handler+0x114/0x160
> -> #1 (&mm->mmap_lock){++++}-{3:3}:
>         lock_acquire+0x150/0x3f0
>         __might_fault+0x7a/0xa0
>         filldir64+0x11c/0x210
>         kernfs_fop_readdir+0x150/0x4c0
>         iterate_dir+0xcc/0x2d0
>         __do_sys_getdents64+0x7a/0x130
>         __do_syscall+0x172/0x750
>         system_call+0x72/0x90
> -> #0 (&root->kernfs_rwsem){++++}-{3:3}:
>         check_prev_add+0x160/0xf40
>         __lock_acquire+0x12aa/0x15a0
>         lock_acquire+0x150/0x3f0
>         down_read+0x5a/0x280
>         kernfs_find_and_get_ns+0x3c/0x80
>         sysfs_notify+0x60/0xc0
>         btrfs_swap_activate+0x83c/0x1240
>         __do_sys_swapon+0x278/0x9c0
>         __do_syscall+0x172/0x750
>         system_call+0x72/0x90
> other info that might help us debug this:
> Chain exists of:
>    &root->kernfs_rwsem --> sb_pagefaults --> &ei->i_mmap_lock
>   Possible unsafe locking scenario:
>         CPU0                    CPU1
>         ----                    ----
>    lock(&ei->i_mmap_lock);
>                                 lock(sb_pagefaults);
>                                 lock(&ei->i_mmap_lock);
>    rlock(&root->kernfs_rwsem);
>   *** DEADLOCK ***
> 2 locks held by swapon/172010:
>   #0: 000002ebc465d3f0 (&sb->s_type->i_mutex_key#20){++++}-{3:3}, at: 
> __do_sys_swapon+0x5be/0x9c0
>   #1: 000002ebc465d270 (&ei->i_mmap_lock){++++}-{3:3}, at: 
> btrfs_swap_activate+0x9a/0x1240
> stack backtrace:
> CPU: 6 UID: 0 PID: 172010 Comm: swapon Not tainted 
> 7.2.0-20260730.rc5.git10.af7a8a7752eb.300.fc44.s390x+debug #1 PREEMPT
> Hardware name: IBM 8561 T01 701 (z/VM 7.4.0)
> Call Trace:
>   [<000003f7d5ab4e3e>] dump_stack_lvl+0xae/0x108
>   [<000003f7d5bbef24>] print_circular_bug+0x1a4/0x230
>   [<000003f7d5bbf13c>] check_noncircular+0x18c/0x1b0
>   [<000003f7d5bc0510>] check_prev_add+0x160/0xf40
>   [<000003f7d5bc408a>] __lock_acquire+0x12aa/0x15a0
>   [<000003f7d5bc44d0>] lock_acquire+0x150/0x3f0
>   [<000003f7d6c447ca>] down_read+0x5a/0x280
>   [<000003f7d60ad61c>] kernfs_find_and_get_ns+0x3c/0x80
>   [<000003f7d60b3b70>] sysfs_notify+0x60/0xc0
>   [<000003f7d635653c>] btrfs_swap_activate+0x83c/0x1240
>   [<000003f7d5f1d268>] __do_sys_swapon+0x278/0x9c0
>   [<000003f7d6c369a2>] __do_syscall+0x172/0x750
>   [<000003f7d6c4baa2>] system_call+0x72/0x90
> INFO: lockdep is turned off.


  reply	other threads:[~2026-07-31 11:12 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 10:57 Lockdep circular dependency: btrfs_swap_activate() calls sysfs_notify() Christian Borntraeger
2026-07-31 11:12 ` Qu Wenruo [this message]
2026-07-31 11:14   ` Christian Borntraeger
2026-08-03  9:07     ` Christian Borntraeger
2026-08-03  9:44       ` Qu Wenruo

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=11be35c2-7ede-4c83-b21f-39e52c3b04a2@gmx.com \
    --to=quwenruo.btrfs@gmx.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=clm@fb.com \
    --cc=dsterba@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=wqu@suse.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