From 3f594a55c7ff91d55e707f0ae774856261cd1842 Mon Sep 17 00:00:00 2001 From: yury Date: Wed, 4 Jun 2008 11:11:52 +0000 Subject: [PATCH] b=15440 r=shadow,nikita - fixes missed CFS_INIT_LIST_HEAD(&ns->ns_list_chain); in ldlm_namespace_new(); - cleanups about names and ns list work; - remove ns from list before waiting to refc == 0. --- lustre/include/lustre_dlm.h | 10 ++++--- lustre/ldlm/ldlm_pool.c | 12 ++++----- lustre/ldlm/ldlm_resource.c | 65 ++++++++++++++++++++++++++++++--------------- 3 files changed, 56 insertions(+), 31 deletions(-) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index 70a0733..e8a3bbf 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -698,12 +698,14 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client, int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags); void ldlm_namespace_free(struct ldlm_namespace *ns, struct obd_import *imp, int force); -void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client); -struct ldlm_namespace *ldlm_namespace_first(ldlm_side_t client); +void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client); +void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client); +void ldlm_namespace_move_locked(struct ldlm_namespace *ns, ldlm_side_t client); +struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t client); +void ldlm_namespace_get_locked(struct ldlm_namespace *ns); +void ldlm_namespace_put_locked(struct ldlm_namespace *ns, int wakeup); void ldlm_namespace_get(struct ldlm_namespace *ns); void ldlm_namespace_put(struct ldlm_namespace *ns, int wakeup); -void ldlm_namespace_get_nolock(struct ldlm_namespace *ns); -void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup); int ldlm_proc_setup(void); #ifdef LPROCFS void ldlm_proc_cleanup(void); diff --git a/lustre/ldlm/ldlm_pool.c b/lustre/ldlm/ldlm_pool.c index dcae254..fbcf055 100644 --- a/lustre/ldlm/ldlm_pool.c +++ b/lustre/ldlm/ldlm_pool.c @@ -783,9 +783,9 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, mutex_up(ldlm_namespace_lock(client)); return 0; } - ns = ldlm_namespace_first(client); + ns = ldlm_namespace_first_locked(client); ldlm_namespace_get(ns); - ldlm_namespace_move(ns, client); + ldlm_namespace_move_locked(ns, client); mutex_up(ldlm_namespace_lock(client)); total += ldlm_pool_shrink(&ns->ns_pool, 0, gfp_mask); ldlm_namespace_put(ns, 1); @@ -810,9 +810,9 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr, cached = 0; break; } - ns = ldlm_namespace_first(client); + ns = ldlm_namespace_first_locked(client); ldlm_namespace_get(ns); - ldlm_namespace_move(ns, client); + ldlm_namespace_move_locked(ns, client); mutex_up(ldlm_namespace_lock(client)); nr_locks = ldlm_pool_granted(&ns->ns_pool); @@ -909,9 +909,9 @@ void ldlm_pools_recalc(ldlm_side_t client) mutex_up(ldlm_namespace_lock(client)); break; } - ns = ldlm_namespace_first(client); + ns = ldlm_namespace_first_locked(client); ldlm_namespace_get(ns); - ldlm_namespace_move(ns, client); + ldlm_namespace_move_locked(ns, client); mutex_up(ldlm_namespace_lock(client)); /* After setup is done - recalc the pool. */ diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index 2629a64..48399f1 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -336,6 +336,7 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client, CFS_INIT_LIST_HEAD(bucket); CFS_INIT_LIST_HEAD(&ns->ns_unused_list); + CFS_INIT_LIST_HEAD(&ns->ns_list_chain); ns->ns_nr_unused = 0; ns->ns_max_unused = LDLM_DEFAULT_LRU_SIZE; ns->ns_max_age = LDLM_DEFAULT_MAX_ALIVE; @@ -354,11 +355,7 @@ struct ldlm_namespace *ldlm_namespace_new(char *name, ldlm_side_t client, } at_init(&ns->ns_at_estimate, ldlm_enqueue_min, 0); - - mutex_down(ldlm_namespace_lock(client)); - list_add(&ns->ns_list_chain, ldlm_namespace_list(client)); - atomic_inc(ldlm_namespace_nr(client)); - mutex_up(ldlm_namespace_lock(client)); + ldlm_namespace_register(ns, client); RETURN(ns); out_proc: @@ -552,6 +549,9 @@ void ldlm_namespace_free_prior(struct ldlm_namespace *ns, return; } + /* Remove @ns from list. */ + ldlm_namespace_unregister(ns, ns->ns_client); + /* Can fail with -EINTR when force == 0 in which case try harder */ rc = __ldlm_namespace_free(ns, force); if (rc != ELDLM_OK) { @@ -575,16 +575,14 @@ void ldlm_namespace_free_post(struct ldlm_namespace *ns) EXIT; return; } - mutex_down(ldlm_namespace_lock(ns->ns_client)); - /* - * Some asserts and possibly other parts of code still using - * list_empty(&ns->ns_list_chain). This is why it is important - * to use list_del_init() here. + + /* + * Fini pool _before_ parent proc dir is removed. This is important as + * ldlm_pool_fini() removes own proc dir which is child to @dir. Removing + * it after @dir may cause oops. */ - list_del_init(&ns->ns_list_chain); - atomic_dec(ldlm_namespace_nr(ns->ns_client)); ldlm_pool_fini(&ns->ns_pool); - mutex_up(ldlm_namespace_lock(ns->ns_client)); + #ifdef LPROCFS { struct proc_dir_entry *dir; @@ -634,7 +632,7 @@ void ldlm_namespace_free(struct ldlm_namespace *ns, ldlm_namespace_free_post(ns); } -void ldlm_namespace_get_nolock(struct ldlm_namespace *ns) +void ldlm_namespace_get_locked(struct ldlm_namespace *ns) { LASSERT(ns->ns_refcount >= 0); ns->ns_refcount++; @@ -643,11 +641,11 @@ void ldlm_namespace_get_nolock(struct ldlm_namespace *ns) void ldlm_namespace_get(struct ldlm_namespace *ns) { spin_lock(&ns->ns_hash_lock); - ldlm_namespace_get_nolock(ns); + ldlm_namespace_get_locked(ns); spin_unlock(&ns->ns_hash_lock); } -void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup) +void ldlm_namespace_put_locked(struct ldlm_namespace *ns, int wakeup) { LASSERT(ns->ns_refcount > 0); ns->ns_refcount--; @@ -658,12 +656,37 @@ void ldlm_namespace_put_nolock(struct ldlm_namespace *ns, int wakeup) void ldlm_namespace_put(struct ldlm_namespace *ns, int wakeup) { spin_lock(&ns->ns_hash_lock); - ldlm_namespace_put_nolock(ns, wakeup); + ldlm_namespace_put_locked(ns, wakeup); spin_unlock(&ns->ns_hash_lock); } +/* Register @ns in the list of namespaces */ +void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client) +{ + mutex_down(ldlm_namespace_lock(client)); + LASSERT(list_empty(&ns->ns_list_chain)); + list_add(&ns->ns_list_chain, ldlm_namespace_list(client)); + atomic_inc(ldlm_namespace_nr(client)); + mutex_up(ldlm_namespace_lock(client)); +} + +/* Unregister @ns from the list of namespaces */ +void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client) +{ + mutex_down(ldlm_namespace_lock(client)); + LASSERT(!list_empty(&ns->ns_list_chain)); + /* + * Some asserts and possibly other parts of code still using + * list_empty(&ns->ns_list_chain). This is why it is important + * to use list_del_init() here. + */ + list_del_init(&ns->ns_list_chain); + atomic_dec(ldlm_namespace_nr(client)); + mutex_up(ldlm_namespace_lock(client)); +} + /* Should be called under ldlm_namespace_lock(client) taken */ -void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client) +void ldlm_namespace_move_locked(struct ldlm_namespace *ns, ldlm_side_t client) { LASSERT(!list_empty(&ns->ns_list_chain)); LASSERT_SEM_LOCKED(ldlm_namespace_lock(client)); @@ -671,7 +694,7 @@ void ldlm_namespace_move(struct ldlm_namespace *ns, ldlm_side_t client) } /* Should be called under ldlm_namespace_lock(client) taken */ -struct ldlm_namespace *ldlm_namespace_first(ldlm_side_t client) +struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t client) { LASSERT_SEM_LOCKED(ldlm_namespace_lock(client)); LASSERT(!list_empty(ldlm_namespace_list(client))); @@ -786,7 +809,7 @@ ldlm_resource_add(struct ldlm_namespace *ns, struct ldlm_resource *parent, bucket = ns->ns_hash + hash; list_add(&res->lr_hash, bucket); ns->ns_resources++; - ldlm_namespace_get_nolock(ns); + ldlm_namespace_get_locked(ns); if (parent == NULL) { list_add(&res->lr_childof, &ns->ns_root_list); @@ -885,7 +908,7 @@ void __ldlm_resource_putref_final(struct ldlm_resource *res) /* Pass 0 as second argument to not wake up ->ns_waitq yet, will do it * later. */ - ldlm_namespace_put_nolock(ns, 0); + ldlm_namespace_put_locked(ns, 0); list_del_init(&res->lr_hash); list_del_init(&res->lr_childof); -- 1.8.3.1