mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-03-11 04:46:18 +03:00
A deadlock occurs when snapshot expiry tasks are cancelled while holding locks. The snapshot expiry task (snapentry_expire) spawns an umount process and waits for it to complete. Concurrently, ARC memory pressure triggers arc_prune which calls zfs_exit_fs(), attempting to cancel the expiry task while holding locks. The umount process spawned by the expiry task blocks trying to acquire locks held by arc_prune, which is blocked waiting for the expiry task to complete. This creates a circular dependency: expiry task waits for umount, umount waits for arc_prune, arc_prune waits for expiry task. Fix by adding non-blocking cancellation support to taskq_cancel_id(). The zfs_exit_fs() path calls zfsctl_snapshot_unmount_delay() to reschedule the unmount, which needs to cancel any existing expiry task. It now uses non-blocking cancellation to avoid waiting while holding locks, breaking the deadlock by returning immediately when the task is already running. The per-entry se_taskqid_lock has been removed, with all taskqid operations now protected by the global zfs_snapshot_lock held as WRITER. Additionally, an se_in_umount flag prevents recursive waits when zfsctl_destroy() is called during unmount. The taskqid is now only cleared by the caller on successful cancellation; running tasks clear their own taskqid upon completion. Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ameer Hamza <ahamza@ixsystems.com> Closes #17941 |
||
|---|---|---|
| .. | ||
| include | ||
| os | ||
| assert.c | ||
| atomic.c | ||
| backtrace.c | ||
| condvar.c | ||
| cred.c | ||
| getexecname.c | ||
| kmem.c | ||
| kstat.c | ||
| libspl_impl.h | ||
| libspl.c | ||
| list.c | ||
| Makefile.am | ||
| mkdirp.c | ||
| mutex.c | ||
| page.c | ||
| procfs_list.c | ||
| random.c | ||
| rwlock.c | ||
| sid.c | ||
| strlcat.c | ||
| strlcpy.c | ||
| taskq.c | ||
| thread.c | ||
| timestamp.c | ||
| tunables.c | ||