From dded1e7283d66ebf673901caed90588a58096086 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 17 Jun 2015 15:42:36 -0700 Subject: [PATCH] LU-9312 hsm: add a cookie indexed request hash Replace linear scans of the HSM coordinator's cdt_requests list with lookups into a cookie indexed hash (cdt_request_cookie_hash). Rename cdt_requests to cdt_request_list. Remove the unused function mdt_hsm_get_running(). Change-Id: I97309aeeb0e02a07e8ddac9f1667989c65f01b8b Signed-off-by: John L. Hammond Reviewed-on: https://review.whamcloud.com/26763 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Henri Doreau Reviewed-by: Faccini Bruno Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_coordinator.c | 52 ++++++++++---- lustre/mdt/mdt_hsm_cdt_client.c | 37 +--------- lustre/mdt/mdt_hsm_cdt_requests.c | 142 ++++++++++++++++++++++---------------- lustre/mdt/mdt_internal.h | 18 ++--- 4 files changed, 131 insertions(+), 118 deletions(-) diff --git a/lustre/mdt/mdt_coordinator.c b/lustre/mdt/mdt_coordinator.c index e1f2493..5637ffb 100644 --- a/lustre/mdt/mdt_coordinator.c +++ b/lustre/mdt/mdt_coordinator.c @@ -282,7 +282,7 @@ static int mdt_coordinator_cb(const struct lu_env *env, * error may happen if coordinator crashes or stopped * with running request */ - car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie, NULL); + car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie); if (car == NULL) { last = larr->arr_req_change; } else { @@ -776,23 +776,33 @@ int mdt_hsm_cdt_init(struct mdt_device *mdt) init_rwsem(&cdt->cdt_request_lock); mutex_init(&cdt->cdt_restore_lock); - INIT_LIST_HEAD(&cdt->cdt_requests); + INIT_LIST_HEAD(&cdt->cdt_request_list); INIT_LIST_HEAD(&cdt->cdt_agents); INIT_LIST_HEAD(&cdt->cdt_restore_hdl); + cdt->cdt_request_cookie_hash = cfs_hash_create("REQUEST_COOKIE_HASH", + CFS_HASH_BITS_MIN, + CFS_HASH_BITS_MAX, + CFS_HASH_BKT_BITS, + 0 /* extra bytes */, + CFS_HASH_MIN_THETA, + CFS_HASH_MAX_THETA, + &cdt_request_cookie_hash_ops, + CFS_HASH_DEFAULT); + if (cdt->cdt_request_cookie_hash == NULL) + RETURN(-ENOMEM); + rc = lu_env_init(&cdt->cdt_env, LCT_MD_THREAD); if (rc < 0) - RETURN(rc); + GOTO(out_request_cookie_hash, rc); /* for mdt_ucred(), lu_ucred stored in lu_ucred_key */ rc = lu_context_init(&cdt->cdt_session, LCT_SERVER_SESSION); - if (rc == 0) { - lu_context_enter(&cdt->cdt_session); - cdt->cdt_env.le_ses = &cdt->cdt_session; - } else { - lu_env_fini(&cdt->cdt_env); - RETURN(rc); - } + if (rc < 0) + GOTO(out_env, rc); + + lu_context_enter(&cdt->cdt_session); + cdt->cdt_env.le_ses = &cdt->cdt_session; cdt_mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key); LASSERT(cdt_mti != NULL); @@ -812,6 +822,14 @@ int mdt_hsm_cdt_init(struct mdt_device *mdt) cdt->cdt_active_req_timeout = 3600; RETURN(0); + +out_env: + lu_env_fini(&cdt->cdt_env); +out_request_cookie_hash: + cfs_hash_putref(cdt->cdt_request_cookie_hash); + cdt->cdt_request_cookie_hash = NULL; + + return rc; } /** @@ -828,6 +846,9 @@ int mdt_hsm_cdt_fini(struct mdt_device *mdt) lu_env_fini(&cdt->cdt_env); + cfs_hash_putref(cdt->cdt_request_cookie_hash); + cdt->cdt_request_cookie_hash = NULL; + RETURN(0); } @@ -936,10 +957,13 @@ int mdt_hsm_cdt_stop(struct mdt_device *mdt) /* start cleaning */ down_write(&cdt->cdt_request_lock); - list_for_each_entry_safe(car, tmp1, &cdt->cdt_requests, + list_for_each_entry_safe(car, tmp1, &cdt->cdt_request_list, car_request_list) { + cfs_hash_del(cdt->cdt_request_cookie_hash, + &car->car_hai->hai_cookie, + &car->car_cookie_hash); list_del(&car->car_request_list); - mdt_cdt_free_request(car); + mdt_cdt_put_request(car); } up_write(&cdt->cdt_request_lock); @@ -1014,7 +1038,7 @@ int mdt_hsm_add_hal(struct mdt_thread_info *mti, } /* find the running request to set it canceled */ - car = mdt_cdt_find_request(cdt, hai->hai_cookie, NULL); + car = mdt_cdt_find_request(cdt, hai->hai_cookie); if (car != NULL) { car->car_canceled = 1; /* uuid has to be changed to the one running the @@ -1554,7 +1578,7 @@ static int hsm_cancel_all_actions(struct mdt_device *mdt) /* send cancel to all running requests */ down_read(&cdt->cdt_request_lock); - list_for_each_entry(car, &cdt->cdt_requests, car_request_list) { + list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) { mdt_cdt_get_request(car); /* request is not yet removed from list, it will be done * when copytool will return progress diff --git a/lustre/mdt/mdt_hsm_cdt_client.c b/lustre/mdt/mdt_hsm_cdt_client.c index 22df94c..a078d39 100644 --- a/lustre/mdt/mdt_hsm_cdt_client.c +++ b/lustre/mdt/mdt_hsm_cdt_client.c @@ -472,41 +472,6 @@ out: } /** - * get running action on a FID list or from cookie - * \param mti [IN] - * \param hal [IN/OUT] requests - * \retval 0 success - * \retval -ve failure - */ -int mdt_hsm_get_running(struct mdt_thread_info *mti, - struct hsm_action_list *hal) -{ - struct mdt_device *mdt = mti->mti_mdt; - struct coordinator *cdt = &mdt->mdt_coordinator; - struct hsm_action_item *hai; - int i; - ENTRY; - - hai = hai_first(hal); - for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { - struct cdt_agent_req *car; - - if (!fid_is_sane(&hai->hai_fid)) - RETURN(-EINVAL); - - car = mdt_cdt_find_request(cdt, 0, &hai->hai_fid); - if (car == NULL) { - hai->hai_cookie = 0; - hai->hai_action = HSMA_NONE; - } else { - *hai = *car->car_hai; - mdt_cdt_put_request(car); - } - } - RETURN(0); -} - -/** * check if a restore is running on a FID * this is redundant with mdt_hsm_coordinator_get_running() * but as it can be called frequently when getting attr @@ -581,7 +546,7 @@ int mdt_hsm_get_actions(struct mdt_thread_info *mti, for (i = 0; i < hal->hal_count; i++, hai = hai_next(hai)) { struct cdt_agent_req *car; - car = mdt_cdt_find_request(cdt, hai->hai_cookie, NULL); + car = mdt_cdt_find_request(cdt, hai->hai_cookie); if (car == NULL) { hai->hai_cookie = 0; } else { diff --git a/lustre/mdt/mdt_hsm_cdt_requests.c b/lustre/mdt/mdt_hsm_cdt_requests.c index 0ac8135..e13fdaf 100644 --- a/lustre/mdt/mdt_hsm_cdt_requests.c +++ b/lustre/mdt/mdt_hsm_cdt_requests.c @@ -36,11 +36,63 @@ #define DEBUG_SUBSYSTEM S_MDS +#include +#include #include #include #include #include "mdt_internal.h" +static unsigned int +cdt_request_cookie_hash(struct cfs_hash *hs, const void *key, unsigned int mask) +{ + return cfs_hash_djb2_hash(key, sizeof(u64), mask); +} + +static void *cdt_request_cookie_object(struct hlist_node *hnode) +{ + return hlist_entry(hnode, struct cdt_agent_req, car_cookie_hash); +} + +static void *cdt_request_cookie_key(struct hlist_node *hnode) +{ + struct cdt_agent_req *car = cdt_request_cookie_object(hnode); + + return &car->car_hai->hai_cookie; +} + +static int cdt_request_cookie_keycmp(const void *key, struct hlist_node *hnode) +{ + const u64 *cookie2 = cdt_request_cookie_key(hnode); + + return *(u64 *)key == *cookie2; +} + +static void +cdt_request_cookie_get(struct cfs_hash *hs, struct hlist_node *hnode) +{ + struct cdt_agent_req *car = cdt_request_cookie_object(hnode); + + mdt_cdt_get_request(car); +} + +static void +cdt_request_cookie_put(struct cfs_hash *hs, struct hlist_node *hnode) +{ + struct cdt_agent_req *car = cdt_request_cookie_object(hnode); + + mdt_cdt_put_request(car); +} + +struct cfs_hash_ops cdt_request_cookie_hash_ops = { + .hs_hash = cdt_request_cookie_hash, + .hs_key = cdt_request_cookie_key, + .hs_keycmp = cdt_request_cookie_keycmp, + .hs_object = cdt_request_cookie_object, + .hs_get = cdt_request_cookie_get, + .hs_put_locked = cdt_request_cookie_put, +}; + /** * dump requests list * \param cdt [IN] coordinator @@ -50,7 +102,7 @@ void dump_requests(char *prefix, struct coordinator *cdt) struct cdt_agent_req *car; down_read(&cdt->cdt_request_lock); - list_for_each_entry(car, &cdt->cdt_requests, car_request_list) { + list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) { CDEBUG(D_HSM, "%s fid="DFID" dfid="DFID " compound/cookie=%#llx/%#llx" " action=%s archive#=%d flags=%#llx" @@ -301,60 +353,35 @@ void mdt_cdt_put_request(struct cdt_agent_req *car) } /** - * find request in the list by cookie or by fid - * lock cdt_request_lock needs to be held by caller - * \param cdt [IN] coordinator - * \param cookie [IN] request cookie - * \param fid [IN] fid - * \retval request pointer or NULL if not found - */ -static struct cdt_agent_req *cdt_find_request_nolock(struct coordinator *cdt, - __u64 cookie, - const struct lu_fid *fid) -{ - struct cdt_agent_req *car; - struct cdt_agent_req *found = NULL; - ENTRY; - - list_for_each_entry(car, &cdt->cdt_requests, car_request_list) { - if (car->car_hai->hai_cookie == cookie || - (fid != NULL && lu_fid_eq(fid, &car->car_hai->hai_fid))) { - mdt_cdt_get_request(car); - found = car; - break; - } - } - - RETURN(found); -} - -/** * add a request to the list * \param cdt [IN] coordinator * \param car [IN] request * \retval 0 success * \retval -ve failure */ -int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car) +int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *car) { - struct cdt_agent_req *car; + int rc; ENTRY; /* cancel requests are not kept in memory */ - LASSERT(new_car->car_hai->hai_action != HSMA_CANCEL); + LASSERT(car->car_hai->hai_action != HSMA_CANCEL); down_write(&cdt->cdt_request_lock); - car = cdt_find_request_nolock(cdt, new_car->car_hai->hai_cookie, NULL); - if (car != NULL) { - mdt_cdt_put_request(car); + + rc = cfs_hash_add_unique(cdt->cdt_request_cookie_hash, + &car->car_hai->hai_cookie, + &car->car_cookie_hash); + if (rc < 0) { up_write(&cdt->cdt_request_lock); RETURN(-EEXIST); } - list_add_tail(&new_car->car_request_list, &cdt->cdt_requests); + list_add_tail(&car->car_request_list, &cdt->cdt_request_list); + up_write(&cdt->cdt_request_lock); - mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &new_car->car_uuid); + mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &car->car_uuid); atomic_inc(&cdt->cdt_request_count); @@ -368,15 +395,13 @@ int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car) * \param fid [IN] fid * \retval request pointer or NULL if not found */ -struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, - const __u64 cookie, - const struct lu_fid *fid) +struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie) { struct cdt_agent_req *car; ENTRY; down_read(&cdt->cdt_request_lock); - car = cdt_find_request_nolock(cdt, cookie, fid); + car = cfs_hash_lookup(cdt->cdt_request_cookie_hash, &cookie); up_read(&cdt->cdt_request_lock); RETURN(car); @@ -394,25 +419,22 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie) ENTRY; down_write(&cdt->cdt_request_lock); - car = cdt_find_request_nolock(cdt, cookie, NULL); - if (car != NULL) { - list_del(&car->car_request_list); + car = cfs_hash_del_key(cdt->cdt_request_cookie_hash, &cookie); + if (car == NULL) { up_write(&cdt->cdt_request_lock); + RETURN(-ENOENT); + } - /* reference from cdt_requests list */ - mdt_cdt_put_request(car); - - /* reference from cdt_find_request_nolock() */ - mdt_cdt_put_request(car); + list_del(&car->car_request_list); + up_write(&cdt->cdt_request_lock); - LASSERT(atomic_read(&cdt->cdt_request_count) >= 1); - atomic_dec(&cdt->cdt_request_count); + /* Drop reference from cdt_request_list. */ + mdt_cdt_put_request(car); - RETURN(0); - } - up_write(&cdt->cdt_request_lock); + LASSERT(atomic_read(&cdt->cdt_request_count) >= 1); + atomic_dec(&cdt->cdt_request_count); - RETURN(-ENOENT); + RETURN(0); } /** @@ -430,7 +452,7 @@ struct cdt_agent_req *mdt_cdt_update_request(struct coordinator *cdt, int rc; ENTRY; - car = mdt_cdt_find_request(cdt, pgs->hpk_cookie, NULL); + car = mdt_cdt_find_request(cdt, pgs->hpk_cookie); if (car == NULL) RETURN(ERR_PTR(-ENOENT)); @@ -469,14 +491,14 @@ static void *mdt_hsm_active_requests_proc_start(struct seq_file *s, loff_t *p) down_read(&cdt->cdt_request_lock); - if (list_empty(&cdt->cdt_requests)) + if (list_empty(&cdt->cdt_request_list)) RETURN(NULL); if (*p == 0) RETURN(SEQ_START_TOKEN); i = 0; - list_for_each(pos, &cdt->cdt_requests) { + list_for_each(pos, &cdt->cdt_request_list) { i++; if (i >= *p) RETURN(pos); @@ -497,12 +519,12 @@ static void *mdt_hsm_active_requests_proc_next(struct seq_file *s, void *v, ENTRY; if (pos == SEQ_START_TOKEN) - pos = cdt->cdt_requests.next; + pos = cdt->cdt_request_list.next; else pos = pos->next; (*p)++; - if (pos != &cdt->cdt_requests) + if (pos != &cdt->cdt_request_list) RETURN(pos); else RETURN(NULL); diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index f3f5e0c..89d89ac 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -44,7 +44,8 @@ #ifndef _MDT_INTERNAL_H #define _MDT_INTERNAL_H - +#include +#include #include #include #include @@ -135,8 +136,11 @@ struct coordinator { * requests */ atomic_t cdt_request_count; /**< current count of * started requests */ - struct list_head cdt_requests; /**< list of started - * requests */ + /* started requests (struct cdt_agent_req:car_cookie_hash) + * indexed by cookie */ + struct cfs_hash *cdt_request_cookie_hash; + /* started requests (struct cdt_agent_req:car_request_list) */ + struct list_head cdt_request_list; struct list_head cdt_agents; /**< list of register * agents */ struct list_head cdt_restore_hdl; /**< list of restore lock @@ -454,6 +458,7 @@ struct cdt_req_progress { }; struct cdt_agent_req { + struct hlist_node car_cookie_hash; /**< find req by cookie */ struct list_head car_request_list; /**< to chain all the req. */ atomic_t car_refcount; /**< reference counter */ __u64 car_compound_id; /**< compound id */ @@ -826,11 +831,10 @@ int mdt_hsm_add_actions(struct mdt_thread_info *info, struct hsm_action_list *hal); int mdt_hsm_get_actions(struct mdt_thread_info *mti, struct hsm_action_list *hal); -int mdt_hsm_get_running(struct mdt_thread_info *mti, - struct hsm_action_list *hal); bool mdt_hsm_restore_is_running(struct mdt_thread_info *mti, const struct lu_fid *fid); /* mdt/mdt_hsm_cdt_requests.c */ +extern struct cfs_hash_ops cdt_request_cookie_hash_ops; extern const struct file_operations mdt_hsm_active_requests_fops; void dump_requests(char *prefix, struct coordinator *cdt); struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id, @@ -838,9 +842,7 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id, struct hsm_action_item *hai); void mdt_cdt_free_request(struct cdt_agent_req *car); int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car); -struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, - const __u64 cookie, - const struct lu_fid *fid); +struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie); void mdt_cdt_get_work_done(struct cdt_agent_req *car, __u64 *done_sz); void mdt_cdt_get_request(struct cdt_agent_req *car); void mdt_cdt_put_request(struct cdt_agent_req *car); -- 1.8.3.1