Skip to content

Commit 12bf25d

Browse files
dhavalehsiangkao
authored andcommitted
erofs: lazily initialize per-CPU workers and CPU hotplug hooks
Currently, when EROFS is built with per-CPU workers, the workers are started and CPU hotplug hooks are registered during module initialization. This leads to unnecessary worker start/stop cycles during CPU hotplug events, particularly on Android devices that frequently suspend and resume. This change defers the initialization of per-CPU workers and the registration of CPU hotplug hooks until the first EROFS mount. This ensures that these resources are only allocated and managed when EROFS is actually in use. The tear down of per-CPU workers and unregistration of CPU hotplug hooks still occurs during z_erofs_exit_subsystem(), but only if they were initialized. Signed-off-by: Sandeep Dhavale <[email protected]> Reviewed-by: Gao Xiang <[email protected]> Reviewed-by: Chao Yu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Gao Xiang <[email protected]>
1 parent 4eb56b0 commit 12bf25d

File tree

1 file changed

+50
-20
lines changed

1 file changed

+50
-20
lines changed

fs/erofs/zdata.c

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ static struct workqueue_struct *z_erofs_workqueue __read_mostly;
288288

289289
#ifdef CONFIG_EROFS_FS_PCPU_KTHREAD
290290
static struct kthread_worker __rcu **z_erofs_pcpu_workers;
291+
static atomic_t erofs_percpu_workers_initialized = ATOMIC_INIT(0);
291292

292293
static void erofs_destroy_percpu_workers(void)
293294
{
@@ -333,12 +334,8 @@ static int erofs_init_percpu_workers(void)
333334
}
334335
return 0;
335336
}
336-
#else
337-
static inline void erofs_destroy_percpu_workers(void) {}
338-
static inline int erofs_init_percpu_workers(void) { return 0; }
339-
#endif
340337

341-
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_EROFS_FS_PCPU_KTHREAD)
338+
#ifdef CONFIG_HOTPLUG_CPU
342339
static DEFINE_SPINLOCK(z_erofs_pcpu_worker_lock);
343340
static enum cpuhp_state erofs_cpuhp_state;
344341

@@ -395,15 +392,53 @@ static void erofs_cpu_hotplug_destroy(void)
395392
if (erofs_cpuhp_state)
396393
cpuhp_remove_state_nocalls(erofs_cpuhp_state);
397394
}
398-
#else /* !CONFIG_HOTPLUG_CPU || !CONFIG_EROFS_FS_PCPU_KTHREAD */
395+
#else /* !CONFIG_HOTPLUG_CPU */
399396
static inline int erofs_cpu_hotplug_init(void) { return 0; }
400397
static inline void erofs_cpu_hotplug_destroy(void) {}
401-
#endif
398+
#endif/* CONFIG_HOTPLUG_CPU */
399+
static int z_erofs_init_pcpu_workers(struct super_block *sb)
400+
{
401+
int err;
402402

403-
void z_erofs_exit_subsystem(void)
403+
if (atomic_xchg(&erofs_percpu_workers_initialized, 1))
404+
return 0;
405+
406+
err = erofs_init_percpu_workers();
407+
if (err) {
408+
erofs_err(sb, "per-cpu workers: failed to allocate.");
409+
goto err_init_percpu_workers;
410+
}
411+
412+
err = erofs_cpu_hotplug_init();
413+
if (err < 0) {
414+
erofs_err(sb, "per-cpu workers: failed CPU hotplug init.");
415+
goto err_cpuhp_init;
416+
}
417+
erofs_info(sb, "initialized per-cpu workers successfully.");
418+
return err;
419+
420+
err_cpuhp_init:
421+
erofs_destroy_percpu_workers();
422+
err_init_percpu_workers:
423+
atomic_set(&erofs_percpu_workers_initialized, 0);
424+
return err;
425+
}
426+
427+
static void z_erofs_destroy_pcpu_workers(void)
404428
{
429+
if (!atomic_xchg(&erofs_percpu_workers_initialized, 0))
430+
return;
405431
erofs_cpu_hotplug_destroy();
406432
erofs_destroy_percpu_workers();
433+
}
434+
#else /* !CONFIG_EROFS_FS_PCPU_KTHREAD */
435+
static inline int z_erofs_init_pcpu_workers(struct super_block *sb) { return 0; }
436+
static inline void z_erofs_destroy_pcpu_workers(void) {}
437+
#endif/* CONFIG_EROFS_FS_PCPU_KTHREAD */
438+
439+
void z_erofs_exit_subsystem(void)
440+
{
441+
z_erofs_destroy_pcpu_workers();
407442
destroy_workqueue(z_erofs_workqueue);
408443
z_erofs_destroy_pcluster_pool();
409444
z_erofs_exit_decompressor();
@@ -427,19 +462,8 @@ int __init z_erofs_init_subsystem(void)
427462
goto err_workqueue_init;
428463
}
429464

430-
err = erofs_init_percpu_workers();
431-
if (err)
432-
goto err_pcpu_worker;
433-
434-
err = erofs_cpu_hotplug_init();
435-
if (err < 0)
436-
goto err_cpuhp_init;
437465
return err;
438466

439-
err_cpuhp_init:
440-
erofs_destroy_percpu_workers();
441-
err_pcpu_worker:
442-
destroy_workqueue(z_erofs_workqueue);
443467
err_workqueue_init:
444468
z_erofs_destroy_pcluster_pool();
445469
err_pcluster_pool:
@@ -641,8 +665,14 @@ static const struct address_space_operations z_erofs_cache_aops = {
641665

642666
int z_erofs_init_super(struct super_block *sb)
643667
{
644-
struct inode *const inode = new_inode(sb);
668+
struct inode *inode;
669+
int err;
670+
671+
err = z_erofs_init_pcpu_workers(sb);
672+
if (err)
673+
return err;
645674

675+
inode = new_inode(sb);
646676
if (!inode)
647677
return -ENOMEM;
648678
set_nlink(inode, 1);

0 commit comments

Comments
 (0)