From 80d2960154d5dd416e4818473a505579c0a2d875 Mon Sep 17 00:00:00 2001 From: bobijam Date: Tue, 5 May 2009 01:51:55 +0000 Subject: [PATCH] Branch HEAD b=17402 i=vitaly.fertman i=eric.mei Clear up nid_stat's nid_exp_ref_count usage. --- lustre/include/lustre_export.h | 21 ++++++---- lustre/obdclass/lprocfs_status.c | 86 ++++++++++------------------------------ lustre/obdclass/obd_config.c | 4 +- 3 files changed, 36 insertions(+), 75 deletions(-) diff --git a/lustre/include/lustre_export.h b/lustre/include/lustre_export.h index 33b5248..d0e502d 100644 --- a/lustre/include/lustre_export.h +++ b/lustre/include/lustre_export.h @@ -109,24 +109,31 @@ struct filter_export_data { #define fed_lr_off fed_led.led_lr_off #define fed_lr_idx fed_led.led_lr_idx -typedef struct nid_stat_uuid { - struct list_head ns_uuid_list; - struct obd_uuid ns_uuid; -} nid_stat_uuid_t; - typedef struct nid_stat { lnet_nid_t nid; struct hlist_node nid_hash; struct list_head nid_list; - struct list_head nid_uuid_list; struct obd_device *nid_obd; struct proc_dir_entry *nid_proc; struct lprocfs_stats *nid_stats; struct lprocfs_stats *nid_ldlm_stats; struct brw_stats *nid_brw_stats; - int nid_exp_ref_count; + atomic_t nid_exp_ref_count; /* for obd_nid_stats_hash + exp_nid_stats */ }nid_stat_t; +#define nidstat_getref(nidstat) \ +do { \ + atomic_inc(&(nidstat)->nid_exp_ref_count); \ +} while(0) + +#define nidstat_putref(nidstat) \ +do { \ + atomic_dec(&(nidstat)->nid_exp_ref_count); \ + LASSERTF(atomic_read(&(nidstat)->nid_exp_ref_count) >= 0, \ + "stat %p nid_exp_ref_count < 0\n", nidstat); \ +} while(0) + enum obd_option { OBD_OPT_FORCE = 0x0001, OBD_OPT_FAILOVER = 0x0002, diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index f50c739..a1faf78 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -1055,8 +1055,8 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat) client_stat->nid_proc, client_stat->nid_stats, client_stat->nid_brw_stats); - LASSERTF(client_stat->nid_exp_ref_count == 0, "count %d\n", - client_stat->nid_exp_ref_count); + LASSERTF(atomic_read(&client_stat->nid_exp_ref_count) == 0, + "count %d\n", atomic_read(&client_stat->nid_exp_ref_count)); hlist_del_init(&client_stat->nid_hash); @@ -1676,10 +1676,10 @@ void lprocfs_nid_stats_clear_write_cb(void *obj, void *data) ENTRY; /* object has only hash + iterate_all references. * add/delete blocked by hash bucket lock */ - CDEBUG(D_INFO,"refcnt %d\n", stat->nid_exp_ref_count); - if (stat->nid_exp_ref_count == 2) { + CDEBUG(D_INFO,"refcnt %d\n", atomic_read(&stat->nid_exp_ref_count)); + if (atomic_read(&stat->nid_exp_ref_count) == 2) { hlist_del_init(&stat->nid_hash); - stat->nid_exp_ref_count--; + nidstat_putref(stat); spin_lock(&stat->nid_obd->obd_nid_lock); list_move(&stat->nid_list, data); spin_unlock(&stat->nid_obd->obd_nid_lock); @@ -1722,7 +1722,6 @@ EXPORT_SYMBOL(lprocfs_nid_stats_clear_write); int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) { struct nid_stat *new_stat, *old_stat; - struct nid_stat_uuid *new_ns_uuid; struct obd_device *obd = NULL; cfs_proc_dir_entry_t *entry; int rc = 0; @@ -1748,51 +1747,30 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) if (new_stat == NULL) RETURN(-ENOMEM); - OBD_ALLOC_PTR(new_ns_uuid); - if (new_ns_uuid == NULL) { - OBD_FREE_PTR(new_stat); - RETURN(-ENOMEM); - } - CFS_INIT_LIST_HEAD(&new_ns_uuid->ns_uuid_list); - strncpy(new_ns_uuid->ns_uuid.uuid, exp->exp_client_uuid.uuid, - sizeof(struct obd_uuid)); - - CFS_INIT_LIST_HEAD(&new_stat->nid_uuid_list); new_stat->nid = *nid; new_stat->nid_obd = exp->exp_obd; - new_stat->nid_exp_ref_count = 1; /* live in hash after destroy export */ + atomic_set(&new_stat->nid_exp_ref_count, 0); old_stat = lustre_hash_findadd_unique(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash); CDEBUG(D_INFO, "Found stats %p for nid %s - ref %d\n", - old_stat, libcfs_nid2str(*nid), new_stat->nid_exp_ref_count); + old_stat, libcfs_nid2str(*nid), + atomic_read(&new_stat->nid_exp_ref_count)); /* Return -EALREADY here so that we know that the /proc * entry already has been created */ if (old_stat != new_stat) { - struct nid_stat_uuid *tmp_uuid; - int found = 0; - - exp->exp_nid_stats = old_stat; - /* We need to decrement the refcount if the uuid was - * already in our list */ spin_lock(&obd->obd_nid_lock); - list_for_each_entry(tmp_uuid, &old_stat->nid_uuid_list, - ns_uuid_list) { - if (tmp_uuid && obd_uuid_equals(&tmp_uuid->ns_uuid, - &exp->exp_client_uuid)){ - found = 1; - --old_stat->nid_exp_ref_count; - break; - } + if (exp->exp_nid_stats != old_stat) { + if (exp->exp_nid_stats) + nidstat_putref(exp->exp_nid_stats); + exp->exp_nid_stats = old_stat; + } else { + /* lustre_hash_findadd_unique() has added + * old_stat's refcount */ + nidstat_putref(old_stat); } - if (!found) - list_add(&new_ns_uuid->ns_uuid_list, - &old_stat->nid_uuid_list); - else - OBD_FREE_PTR(new_ns_uuid); - spin_unlock(&obd->obd_nid_lock); GOTO(destroy_new, rc = -EALREADY); @@ -1807,11 +1785,6 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) GOTO(destroy_new_ns, rc = -ENOMEM); } - /* Add in uuid to our nid_stats list */ - spin_lock(&obd->obd_nid_lock); - list_add(&new_ns_uuid->ns_uuid_list, &new_stat->nid_uuid_list); - spin_unlock(&obd->obd_nid_lock); - entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", lprocfs_exp_rd_uuid, NULL, new_stat, NULL); if (IS_ERR(entry)) { @@ -1828,6 +1801,9 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) GOTO(destroy_new_ns, rc); } + if (exp->exp_nid_stats) + nidstat_putref(exp->exp_nid_stats); + nidstat_getref(new_stat); exp->exp_nid_stats = new_stat; *newnid = 1; /* protect competitive add to list, not need locking on destroy */ @@ -1841,7 +1817,6 @@ destroy_new_ns: if (new_stat->nid_proc != NULL) lprocfs_remove(&new_stat->nid_proc); lustre_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash); - OBD_FREE_PTR(new_ns_uuid); destroy_new: OBD_FREE_PTR(new_stat); @@ -1851,32 +1826,11 @@ destroy_new: int lprocfs_exp_cleanup(struct obd_export *exp) { struct nid_stat *stat = exp->exp_nid_stats; - struct nid_stat_uuid *cursor, *tmp; - int found = 0; if(!stat || !exp->exp_obd) RETURN(0); - spin_lock(&exp->exp_obd->obd_nid_lock); - list_for_each_entry_safe(cursor, tmp, - &stat->nid_uuid_list, - ns_uuid_list) { - if (cursor && obd_uuid_equals(&cursor->ns_uuid, - &exp->exp_client_uuid)) { - found = 1; - list_del(&cursor->ns_uuid_list); - OBD_FREE_PTR(cursor); - --stat->nid_exp_ref_count; - CDEBUG(D_INFO, "Put stat %p - %d\n", stat, - stat->nid_exp_ref_count); - break; - } - } - spin_unlock(&exp->exp_obd->obd_nid_lock); - if (!found) - CERROR("obd_export's client uuid %s are not found in its " - "nid_stats list\n", exp->exp_client_uuid.uuid); - + nidstat_putref(exp->exp_nid_stats); exp->exp_nid_stats = NULL; lprocfs_free_md_stats(exp->exp_obd); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index af30f03..632fb3d 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -1574,7 +1574,7 @@ nidstats_get(struct hlist_node *hnode) struct nid_stat *ns; ns = hlist_entry(hnode, struct nid_stat, nid_hash); - ns->nid_exp_ref_count++; + nidstat_getref(ns); RETURN(ns); } @@ -1585,7 +1585,7 @@ nidstats_put(struct hlist_node *hnode) struct nid_stat *ns; ns = hlist_entry(hnode, struct nid_stat, nid_hash); - ns->nid_exp_ref_count--; + nidstat_putref(ns); RETURN(ns); } -- 1.8.3.1