Whamcloud - gitweb
LU-11290 ldlm: page discard speedup 27/39327/10
authorAlexander Zarochentsev <c17826@cray.com>
Sun, 31 May 2020 16:29:25 +0000 (19:29 +0300)
committerOleg Drokin <green@whamcloud.com>
Thu, 19 Nov 2020 10:19:12 +0000 (10:19 +0000)
Improving check_and_discard_cb, allowing to cache
negative result of dlm lock lookup and avoid
excessive osc_dlm_lock_at_pgoff() calls.

HPE-bug-id: LUS-6432
Change-Id: I253f944bf430b06d0e1a300d22e5d9b2e97412bf
Signed-off-by: Alexander Zarochentsev <c17826@cray.com>
Reviewed-on: https://review.whamcloud.com/39327
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Vitaly Fertman <vitaly.fertman@hpe.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_dlm.h
lustre/include/lustre_osc.h
lustre/ldlm/ldlm_lock.c
lustre/osc/osc_cache.c
lustre/osc/osc_lock.c

index 65e91fe..1bcd224 100644 (file)
@@ -1013,6 +1013,7 @@ enum ldlm_match_flags {
        LDLM_MATCH_UNREF   = BIT(0),
        LDLM_MATCH_AST     = BIT(1),
        LDLM_MATCH_AST_ANY = BIT(2),
        LDLM_MATCH_UNREF   = BIT(0),
        LDLM_MATCH_AST     = BIT(1),
        LDLM_MATCH_AST_ANY = BIT(2),
+       LDLM_MATCH_RIGHT   = BIT(3),
 };
 
 /**
 };
 
 /**
index f41ecb7..6432a59 100644 (file)
@@ -169,6 +169,7 @@ struct osc_thread_info {
         */
        pgoff_t                 oti_next_index;
        pgoff_t                 oti_fn_index; /* first non-overlapped index */
         */
        pgoff_t                 oti_next_index;
        pgoff_t                 oti_fn_index; /* first non-overlapped index */
+       pgoff_t                 oti_ng_index; /* negative lock caching */
        struct cl_sync_io       oti_anchor;
        struct cl_req_attr      oti_req_attr;
        struct lu_buf           oti_ladvise_buf;
        struct cl_sync_io       oti_anchor;
        struct cl_req_attr      oti_req_attr;
        struct lu_buf           oti_ladvise_buf;
@@ -231,6 +232,10 @@ enum osc_dap_flags {
         * check ast data is present, requested to cancel cb
         */
        OSC_DAP_FL_AST       = BIT(2),
         * check ast data is present, requested to cancel cb
         */
        OSC_DAP_FL_AST       = BIT(2),
+       /**
+        * look at right region for the desired lock
+        */
+       OSC_DAP_FL_RIGHT     = BIT(3),
 };
 
 /*
 };
 
 /*
index 546f351..dcb6448 100644 (file)
@@ -1199,8 +1199,9 @@ static int lock_matches(struct ldlm_lock *lock, struct ldlm_match_data *data)
 
        switch (lock->l_resource->lr_type) {
        case LDLM_EXTENT:
 
        switch (lock->l_resource->lr_type) {
        case LDLM_EXTENT:
-               if (lpol->l_extent.start > data->lmd_policy->l_extent.start ||
-                   lpol->l_extent.end < data->lmd_policy->l_extent.end)
+               if (!(data->lmd_match & LDLM_MATCH_RIGHT) &&
+                   (lpol->l_extent.start > data->lmd_policy->l_extent.start ||
+                    lpol->l_extent.end < data->lmd_policy->l_extent.end))
                        return INTERVAL_ITER_CONT;
 
                if (unlikely(match == LCK_GROUP) &&
                        return INTERVAL_ITER_CONT;
 
                if (unlikely(match == LCK_GROUP) &&
@@ -1286,6 +1287,9 @@ struct ldlm_lock *search_itree(struct ldlm_resource *res,
 
        data->lmd_lock = NULL;
 
 
        data->lmd_lock = NULL;
 
+       if (data->lmd_match & LDLM_MATCH_RIGHT)
+               ext.end = OBD_OBJECT_EOF;
+
        for (idx = 0; idx < LCK_MODE_NUM; idx++) {
                struct ldlm_interval_tree *tree = &res->lr_itree[idx];
 
        for (idx = 0; idx < LCK_MODE_NUM; idx++) {
                struct ldlm_interval_tree *tree = &res->lr_itree[idx];
 
index a477ebd..364a71f 100644 (file)
@@ -3117,28 +3117,51 @@ static bool check_and_discard_cb(const struct lu_env *env, struct cl_io *io,
 {
        struct osc_thread_info *info = osc_env_info(env);
        struct osc_object *osc = cbdata;
 {
        struct osc_thread_info *info = osc_env_info(env);
        struct osc_object *osc = cbdata;
+       struct cl_page *page = ops->ops_cl.cpl_page;
        pgoff_t index;
        pgoff_t index;
+       bool discard = false;
 
        index = osc_index(ops);
 
        index = osc_index(ops);
-       if (index >= info->oti_fn_index) {
-               struct ldlm_lock *tmp;
-               struct cl_page *page = ops->ops_cl.cpl_page;
 
 
+       /* negative lock caching */
+       if (index < info->oti_ng_index) {
+               discard = true;
+       } else if (index >= info->oti_fn_index) {
+               struct ldlm_lock *tmp;
                /* refresh non-overlapped index */
                tmp = osc_dlmlock_at_pgoff(env, osc, index,
                /* refresh non-overlapped index */
                tmp = osc_dlmlock_at_pgoff(env, osc, index,
-                                          OSC_DAP_FL_TEST_LOCK | OSC_DAP_FL_AST);
+                                          OSC_DAP_FL_TEST_LOCK |
+                                          OSC_DAP_FL_AST | OSC_DAP_FL_RIGHT);
                if (tmp != NULL) {
                        __u64 end = tmp->l_policy_data.l_extent.end;
                if (tmp != NULL) {
                        __u64 end = tmp->l_policy_data.l_extent.end;
-                       /* Cache the first-non-overlapped index so as to skip
-                        * all pages within [index, oti_fn_index). This is safe
-                        * because if tmp lock is canceled, it will discard
-                        * these pages. */
-                       info->oti_fn_index = cl_index(osc2cl(osc), end + 1);
-                       if (end == OBD_OBJECT_EOF)
-                               info->oti_fn_index = CL_PAGE_EOF;
+                       __u64 start = tmp->l_policy_data.l_extent.start;
+
+                       /* no lock covering this page */
+                       if (index < cl_index(osc2cl(osc), start)) {
+                               /* no lock at @index, first lock at @start */
+                               info->oti_ng_index = cl_index(osc2cl(osc),
+                                                    start);
+                               discard = true;
+                       } else {
+                               /* Cache the first-non-overlapped index so as to
+                                * skip all pages within [index, oti_fn_index).
+                                * This is safe because if tmp lock is canceled,
+                                * it will discard these pages.
+                                */
+                               info->oti_fn_index = cl_index(osc2cl(osc),
+                                                    end + 1);
+                               if (end == OBD_OBJECT_EOF)
+                                       info->oti_fn_index = CL_PAGE_EOF;
+                       }
                        LDLM_LOCK_PUT(tmp);
                        LDLM_LOCK_PUT(tmp);
-               } else if (cl_page_own(env, io, page) == 0) {
-                       /* discard the page */
+               } else {
+                       info->oti_ng_index = CL_PAGE_EOF;
+                       discard = true;
+               }
+       }
+
+       if (discard) {
+               if (cl_page_own(env, io, page) == 0) {
                        cl_page_discard(env, io, page);
                        cl_page_disown(env, io, page);
                } else {
                        cl_page_discard(env, io, page);
                        cl_page_disown(env, io, page);
                } else {
@@ -3201,6 +3224,7 @@ int osc_lock_discard_pages(const struct lu_env *env, struct osc_object *osc,
 
        cb = discard ? osc_discard_cb : check_and_discard_cb;
        info->oti_fn_index = info->oti_next_index = start;
 
        cb = discard ? osc_discard_cb : check_and_discard_cb;
        info->oti_fn_index = info->oti_next_index = start;
+       info->oti_ng_index = 0;
 
        osc_page_gang_lookup(env, io, osc,
                             info->oti_next_index, end, cb, osc);
 
        osc_page_gang_lookup(env, io, osc,
                             info->oti_next_index, end, cb, osc);
index f3ed624..62da056 100644 (file)
@@ -1294,6 +1294,9 @@ struct ldlm_lock *osc_obj_dlmlock_at_pgoff(const struct lu_env *env,
        if (dap_flags & OSC_DAP_FL_CANCELING)
                match_flags |= LDLM_MATCH_UNREF;
 
        if (dap_flags & OSC_DAP_FL_CANCELING)
                match_flags |= LDLM_MATCH_UNREF;
 
+       if (dap_flags & OSC_DAP_FL_RIGHT)
+               match_flags |= LDLM_MATCH_RIGHT;
+
        /*
         * It is fine to match any group lock since there could be only one
         * with a uniq gid and it conflicts with all other lock modes too
        /*
         * It is fine to match any group lock since there could be only one
         * with a uniq gid and it conflicts with all other lock modes too