Add the helper, so we can remove the duplicated code for freeing all workers in clearing FD. Acked-by: Dan Schatzberg <schatzberg.dan@xxxxxxxxx> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- drivers/block/loop.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index f63bd75e80ba..4c524c72d976 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1154,16 +1154,14 @@ static void loop_set_timer(struct loop_device *lo) schedule_delayed_work(&lo->idle_work, LOOP_IDLE_WORKER_TIMEOUT); } -static void loop_free_idle_workers(struct work_struct *work) +static void __loop_free_idle_workers(struct loop_device *lo, bool force) { - struct loop_device *lo = container_of(work, struct loop_device, - idle_work.work); struct loop_worker *pos, *worker; spin_lock(&lo->lo_work_lock); list_for_each_entry_safe(worker, pos, &lo->idle_worker_list, idle_list) { - if (time_is_after_jiffies(worker->last_ran_at + + if (!force && time_is_after_jiffies(worker->last_ran_at + LOOP_IDLE_WORKER_TIMEOUT)) break; list_del(&worker->idle_list); @@ -1176,6 +1174,14 @@ static void loop_free_idle_workers(struct work_struct *work) spin_unlock(&lo->lo_work_lock); } +static void loop_free_idle_workers(struct work_struct *work) +{ + struct loop_device *lo = container_of(work, struct loop_device, + idle_work.work); + + __loop_free_idle_workers(lo, false); +} + static int loop_configure(struct loop_device *lo, fmode_t mode, struct block_device *bdev, const struct loop_config *config) @@ -1324,7 +1330,6 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) int err = 0; bool partscan = false; int lo_number; - struct loop_worker *pos, *worker; mutex_lock(&lo->lo_mutex); if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { @@ -1345,15 +1350,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) blk_mq_freeze_queue(lo->lo_queue); destroy_workqueue(lo->workqueue); - spin_lock(&lo->lo_work_lock); - list_for_each_entry_safe(worker, pos, &lo->idle_worker_list, - idle_list) { - list_del(&worker->idle_list); - rb_erase(&worker->rb_node, &lo->worker_tree); - css_put(worker->blkcg_css); - kfree(worker); - } - spin_unlock(&lo->lo_work_lock); + __loop_free_idle_workers(lo, true); cancel_delayed_work_sync(&lo->idle_work); spin_lock_irq(&lo->lo_lock); -- 2.31.1