Re: [PATCH 1/8] loop: de-duplicate the idle worker freeing code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed 26-01-22 16:50:33, Christoph Hellwig wrote:
> Use a common helper for both timer based and uncoditional freeing of idle
> workers.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Nice cleanup. Feel free to add:

Reviewed-by: Jan Kara <jack@xxxxxxx>

								Honza

> ---
>  drivers/block/loop.c | 73 +++++++++++++++++++++-----------------------
>  1 file changed, 35 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 01cbbfc4e9e24..b268bca6e4fb7 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -804,7 +804,6 @@ struct loop_worker {
>  
>  static void loop_workfn(struct work_struct *work);
>  static void loop_rootcg_workfn(struct work_struct *work);
> -static void loop_free_idle_workers(struct timer_list *timer);
>  
>  #ifdef CONFIG_BLK_CGROUP
>  static inline int queue_on_root_worker(struct cgroup_subsys_state *css)
> @@ -888,6 +887,39 @@ static void loop_queue_work(struct loop_device *lo, struct loop_cmd *cmd)
>  	spin_unlock_irq(&lo->lo_work_lock);
>  }
>  
> +static void loop_set_timer(struct loop_device *lo)
> +{
> +	timer_reduce(&lo->timer, jiffies + LOOP_IDLE_WORKER_TIMEOUT);
> +}
> +
> +static void loop_free_idle_workers(struct loop_device *lo, bool delete_all)
> +{
> +	struct loop_worker *pos, *worker;
> +
> +	spin_lock_irq(&lo->lo_work_lock);
> +	list_for_each_entry_safe(worker, pos, &lo->idle_worker_list,
> +				idle_list) {
> +		if (!delete_all &&
> +		    time_is_after_jiffies(worker->last_ran_at +
> +					  LOOP_IDLE_WORKER_TIMEOUT))
> +			break;
> +		list_del(&worker->idle_list);
> +		rb_erase(&worker->rb_node, &lo->worker_tree);
> +		css_put(worker->blkcg_css);
> +		kfree(worker);
> +	}
> +	if (!list_empty(&lo->idle_worker_list))
> +		loop_set_timer(lo);
> +	spin_unlock_irq(&lo->lo_work_lock);
> +}
> +
> +static void loop_free_idle_workers_timer(struct timer_list *timer)
> +{
> +	struct loop_device *lo = container_of(timer, struct loop_device, timer);
> +
> +	return loop_free_idle_workers(lo, false);
> +}
> +
>  static void loop_update_rotational(struct loop_device *lo)
>  {
>  	struct file *file = lo->lo_backing_file;
> @@ -1022,7 +1054,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
>  	INIT_LIST_HEAD(&lo->rootcg_cmd_list);
>  	INIT_LIST_HEAD(&lo->idle_worker_list);
>  	lo->worker_tree = RB_ROOT;
> -	timer_setup(&lo->timer, loop_free_idle_workers,
> +	timer_setup(&lo->timer, loop_free_idle_workers_timer,
>  		TIMER_DEFERRABLE);
>  	lo->use_dio = lo->lo_flags & LO_FLAGS_DIRECT_IO;
>  	lo->lo_device = bdev;
> @@ -1086,7 +1118,6 @@ static void __loop_clr_fd(struct loop_device *lo)
>  {
>  	struct file *filp;
>  	gfp_t gfp = lo->old_gfp_mask;
> -	struct loop_worker *pos, *worker;
>  
>  	/*
>  	 * Flush loop_configure() and loop_change_fd(). It is acceptable for
> @@ -1116,15 +1147,7 @@ static void __loop_clr_fd(struct loop_device *lo)
>  	blk_mq_freeze_queue(lo->lo_queue);
>  
>  	destroy_workqueue(lo->workqueue);
> -	spin_lock_irq(&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_irq(&lo->lo_work_lock);
> +	loop_free_idle_workers(lo, true);
>  	del_timer_sync(&lo->timer);
>  
>  	spin_lock_irq(&lo->lo_lock);
> @@ -1871,11 +1894,6 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
>  	}
>  }
>  
> -static void loop_set_timer(struct loop_device *lo)
> -{
> -	timer_reduce(&lo->timer, jiffies + LOOP_IDLE_WORKER_TIMEOUT);
> -}
> -
>  static void loop_process_work(struct loop_worker *worker,
>  			struct list_head *cmd_list, struct loop_device *lo)
>  {
> @@ -1924,27 +1942,6 @@ static void loop_rootcg_workfn(struct work_struct *work)
>  	loop_process_work(NULL, &lo->rootcg_cmd_list, lo);
>  }
>  
> -static void loop_free_idle_workers(struct timer_list *timer)
> -{
> -	struct loop_device *lo = container_of(timer, struct loop_device, timer);
> -	struct loop_worker *pos, *worker;
> -
> -	spin_lock_irq(&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 +
> -						LOOP_IDLE_WORKER_TIMEOUT))
> -			break;
> -		list_del(&worker->idle_list);
> -		rb_erase(&worker->rb_node, &lo->worker_tree);
> -		css_put(worker->blkcg_css);
> -		kfree(worker);
> -	}
> -	if (!list_empty(&lo->idle_worker_list))
> -		loop_set_timer(lo);
> -	spin_unlock_irq(&lo->lo_work_lock);
> -}
> -
>  static const struct blk_mq_ops loop_mq_ops = {
>  	.queue_rq       = loop_queue_rq,
>  	.complete	= lo_complete_rq,
> -- 
> 2.30.2
> 
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux