lkml.org 
[lkml]   [2018]   [Mar]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH 09/17] staging: lustre: ldlm: use delayed_work for pools_recalc
    Date
    On Mar 1, 2018, at 16:31, NeilBrown <neilb@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@suse.com>

    Reviewed-by: Andreas Dilger <andreas.dilger@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







    \
     
     \ /
      Last update: 2018-03-08 20:23    [W:5.087 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site