From: Gao Xiang Date: Fri, 19 Jun 2026 08:34:03 +0000 (+0800) Subject: erofs: simplify RCU read critical sections X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=59397c6b755a35e5a33dbcbe22240cd86ebb935b;p=thirdparty%2Fkernel%2Flinux.git erofs: simplify RCU read critical sections - use scoped_guard() for RCU read critical section in z_erofs_decompress_kickoff(); - simplify the RCU critical section loop in z_erofs_pcluster_begin(). Signed-off-by: Gao Xiang --- diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index c6240dccbb0f..1c65b741b288 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -806,6 +806,7 @@ static int z_erofs_pcluster_begin(struct z_erofs_frontend *fe) struct super_block *sb = fe->inode->i_sb; struct z_erofs_pcluster *pcl = NULL; void *ptr = NULL; + bool needretry; int ret; DBG_BUGON(fe->pcl); @@ -825,19 +826,16 @@ static int z_erofs_pcluster_begin(struct z_erofs_frontend *fe) } ptr = map->buf.page; } else { - while (1) { + do { rcu_read_lock(); pcl = xa_load(&EROFS_SB(sb)->managed_pslots, map->m_pa); - if (!pcl || z_erofs_get_pcluster(pcl)) { - DBG_BUGON(pcl && map->m_pa != pcl->pos); - rcu_read_unlock(); - break; - } + needretry = pcl && !z_erofs_get_pcluster(pcl); rcu_read_unlock(); - } + } while (needretry); } if (pcl) { + DBG_BUGON(map->m_pa != pcl->pos); fe->pcl = pcl; ret = -EEXIST; } else { @@ -1459,21 +1457,19 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io, if (sbi->sync_decompress == EROFS_SYNC_DECOMPRESS_AUTO) sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON; #ifdef CONFIG_EROFS_FS_PCPU_KTHREAD - struct kthread_worker *worker; + scoped_guard(rcu) { + struct kthread_worker *worker; - rcu_read_lock(); - worker = rcu_dereference( + worker = rcu_dereference( z_erofs_pcpu_workers[raw_smp_processor_id()]); - if (!worker) { - INIT_WORK(&io->u.work, z_erofs_decompressqueue_work); - queue_work(z_erofs_workqueue, &io->u.work); - } else { - kthread_queue_work(worker, &io->u.kthread_work); + if (worker) { + kthread_queue_work(worker, &io->u.kthread_work); + return; + } } - rcu_read_unlock(); -#else - queue_work(z_erofs_workqueue, &io->u.work); + INIT_WORK(&io->u.work, z_erofs_decompressqueue_work); #endif + queue_work(z_erofs_workqueue, &io->u.work); return; } gfp_flag = memalloc_noio_save();