Whamcloud - gitweb
LU-9312 hsm: add a cookie indexed request hash 63/26763/3
authorJohn L. Hammond <john.hammond@intel.com>
Wed, 17 Jun 2015 22:42:36 +0000 (15:42 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 9 May 2017 03:46:23 +0000 (03:46 +0000)
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 <john.hammond@intel.com>
Reviewed-on: https://review.whamcloud.com/26763
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Henri Doreau <henri.doreau@cea.fr>
Reviewed-by: Faccini Bruno <bruno.faccini@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdt/mdt_coordinator.c
lustre/mdt/mdt_hsm_cdt_client.c
lustre/mdt/mdt_hsm_cdt_requests.c
lustre/mdt/mdt_internal.h

index e1f2493..5637ffb 100644 (file)
@@ -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
index 22df94c..a078d39 100644 (file)
@@ -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 {
index 0ac8135..e13fdaf 100644 (file)
 
 #define DEBUG_SUBSYSTEM S_MDS
 
+#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_hash.h>
 #include <obd_support.h>
 #include <lustre/lustre_user.h>
 #include <lprocfs_status.h>
 #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);
index f3f5e0c..89d89ac 100644 (file)
@@ -44,7 +44,8 @@
 #ifndef _MDT_INTERNAL_H
 #define _MDT_INTERNAL_H
 
-
+#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_hash.h>
 #include <upcall_cache.h>
 #include <lustre_net.h>
 #include <lustre/lustre_idl.h>
@@ -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);