mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
fs: quota: create dedicated workqueue for quota_release_work
[ Upstream commit 72b7ceca857f38a8ca7c5629feffc63769638974 ]
There is a kernel panic due to WARN_ONCE when panic_on_warn is set.
This issue occurs when writeback is triggered due to sync call for an
opened file(ie, writeback reason is WB_REASON_SYNC). When f2fs balance
is needed at sync path, flush for quota_release_work is triggered.
By default quota_release_work is queued to "events_unbound" queue which
does not have WQ_MEM_RECLAIM flag. During f2fs balance "writeback"
workqueue tries to flush quota_release_work causing kernel panic due to
MEM_RECLAIM flag mismatch errors.
This patch creates dedicated workqueue with WQ_MEM_RECLAIM flag
for work quota_release_work.
------------[ cut here ]------------
WARNING: CPU: 4 PID: 14867 at kernel/workqueue.c:3721 check_flush_dependency+0x13c/0x148
Call trace:
check_flush_dependency+0x13c/0x148
__flush_work+0xd0/0x398
flush_delayed_work+0x44/0x5c
dquot_writeback_dquots+0x54/0x318
f2fs_do_quota_sync+0xb8/0x1a8
f2fs_write_checkpoint+0x3cc/0x99c
f2fs_gc+0x190/0x750
f2fs_balance_fs+0x110/0x168
f2fs_write_single_data_page+0x474/0x7dc
f2fs_write_data_pages+0x7d0/0xd0c
do_writepages+0xe0/0x2f4
__writeback_single_inode+0x44/0x4ac
writeback_sb_inodes+0x30c/0x538
wb_writeback+0xf4/0x440
wb_workfn+0x128/0x5d4
process_scheduled_works+0x1c4/0x45c
worker_thread+0x32c/0x3e8
kthread+0x11c/0x1b0
ret_from_fork+0x10/0x20
Kernel panic - not syncing: kernel: panic_on_warn set ...
Fixes: ac6f420291b3 ("quota: flush quota_release_work upon quota writeback")
CC: stable@vger.kernel.org
Signed-off-by: Shashank A P <shashank.ap@samsung.com>
Link: https://patch.msgid.link/20250901092905.2115-1-shashank.ap@samsung.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d7d942c9a1
commit
f846eacde2
@@ -163,6 +163,9 @@ static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
|
||||
/* SLAB cache for dquot structures */
|
||||
static struct kmem_cache *dquot_cachep;
|
||||
|
||||
/* workqueue for work quota_release_work*/
|
||||
static struct workqueue_struct *quota_unbound_wq;
|
||||
|
||||
void register_quota_format(struct quota_format_type *fmt)
|
||||
{
|
||||
spin_lock(&dq_list_lock);
|
||||
@@ -891,7 +894,7 @@ void dqput(struct dquot *dquot)
|
||||
put_releasing_dquots(dquot);
|
||||
atomic_dec(&dquot->dq_count);
|
||||
spin_unlock(&dq_list_lock);
|
||||
queue_delayed_work(system_unbound_wq, "a_release_work, 1);
|
||||
queue_delayed_work(quota_unbound_wq, "a_release_work, 1);
|
||||
}
|
||||
EXPORT_SYMBOL(dqput);
|
||||
|
||||
@@ -3046,6 +3049,11 @@ static int __init dquot_init(void)
|
||||
if (register_shrinker(&dqcache_shrinker, "dquota-cache"))
|
||||
panic("Cannot register dquot shrinker");
|
||||
|
||||
quota_unbound_wq = alloc_workqueue("quota_events_unbound",
|
||||
WQ_UNBOUND | WQ_MEM_RECLAIM, WQ_MAX_ACTIVE);
|
||||
if (!quota_unbound_wq)
|
||||
panic("Cannot create quota_unbound_wq\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(dquot_init);
|
||||
|
||||
Reference in New Issue
Block a user