Skip to content

Commit 72b7cec

Browse files
Shashank A Pjankara
authored andcommitted
fs: quota: create dedicated workqueue for quota_release_work
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: ac6f420 ("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>
1 parent fab1bed commit 72b7cec

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

fs/quota/dquot.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
162162
/* SLAB cache for dquot structures */
163163
static struct kmem_cache *dquot_cachep;
164164

165+
/* workqueue for work quota_release_work*/
166+
static struct workqueue_struct *quota_unbound_wq;
167+
165168
void register_quota_format(struct quota_format_type *fmt)
166169
{
167170
spin_lock(&dq_list_lock);
@@ -881,7 +884,7 @@ void dqput(struct dquot *dquot)
881884
put_releasing_dquots(dquot);
882885
atomic_dec(&dquot->dq_count);
883886
spin_unlock(&dq_list_lock);
884-
queue_delayed_work(system_unbound_wq, &quota_release_work, 1);
887+
queue_delayed_work(quota_unbound_wq, &quota_release_work, 1);
885888
}
886889
EXPORT_SYMBOL(dqput);
887890

@@ -3041,6 +3044,11 @@ static int __init dquot_init(void)
30413044

30423045
shrinker_register(dqcache_shrinker);
30433046

3047+
quota_unbound_wq = alloc_workqueue("quota_events_unbound",
3048+
WQ_UNBOUND | WQ_MEM_RECLAIM, WQ_MAX_ACTIVE);
3049+
if (!quota_unbound_wq)
3050+
panic("Cannot create quota_unbound_wq\n");
3051+
30443052
return 0;
30453053
}
30463054
fs_initcall(dquot_init);

0 commit comments

Comments
 (0)