From f50f48669cfd4ed07d0af055da4990a8b0a4b35a Mon Sep 17 00:00:00 2001 From: pravins Date: Thu, 9 Oct 2008 14:36:33 +0000 Subject: [PATCH] b=15977 i=umka i=grev backported patch for fixing memory leak in per-nid-stat. --- lustre/obdclass/lprocfs_status.c | 89 ++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 16e622d..594228d 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -812,12 +812,12 @@ static void lprocfs_free_client_stats(struct nid_stat *client_stat) lprocfs_free_stats(&client_stat->nid_stats); if (client_stat->nid_brw_stats) - OBD_FREE(client_stat->nid_brw_stats, sizeof(struct brw_stats)); + OBD_FREE_PTR(client_stat->nid_brw_stats); if (client_stat->nid_ldlm_stats) lprocfs_free_stats(&client_stat->nid_ldlm_stats); - OBD_FREE(client_stat, sizeof(*client_stat)); + OBD_FREE_PTR(client_stat); return; } @@ -1417,8 +1417,8 @@ EXPORT_SYMBOL(lprocfs_nid_stats_clear_write); int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) { int rc = 0; - struct nid_stat *tmp, *tmp1; - struct nid_stat_uuid *cursor, *tmp_ns_uuid; + struct nid_stat *new_stat, *old_stat; + struct nid_stat_uuid *cursor, *new_ns_uuid; struct obd_device *obd; cfs_proc_dir_entry_t *entry; ENTRY; @@ -1430,8 +1430,8 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) RETURN(-EINVAL); /* not test against zero because eric say: - * You may only test nid against another nid, or LNET_NID_ANY. Anything else is - * nonsense.*/ + * You may only test nid against another nid, or LNET_NID_ANY. + * Anything else is nonsense.*/ if (!nid || *nid == LNET_NID_ANY) RETURN(0); @@ -1439,100 +1439,109 @@ int lprocfs_exp_setup(struct obd_export *exp, lnet_nid_t *nid, int *newnid) CDEBUG(D_CONFIG, "using hash %p\n", obd->obd_nid_stats_hash); - OBD_ALLOC_PTR(tmp); - if (tmp == NULL) + OBD_ALLOC_PTR(new_stat); + if (new_stat == NULL) RETURN(-ENOMEM); - OBD_ALLOC(tmp_ns_uuid, sizeof(struct nid_stat_uuid)); - if (tmp_ns_uuid == NULL) { - OBD_FREE(tmp, sizeof(struct nid_stat)); + OBD_ALLOC_PTR(new_ns_uuid); + if (new_ns_uuid == NULL) { + OBD_FREE_PTR(new_stat); RETURN(-ENOMEM); } - CFS_INIT_LIST_HEAD(&tmp_ns_uuid->ns_uuid_list); - strncpy(tmp_ns_uuid->ns_uuid.uuid, exp->exp_client_uuid.uuid, + 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(&tmp->nid_uuid_list); - tmp->nid = *nid; - tmp->nid_obd = exp->exp_obd; - tmp->nid_exp_ref_count = 1; /* need live in hash after destroy export */ + 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; /* need live in hash after destroy export */ /* protect competitive add to list, not need locking on destroy */ spin_lock(&obd->obd_nid_lock); - list_add(&tmp->nid_list, &obd->obd_nid_stats); + list_add(&new_stat->nid_list, &obd->obd_nid_stats); spin_unlock(&obd->obd_nid_lock); - tmp1 = lustre_hash_findadd_unique(obd->obd_nid_stats_hash, - nid, &tmp->nid_hash); + 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", - tmp1, libcfs_nid2str(*nid), tmp->nid_exp_ref_count); + old_stat, libcfs_nid2str(*nid), new_stat->nid_exp_ref_count); /* Return -EALREADY here so that we know that the /proc * entry already has been created */ - if (tmp1 != tmp) { + if (old_stat != new_stat) { int found = 0; - exp->exp_nid_stats = tmp1; + 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(cursor, - &tmp1->nid_uuid_list, + &old_stat->nid_uuid_list, ns_uuid_list) { if (cursor && obd_uuid_equals(&cursor->ns_uuid, &exp->exp_client_uuid)) { found = 1; - --tmp1->nid_exp_ref_count; + --old_stat->nid_exp_ref_count; break; } } if (!found) - list_add(&tmp_ns_uuid->ns_uuid_list, - &tmp1->nid_uuid_list); + 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); } /* not found - create */ - tmp->nid_proc = proc_mkdir(libcfs_nid2str(*nid), + new_stat->nid_proc = proc_mkdir(libcfs_nid2str(*nid), obd->obd_proc_exports_entry); - if (!tmp->nid_proc) { + if (!new_stat->nid_proc) { CERROR("Error making export directory for" " nid %s\n", libcfs_nid2str(*nid)); - lustre_hash_del(obd->obd_nid_stats_hash, nid, &tmp->nid_hash); - GOTO(destroy_new, rc = -ENOMEM); + GOTO(destroy_new_ns, rc = -ENOMEM); } /* Add in uuid to our nid_stats list */ spin_lock(&obd->obd_nid_lock); - list_add(&tmp_ns_uuid->ns_uuid_list, &tmp->nid_uuid_list); + list_add(&new_ns_uuid->ns_uuid_list, &new_stat->nid_uuid_list); spin_unlock(&obd->obd_nid_lock); - entry = lprocfs_add_simple(tmp->nid_proc, "uuid", - lprocfs_exp_rd_uuid, NULL, tmp, NULL); + entry = lprocfs_add_simple(new_stat->nid_proc, "uuid", + lprocfs_exp_rd_uuid, NULL, new_stat, NULL); if (IS_ERR(entry)) { CWARN("Error adding the uuid file\n"); rc = PTR_ERR(entry); + GOTO(destroy_new_ns, rc); } - entry = lprocfs_add_simple(tmp->nid_proc, "hash", - lprocfs_exp_rd_hash, NULL, tmp, NULL); + entry = lprocfs_add_simple(new_stat->nid_proc, "hash", + lprocfs_exp_rd_hash, NULL, new_stat, NULL); if (IS_ERR(entry)) { CWARN("Error adding the hash file\n"); rc = PTR_ERR(entry); + lprocfs_remove(&new_stat->nid_proc); + GOTO(destroy_new_ns, rc); } - exp->exp_nid_stats = tmp; + exp->exp_nid_stats = new_stat; *newnid = 1; RETURN(rc); +destroy_new_ns: + lustre_hash_del(obd->obd_nid_stats_hash, nid, &new_stat->nid_hash); + OBD_FREE_PTR(new_ns_uuid); + destroy_new: spin_lock(&obd->obd_nid_lock); - list_del(&tmp->nid_list); + list_del(&new_stat->nid_list); spin_unlock(&obd->obd_nid_lock); - OBD_FREE_PTR(tmp); + OBD_FREE_PTR(new_stat); RETURN(rc); } @@ -1553,7 +1562,7 @@ int lprocfs_exp_cleanup(struct obd_export *exp) &exp->exp_client_uuid)) { found = 1; list_del(&cursor->ns_uuid_list); - OBD_FREE(cursor, sizeof(struct nid_stat_uuid)); + OBD_FREE_PTR(cursor); break; } } -- 1.8.3.1