[lustre-devel] [PATCH 09/17] staging: lustre: ldlm: use delayed_work for pools_recalc

Dilger, Andreas andreas.dilger at intel.com
Thu Mar 8 11:22:08 PST 2018


On Mar 1, 2018, at 16:31, NeilBrown <neilb at suse.com> wrote:
> 
> ldlm currenty has a kthread which wakes up every so often
> and calls ldlm_pools_recalc().
> The thread is started and stopped, but no other external interactions
> happen.
> 
> This can trivially be replaced by a delayed_work if we have
> ldlm_pools_recalc() reschedule the work rather than just report
> when to do that.
> 
> Signed-off-by: NeilBrown <neilb at suse.com>

Reviewed-by: Andreas Dilger <andreas.dilger at intel.com>

> ---
> drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |   99 +++---------------------
> 1 file changed, 11 insertions(+), 88 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
> index a0e486b57e08..53b8f33e54b5 100644
> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
> @@ -784,9 +784,6 @@ static int ldlm_pool_granted(struct ldlm_pool *pl)
> 	return atomic_read(&pl->pl_granted);
> }
> 
> -static struct ptlrpc_thread *ldlm_pools_thread;
> -static struct completion ldlm_pools_comp;
> -
> /*
>  * count locks from all namespaces (if possible). Returns number of
>  * cached locks.
> @@ -899,8 +896,12 @@ static unsigned long ldlm_pools_cli_scan(struct shrinker *s,
> 			       sc->gfp_mask);
> }
> 
> -static int ldlm_pools_recalc(enum ldlm_side client)
> +static void ldlm_pools_recalc(struct work_struct *ws);
> +static DECLARE_DELAYED_WORK(ldlm_recalc_pools, ldlm_pools_recalc);
> +
> +static void ldlm_pools_recalc(struct work_struct *ws)
> {
> +	enum ldlm_side client = LDLM_NAMESPACE_CLIENT;
> 	struct ldlm_namespace *ns;
> 	struct ldlm_namespace *ns_old = NULL;
> 	/* seconds of sleep if no active namespaces */
> @@ -982,92 +983,19 @@ static int ldlm_pools_recalc(enum ldlm_side client)
> 	/* Wake up the blocking threads from time to time. */
> 	ldlm_bl_thread_wakeup();
> 
> -	return time;
> -}
> -
> -static int ldlm_pools_thread_main(void *arg)
> -{
> -	struct ptlrpc_thread *thread = (struct ptlrpc_thread *)arg;
> -	int c_time;
> -
> -	thread_set_flags(thread, SVC_RUNNING);
> -	wake_up(&thread->t_ctl_waitq);
> -
> -	CDEBUG(D_DLMTRACE, "%s: pool thread starting, process %d\n",
> -	       "ldlm_poold", current_pid());
> -
> -	while (1) {
> -		/*
> -		 * Recal all pools on this tick.
> -		 */
> -		c_time = ldlm_pools_recalc(LDLM_NAMESPACE_CLIENT);
> -
> -		/*
> -		 * Wait until the next check time, or until we're
> -		 * stopped.
> -		 */
> -		wait_event_idle_timeout(thread->t_ctl_waitq,
> -					thread_is_stopping(thread) ||
> -					thread_is_event(thread),
> -					c_time * HZ);
> -
> -		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
> -			break;
> -		thread_test_and_clear_flags(thread, SVC_EVENT);
> -	}
> -
> -	thread_set_flags(thread, SVC_STOPPED);
> -	wake_up(&thread->t_ctl_waitq);
> -
> -	CDEBUG(D_DLMTRACE, "%s: pool thread exiting, process %d\n",
> -	       "ldlm_poold", current_pid());
> -
> -	complete_and_exit(&ldlm_pools_comp, 0);
> +	schedule_delayed_work(&ldlm_recalc_pools, time * HZ);
> }
> 
> static int ldlm_pools_thread_start(void)
> {
> -	struct task_struct *task;
> -
> -	if (ldlm_pools_thread)
> -		return -EALREADY;
> -
> -	ldlm_pools_thread = kzalloc(sizeof(*ldlm_pools_thread), GFP_NOFS);
> -	if (!ldlm_pools_thread)
> -		return -ENOMEM;
> -
> -	init_completion(&ldlm_pools_comp);
> -	init_waitqueue_head(&ldlm_pools_thread->t_ctl_waitq);
> +	schedule_delayed_work(&ldlm_recalc_pools, 0);
> 
> -	task = kthread_run(ldlm_pools_thread_main, ldlm_pools_thread,
> -			   "ldlm_poold");
> -	if (IS_ERR(task)) {
> -		CERROR("Can't start pool thread, error %ld\n", PTR_ERR(task));
> -		kfree(ldlm_pools_thread);
> -		ldlm_pools_thread = NULL;
> -		return PTR_ERR(task);
> -	}
> -	wait_event_idle(ldlm_pools_thread->t_ctl_waitq,
> -			thread_is_running(ldlm_pools_thread));
> 	return 0;
> }
> 
> static void ldlm_pools_thread_stop(void)
> {
> -	if (!ldlm_pools_thread)
> -		return;
> -
> -	thread_set_flags(ldlm_pools_thread, SVC_STOPPING);
> -	wake_up(&ldlm_pools_thread->t_ctl_waitq);
> -
> -	/*
> -	 * Make sure that pools thread is finished before freeing @thread.
> -	 * This fixes possible race and oops due to accessing freed memory
> -	 * in pools thread.
> -	 */
> -	wait_for_completion(&ldlm_pools_comp);
> -	kfree(ldlm_pools_thread);
> -	ldlm_pools_thread = NULL;
> +	cancel_delayed_work_sync(&ldlm_recalc_pools);
> }
> 
> static struct shrinker ldlm_pools_cli_shrinker = {
> @@ -1081,20 +1009,15 @@ int ldlm_pools_init(void)
> 	int rc;
> 
> 	rc = ldlm_pools_thread_start();
> -	if (rc)
> -		return rc;
> -
> -	rc = register_shrinker(&ldlm_pools_cli_shrinker);
> -	if (rc)
> -		ldlm_pools_thread_stop();
> +	if (!rc)
> +		rc = register_shrinker(&ldlm_pools_cli_shrinker);
> 
> 	return rc;
> }
> 
> void ldlm_pools_fini(void)
> {
> -	if (ldlm_pools_thread)
> -		unregister_shrinker(&ldlm_pools_cli_shrinker);
> +	unregister_shrinker(&ldlm_pools_cli_shrinker);
> 
> 	ldlm_pools_thread_stop();
> }
> 
> 

Cheers, Andreas
--
Andreas Dilger
Lustre Principal Architect
Intel Corporation









More information about the lustre-devel mailing list