Whamcloud - gitweb
LU-11085 ldlm: simplify use of interval-tree. 21/33221/28
authorNeilBrown <neilb@suse.de>
Wed, 25 Mar 2020 02:50:16 +0000 (22:50 -0400)
committerOleg Drokin <green@whamcloud.com>
Tue, 21 May 2024 18:20:04 +0000 (18:20 +0000)
The interval tree used for keeping track of extent locks is currently
separate from those locks themselves.  A separate 'ldlm_interval'
structure is allocated and linked to all locks which have the same
extent.

This requires that the interval tree library handles an insert where
exactly the same interval already exists differently from any other
insert.  No other users of the interval tree library wants this, and
the library which is part of linux doesn't support it.  So it would be
good to remove this requirement.

This patch changes the library, removes the 'ldlm_interval' structure,
and stores each lock in the tree.  This substantially simplifies a lot
of code, but has some costs.

The ldlm_lock is now larger - it contains three pointers for the
rbtree where previously it had one, and it now has an extra copy of
the range start/end.  These will be resolved in later patches by
removing duplication and sharing space with other fields that aren't
used for extent locks.

The extent-tree can now be substantially larger as it now contains
every lock for a given extent rather than each extent only once.  As
the depth of the tree grows with the log of the number of elements,
this isn't an enormous cost, but it may still be measurable.  In
particular, locks that cover the full extent [0..MAX] are common and
can swamp other locks (citation needed).  Such locks can be easily
kept in a separate list.  This will restore some of the code
complexity, but is otherwise of little cost.

Linux-commit: 71236833ad7a98b69e6e675efefbdc04a74c1d4b

Change-Id: I6c82d971aabd02bb036ac0bd27a934d48e972895
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/33221
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Yang Sheng <ys@whamcloud.com>
lustre/include/lustre_dlm.h
lustre/ldlm/ldlm_extent.c
lustre/ldlm/ldlm_flock.c
lustre/ldlm/ldlm_internal.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_lockd.c
lustre/obdclass/interval_tree.c
lustre/ofd/ofd_dlm.c

index 34c6244..ca1b5b6 100644 (file)
@@ -691,13 +691,6 @@ struct ldlm_cb_async_args {
 /** The ldlm_glimpse_work was slab allocated & must be freed accordingly.*/
 #define LDLM_GL_WORK_SLAB_ALLOCATED 0x1
 
-/** Interval node data for each LDLM_EXTENT lock. */
-struct ldlm_interval {
-       struct interval_node    li_node;  /* node for tree management */
-       struct list_head        li_group; /* locks having same policy */
-};
-#define to_ldlm_interval(n) container_of(n, struct ldlm_interval, li_node)
-
 /**
  * Interval tree for extent locks.
  * The interval tree must be accessed under the resource lock.
@@ -819,7 +812,7 @@ struct ldlm_lock {
         * Internal structures per lock type..
         */
        union {
-               struct ldlm_interval    *l_tree_node;
+               struct interval_node    l_tree_node;
                struct ldlm_ibits_node  *l_ibits_node;
        };
        /**
index 9ecafb6..c5835b6 100644 (file)
@@ -345,34 +345,25 @@ struct ldlm_extent_compat_args {
 static enum interval_iter ldlm_extent_compat_cb(struct interval_node *n,
                                                void *data)
 {
+       struct ldlm_lock *lock = container_of(n, struct ldlm_lock, l_tree_node);
        struct ldlm_extent_compat_args *priv = data;
-       struct ldlm_interval *node = to_ldlm_interval(n);
-       struct ldlm_extent *extent;
        struct list_head *work_list = priv->work_list;
-       struct ldlm_lock *lock, *enq = priv->lock;
+       struct ldlm_lock *enq = priv->lock;
        enum ldlm_mode mode = priv->mode;
-       int count = 0;
 
        ENTRY;
-
-       LASSERT(!list_empty(&node->li_group));
-
-       list_for_each_entry(lock, &node->li_group, l_sl_policy) {
-               /* interval tree is for granted lock */
-               LASSERTF(mode == lock->l_granted_mode,
-                        "mode = %s, lock->l_granted_mode = %s\n",
-                        ldlm_lockname[mode],
-                        ldlm_lockname[lock->l_granted_mode]);
-               count++;
-               if (lock->l_blocking_ast && lock->l_granted_mode != LCK_GROUP)
-                       ldlm_add_ast_work_item(lock, enq, work_list);
-       }
+       /* interval tree is for granted lock */
+       LASSERTF(mode == lock->l_granted_mode,
+                "mode = %s, lock->l_granted_mode = %s\n",
+                ldlm_lockname[mode],
+                ldlm_lockname[lock->l_granted_mode]);
+       if (lock->l_blocking_ast && lock->l_granted_mode != LCK_GROUP)
+               ldlm_add_ast_work_item(lock, enq, work_list);
 
        /* don't count conflicting glimpse locks */
-       extent = ldlm_interval_extent(node);
-       if (!(mode == LCK_PR && extent->start == 0 &&
-           extent->end == OBD_OBJECT_EOF))
-               *priv->locks += count;
+       if (!(mode == LCK_PR && lock->l_policy_data.l_extent.start == 0 &&
+             lock->l_policy_data.l_extent.end == OBD_OBJECT_EOF))
+               *priv->locks += 1;
 
        if (priv->compat)
                *priv->compat = 0;
@@ -429,18 +420,19 @@ ldlm_extent_compat_queue(struct list_head *queue, struct ldlm_lock *req,
 
                        data.mode = tree->lit_mode;
                        if (lockmode_compat(req_mode, tree->lit_mode)) {
-                               struct ldlm_interval *node;
-                               struct ldlm_extent *extent;
+                               struct ldlm_lock *lock;
 
                                if (req_mode != LCK_GROUP)
                                        continue;
 
-                               /* group lock,grant it immediately if
-                                * compatible */
-                               node = to_ldlm_interval(tree->lit_root);
-                               extent = ldlm_interval_extent(node);
+                               /* group lock, grant it immediately if
+                                * compatible
+                                */
+                               lock = container_of(tree->lit_root,
+                                                   struct ldlm_lock,
+                                                   l_tree_node);
                                if (req->l_policy_data.l_extent.gid ==
-                                   extent->gid)
+                                   lock->l_policy_data.l_extent.gid)
                                        RETURN(2);
                        }
 
@@ -697,18 +689,11 @@ EXPORT_SYMBOL(ldlm_lock_prolong_one);
 static enum interval_iter ldlm_resource_prolong_cb(struct interval_node *n,
                                                   void *data)
 {
+       struct ldlm_lock *lock = container_of(n, struct ldlm_lock, l_tree_node);
        struct ldlm_prolong_args *arg = data;
-       struct ldlm_interval *node = to_ldlm_interval(n);
-       struct ldlm_lock *lock;
 
        ENTRY;
-
-       LASSERT(!list_empty(&node->li_group));
-
-       list_for_each_entry(lock, &node->li_group, l_sl_policy) {
-               ldlm_lock_prolong_one(lock, arg);
-       }
-
+       ldlm_lock_prolong_one(lock, arg);
        RETURN(INTERVAL_ITER_CONT);
 }
 
@@ -850,31 +835,20 @@ struct ldlm_kms_shift_args {
 static enum interval_iter ldlm_kms_shift_cb(struct interval_node *n,
                                            void *args)
 {
+       struct ldlm_lock *lock = container_of(n, struct ldlm_lock, l_tree_node);
        struct ldlm_kms_shift_args *arg = args;
-       struct ldlm_interval *node = to_ldlm_interval(n);
-       struct ldlm_lock *tmplock;
-       struct ldlm_lock *lock = NULL;
 
        ENTRY;
-
        /* Since all locks in an interval have the same extent, we can just
-        * use the first lock without kms_ignore set. */
-       list_for_each_entry(tmplock, &node->li_group, l_sl_policy) {
-               if (ldlm_is_kms_ignore(tmplock))
-                       continue;
-
-               lock = tmplock;
-
-               break;
-       }
-
-       /* No locks in this interval without kms_ignore set */
-       if (!lock)
+        * use the lock without kms_ignore set.
+        */
+       if (ldlm_is_kms_ignore(lock))
                RETURN(INTERVAL_ITER_CONT);
 
        /* If we find a lock with a greater or equal kms, we are not the
         * highest lock (or we share that distinction with another lock), and
-        * don't need to update KMS.  Return old_kms and stop looking. */
+        * don't need to update KMS.  Return old_kms and stop looking.
+        */
        if (lock->l_policy_data.l_extent.end == OBD_OBJECT_EOF ||
        lock->l_policy_data.l_extent.end + 1 >= arg->old_kms) {
                arg->kms = arg->old_kms;
@@ -951,59 +925,6 @@ __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms)
 }
 EXPORT_SYMBOL(ldlm_extent_shift_kms);
 
-struct kmem_cache *ldlm_interval_slab;
-static struct ldlm_interval *ldlm_interval_alloc(struct ldlm_lock *lock)
-{
-       struct ldlm_interval *node;
-
-       ENTRY;
-
-       LASSERT(lock->l_resource->lr_type == LDLM_EXTENT ||
-               lock->l_resource->lr_type == LDLM_FLOCK);
-       OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS);
-       if (node == NULL)
-               RETURN(NULL);
-
-       INIT_LIST_HEAD(&node->li_group);
-       ldlm_interval_attach(node, lock);
-       RETURN(node);
-}
-
-void ldlm_interval_free(struct ldlm_interval *node)
-{
-       if (node) {
-               LASSERT(list_empty(&node->li_group));
-               LASSERT(!interval_is_intree(&node->li_node));
-               OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node));
-       }
-}
-
-/* interval tree, for LDLM_EXTENT. */
-void ldlm_interval_attach(struct ldlm_interval *n,
-                         struct ldlm_lock *l)
-{
-       LASSERT(l->l_tree_node == NULL);
-       LASSERT(l->l_resource->lr_type == LDLM_EXTENT ||
-               l->l_resource->lr_type == LDLM_FLOCK);
-
-       list_add_tail(&l->l_sl_policy, &n->li_group);
-       l->l_tree_node = n;
-}
-
-struct ldlm_interval *ldlm_interval_detach(struct ldlm_lock *l)
-{
-       struct ldlm_interval *n = l->l_tree_node;
-
-       if (n == NULL)
-               return NULL;
-
-       LASSERT(!list_empty(&n->li_group));
-       l->l_tree_node = NULL;
-       list_del_init(&l->l_sl_policy);
-
-       return list_empty(&n->li_group) ? n : NULL;
-}
-
 static inline int ldlm_mode_to_index(enum ldlm_mode mode)
 {
        int index;
@@ -1015,29 +936,17 @@ static inline int ldlm_mode_to_index(enum ldlm_mode mode)
        return index;
 }
 
-int ldlm_extent_alloc_lock(struct ldlm_lock *lock)
-{
-       lock->l_tree_node = NULL;
-
-       if (ldlm_interval_alloc(lock) == NULL)
-               return -ENOMEM;
-       return 0;
-}
-
 /** Add newly granted lock into interval tree for the resource. */
 void ldlm_extent_add_lock(struct ldlm_resource *res,
                          struct ldlm_lock *lock)
 {
-       struct interval_node *found, **root;
-       struct ldlm_interval *node;
+       struct interval_node **root;
        struct ldlm_extent *extent;
        int idx, rc;
 
        LASSERT(ldlm_is_granted(lock));
 
-       node = lock->l_tree_node;
-       LASSERT(node != NULL);
-       LASSERT(!interval_is_intree(&node->li_node));
+       LASSERT(!interval_is_intree(&lock->l_tree_node));
 
        idx = ldlm_mode_to_index(lock->l_granted_mode);
        LASSERT(lock->l_granted_mode == BIT(idx));
@@ -1046,18 +955,11 @@ void ldlm_extent_add_lock(struct ldlm_resource *res,
        /* node extent initialize */
        extent = &lock->l_policy_data.l_extent;
 
-       rc = interval_set(&node->li_node, extent->start, extent->end);
+       rc = interval_set(&lock->l_tree_node, extent->start, extent->end);
        LASSERT(!rc);
 
        root = &res->lr_itree[idx].lit_root;
-       found = interval_insert(&node->li_node, root);
-       if (found) { /* The policy group found. */
-               struct ldlm_interval *tmp = ldlm_interval_detach(lock);
-
-               LASSERT(tmp != NULL);
-               ldlm_interval_free(tmp);
-               ldlm_interval_attach(to_ldlm_interval(found), lock);
-       }
+       interval_insert(&lock->l_tree_node, root);
        res->lr_itree[idx].lit_size++;
 
        /* even though we use interval tree to manage the extent lock, we also
@@ -1090,11 +992,10 @@ void ldlm_extent_add_lock(struct ldlm_resource *res,
 void ldlm_extent_unlink_lock(struct ldlm_lock *lock)
 {
        struct ldlm_resource *res = lock->l_resource;
-       struct ldlm_interval *node = lock->l_tree_node;
        struct ldlm_interval_tree *tree;
        int idx;
 
-       if (!node || !interval_is_intree(&node->li_node)) /* duplicate unlink */
+       if (!interval_is_intree(&lock->l_tree_node)) /* duplicate unlink */
                return;
 
        idx = ldlm_mode_to_index(lock->l_granted_mode);
@@ -1104,11 +1005,7 @@ void ldlm_extent_unlink_lock(struct ldlm_lock *lock)
        LASSERT(tree->lit_root != NULL); /* assure the tree is not null */
 
        tree->lit_size--;
-       node = ldlm_interval_detach(lock);
-       if (node) {
-               interval_erase(&node->li_node, &tree->lit_root);
-               ldlm_interval_free(node);
-       }
+       interval_erase(&lock->l_tree_node, &tree->lit_root);
 }
 
 void ldlm_extent_policy_wire_to_local(const union ldlm_wire_policy_data *wpolicy,
index 4a1df40..e4568cf 100644 (file)
@@ -120,18 +120,12 @@ static inline void ldlm_flock_blocking_unlink(struct ldlm_lock *req)
 void ldlm_flock_unlink_lock(struct ldlm_lock *lock)
 {
        struct ldlm_resource *res = lock->l_resource;
-       struct ldlm_interval *node = lock->l_tree_node;
+       struct interval_node **root = &res->lr_flock_node.lfn_root;
 
-       if (!node || !interval_is_intree(&node->li_node)) /* duplicate unlink */
+       if (!interval_is_intree(&lock->l_tree_node)) /* duplicate unlink */
                return;
 
-       node = ldlm_interval_detach(lock);
-       if (node) {
-               struct interval_node **root = &res->lr_flock_node.lfn_root;
-
-               interval_erase(&node->li_node, root);
-               ldlm_interval_free(node);
-       }
+       interval_erase(&lock->l_tree_node, root);
 }
 
 static inline void
@@ -286,28 +280,19 @@ static void ldlm_flock_add_lock(struct ldlm_resource *res,
                                struct list_head *head,
                                struct ldlm_lock *lock)
 {
-       struct interval_node *found, **root;
-       struct ldlm_interval *node = lock->l_tree_node;
+       struct interval_node **root;
        struct ldlm_extent *extent = &lock->l_policy_data.l_extent;
        int rc;
 
        LASSERT(ldlm_is_granted(lock));
 
-       LASSERT(node != NULL);
-       LASSERT(!interval_is_intree(&node->li_node));
+       LASSERT(!interval_is_intree(&lock->l_tree_node));
 
-       rc = interval_set(&node->li_node, extent->start, extent->end);
+       rc = interval_set(&lock->l_tree_node, extent->start, extent->end);
        LASSERT(!rc);
 
        root = &res->lr_flock_node.lfn_root;
-       found = interval_insert(&node->li_node, root);
-       if (found) { /* The same extent found. */
-               struct ldlm_interval *tmp = ldlm_interval_detach(lock);
-
-               LASSERT(tmp != NULL);
-               ldlm_interval_free(tmp);
-               ldlm_interval_attach(to_ldlm_interval(found), lock);
-       }
+       interval_insert(&lock->l_tree_node, root);
 
        /* Add the locks into list */
        ldlm_resource_add_lock(res, head, lock);
@@ -317,25 +302,13 @@ static void
 ldlm_flock_range_update(struct ldlm_lock *lock, struct ldlm_lock *req)
 {
        struct ldlm_resource *res = lock->l_resource;
-       struct interval_node *found, **root = &res->lr_flock_node.lfn_root;
-       struct ldlm_interval *node;
+       struct interval_node **root = &res->lr_flock_node.lfn_root;
        struct ldlm_extent *extent = &lock->l_policy_data.l_extent;
 
-       node = ldlm_interval_detach(lock);
-       if (!node) {
-               node = ldlm_interval_detach(req);
-               LASSERT(node);
-       } else {
-               interval_erase(&node->li_node, root);
-       }
-       interval_set(&node->li_node, extent->start, extent->end);
+       interval_erase(&lock->l_tree_node, root);
+       interval_set(&lock->l_tree_node, extent->start, extent->end);
+       interval_insert(&lock->l_tree_node, root);
 
-       found = interval_insert(&node->li_node, root);
-       if (found) { /* The policy group found. */
-               ldlm_interval_free(node);
-               node = to_ldlm_interval(found);
-       }
-       ldlm_interval_attach(node, lock);
        EXIT;
 }
 
index 1234f72..6398dc1 100644 (file)
@@ -202,7 +202,6 @@ int ldlm_process_extent_lock(struct ldlm_lock *lock, __u64 *flags,
                             enum ldlm_process_intention intention,
                             enum ldlm_error *err, struct list_head *work_list);
 #endif
-int ldlm_extent_alloc_lock(struct ldlm_lock *lock);
 void ldlm_extent_add_lock(struct ldlm_resource *res, struct ldlm_lock *lock);
 void ldlm_extent_unlink_lock(struct ldlm_lock *lock);
 
@@ -232,24 +231,6 @@ struct ldlm_state {
        struct ldlm_bl_pool *ldlm_bl_pool;
 };
 
-/* interval tree, for LDLM_EXTENT. */
-extern struct kmem_cache *ldlm_interval_slab; /* slab cache for ldlm_interval */
-extern void ldlm_interval_attach(struct ldlm_interval *n, struct ldlm_lock *l);
-extern struct ldlm_interval *ldlm_interval_detach(struct ldlm_lock *l);
-extern void ldlm_interval_free(struct ldlm_interval *node);
-/* this function must be called with res lock held */
-static inline struct ldlm_extent *
-ldlm_interval_extent(struct ldlm_interval *node)
-{
-       struct ldlm_lock *lock;
-
-       LASSERT(!list_empty(&node->li_group));
-
-       lock = list_first_entry(&node->li_group, struct ldlm_lock,
-                               l_sl_policy);
-       return &lock->l_policy_data.l_extent;
-}
-
 int ldlm_init(void);
 void ldlm_exit(void);
 
index c41a2f1..1a30ab8 100644 (file)
@@ -231,12 +231,9 @@ void ldlm_lock_put(struct ldlm_lock *lock)
                if (lock->l_lvb_data != NULL)
                        OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len);
 
-               if (res->lr_type == LDLM_EXTENT || res->lr_type == LDLM_FLOCK) {
-                       ldlm_interval_free(ldlm_interval_detach(lock));
-               } else if (res->lr_type == LDLM_IBITS) {
-                       if (lock->l_ibits_node != NULL)
-                               OBD_SLAB_FREE_PTR(lock->l_ibits_node,
-                                                 ldlm_inodebits_slab);
+               if (res->lr_type == LDLM_IBITS && lock->l_ibits_node) {
+                       OBD_SLAB_FREE_PTR(lock->l_ibits_node,
+                                         ldlm_inodebits_slab);
                }
                ldlm_resource_putref(res);
                lock->l_resource = NULL;
@@ -510,9 +507,6 @@ struct ldlm_lock *ldlm_lock_new_testing(struct ldlm_resource *resource)
                return NULL;
        lock->l_flags |= BIT(63);
        switch (resource->lr_type) {
-       case LDLM_EXTENT:
-               rc = ldlm_extent_alloc_lock(lock);
-               break;
        case LDLM_IBITS:
                rc = ldlm_inodebits_alloc_lock(lock);
                break;
@@ -1291,15 +1285,12 @@ matched:
 
 static unsigned int itree_overlap_cb(struct interval_node *in, void *args)
 {
-       struct ldlm_interval *node = to_ldlm_interval(in);
+       struct ldlm_lock *lock = container_of(in, struct ldlm_lock,
+                                             l_tree_node);
        struct ldlm_match_data *data = args;
-       struct ldlm_lock *lock;
 
-       list_for_each_entry(lock, &node->li_group, l_sl_policy) {
-               if (lock_matches(lock, data))
-                       return INTERVAL_ITER_STOP;
-       }
-       return INTERVAL_ITER_CONT;
+       return lock_matches(lock, data) ?
+               INTERVAL_ITER_STOP : INTERVAL_ITER_CONT;
 }
 
 /**
@@ -1714,7 +1705,7 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
 {
        struct ldlm_lock        *lock;
        struct ldlm_resource    *res;
-       int                     rc;
+       int rc = 0;
 
        ENTRY;
 
@@ -1739,19 +1730,11 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
                lock->l_glimpse_ast = cbs->lcs_glimpse;
        }
 
-       switch (type) {
-       case LDLM_EXTENT:
-       case LDLM_FLOCK:
-               rc = ldlm_extent_alloc_lock(lock);
-               break;
-       case LDLM_IBITS:
+       if (type == LDLM_IBITS) {
                rc = ldlm_inodebits_alloc_lock(lock);
-               break;
-       default:
-               rc = 0;
+               if (rc)
+                       GOTO(out, rc);
        }
-       if (rc)
-               GOTO(out, rc);
 
        if (lvb_len) {
                lock->l_lvb_len = lvb_len;
@@ -1815,7 +1798,6 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env,
        struct ldlm_resource *res;
        int local = ns_is_client(ns);
        enum ldlm_error rc = ELDLM_OK;
-       struct ldlm_interval *node = NULL;
 #ifdef HAVE_SERVER_SUPPORT
        bool reconstruct = false;
 #endif
@@ -1871,19 +1853,6 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env,
        }
 
 #ifdef HAVE_SERVER_SUPPORT
-       /* For a replaying lock, it might be already in granted list. So
-        * unlinking the lock will cause the interval node to be freed, we
-        * have to allocate the interval node early otherwise we can't regrant
-        * this lock in the future. - jay
-        *
-        * The only time the ldlm_resource changes for the ldlm_lock is when
-        * ldlm_lock_change_resource() is called and that only happens for
-        * the Lustre client case.
-        */
-       if (!local && (*flags & LDLM_FL_REPLAY) &&
-           lock->l_resource->lr_type == LDLM_EXTENT)
-               OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS);
-
        reconstruct = !local && lock->l_resource->lr_type == LDLM_FLOCK &&
                      !(*flags & LDLM_FL_TEST_LOCK);
        if (reconstruct) {
@@ -1926,16 +1895,6 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env,
        }
 
        ldlm_resource_unlink_lock(lock);
-       if (res->lr_type == LDLM_EXTENT && lock->l_tree_node == NULL) {
-               if (node == NULL) {
-                       ldlm_lock_destroy_nolock(lock);
-                       GOTO(out, rc = -ENOMEM);
-               }
-
-               INIT_LIST_HEAD(&node->li_group);
-               ldlm_interval_attach(node, lock);
-               node = NULL;
-       }
 
        /* Some flags from the enqueue want to make it into the AST, via the
         * lock's l_flags.
@@ -1996,8 +1955,6 @@ out:
                                  req, 0, NULL, false, 0);
        }
 #endif
-       if (node)
-               OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node));
        return rc;
 }
 
index c4e553c..d7a1944 100644 (file)
@@ -3528,17 +3528,11 @@ int ldlm_init(void)
        if (ldlm_lock_slab == NULL)
                goto out_resource;
 
-       ldlm_interval_slab = kmem_cache_create("interval_node",
-                                       sizeof(struct ldlm_interval),
-                                       0, SLAB_HWCACHE_ALIGN, NULL);
-       if (ldlm_interval_slab == NULL)
-               goto out_lock;
-
        ldlm_interval_tree_slab = kmem_cache_create("interval_tree",
                        sizeof(struct ldlm_interval_tree) * LCK_MODE_NUM,
                        0, SLAB_HWCACHE_ALIGN, NULL);
        if (ldlm_interval_tree_slab == NULL)
-               goto out_interval;
+               goto out_lock_slab;
 
 #ifdef HAVE_SERVER_SUPPORT
        ldlm_inodebits_slab = kmem_cache_create("ldlm_ibits_node",
@@ -3564,9 +3558,7 @@ out_inodebits:
 out_interval_tree:
        kmem_cache_destroy(ldlm_interval_tree_slab);
 #endif
-out_interval:
-       kmem_cache_destroy(ldlm_interval_slab);
-out_lock:
+out_lock_slab:
        kmem_cache_destroy(ldlm_lock_slab);
 out_resource:
        kmem_cache_destroy(ldlm_resource_slab);
@@ -3587,7 +3579,6 @@ void ldlm_exit(void)
         */
        rcu_barrier();
        kmem_cache_destroy(ldlm_lock_slab);
-       kmem_cache_destroy(ldlm_interval_slab);
        kmem_cache_destroy(ldlm_interval_tree_slab);
 #ifdef HAVE_SERVER_SUPPORT
        kmem_cache_destroy(ldlm_inodebits_slab);
index 6007d37..aa79775 100644 (file)
@@ -105,11 +105,6 @@ static inline int node_compare(struct interval_node *n1,
        return extent_compare(&n1->in_extent, &n2->in_extent);
 }
 
-int node_equal(struct interval_node *n1, struct interval_node *n2)
-{
-       return extent_equal(&n1->in_extent, &n2->in_extent);
-}
-
 #define interval_for_each(node, root)                   \
 for (node = interval_first(root); node != NULL;         \
        node = interval_next(node))
@@ -383,8 +378,6 @@ struct interval_node *interval_insert(struct interval_node *node,
        p = root;
         while (*p) {
                 parent = *p;
-                if (node_equal(parent, node))
-                        RETURN(parent);
 
                 /* max_high field must be updated after each iteration */
                 if (parent->in_max_high < interval_high(node))
index baec254..5549aaa 100644 (file)
@@ -104,11 +104,9 @@ struct ofd_intent_args {
  */
 static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
 {
-       struct ldlm_interval     *node = (struct ldlm_interval *)n;
-       struct ofd_intent_args   *arg = args;
-       __u64                     size = arg->size;
-       struct ldlm_lock         *victim_lock = NULL;
-       struct ldlm_lock         *lck;
+       struct ldlm_lock *lock = container_of(n, struct ldlm_lock, l_tree_node);
+       struct ofd_intent_args *arg = args;
+       __u64 size = arg->size;
        struct ldlm_glimpse_work *gl_work = NULL;
        int rc = 0;
 
@@ -116,20 +114,6 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
        if (interval_high(n) <= size)
                GOTO(out, rc = INTERVAL_ITER_STOP);
 
-       /* Find the 'victim' lock from this interval */
-       list_for_each_entry(lck, &node->li_group, l_sl_policy) {
-               victim_lock = LDLM_LOCK_GET(lck);
-
-               /* the same policy group - every lock has the
-                * same extent, so needn't do it any more */
-               break;
-       }
-
-       /* l_export can be null in race with eviction - In that case, we will
-        * not find any locks in this interval */
-       if (!victim_lock)
-               GOTO(out, rc = INTERVAL_ITER_CONT);
-
        /*
         * This check is for lock taken in ofd_destroy_by_fid() that does
         * not have l_glimpse_ast set. So the logic is: if there is a lock
@@ -137,16 +121,17 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
         * Hence, if you are grabbing DLM locks on the server, always set
         * non-NULL glimpse_ast (e.g., ldlm_request.c::ldlm_glimpse_ast()).
         */
-       if (victim_lock->l_glimpse_ast == NULL) {
-               LDLM_DEBUG(victim_lock, "no l_glimpse_ast");
+       if (lock->l_glimpse_ast == NULL) {
+               LDLM_DEBUG(lock, "no l_glimpse_ast");
                arg->no_glimpse_ast = true;
-               GOTO(out_release, rc = INTERVAL_ITER_STOP);
+               GOTO(out, rc = INTERVAL_ITER_STOP);
        }
 
        /* If NO_EXPANSION is not set, this is an active lock, and we don't need
         * to glimpse any further once we've glimpsed the client holding this
-        * lock.  So set us up to stop.  See comment above this function. */
-       if (!(victim_lock->l_flags & LDLM_FL_NO_EXPANSION))
+        * lock.  So set us up to stop.  See comment above this function.
+        */
+       if (!(lock->l_flags & LDLM_FL_NO_EXPANSION))
                rc = INTERVAL_ITER_STOP;
        else
                rc = INTERVAL_ITER_CONT;
@@ -155,10 +140,11 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
         * client; if so, don't add this lock to the glimpse list - We need
         * only glimpse each client once. (And if we know that client holds
         * an active lock, we can stop glimpsing.  So keep the rc set in the
-        * check above.) */
+        * check above.)
+        */
        list_for_each_entry(gl_work, &arg->gl_list, gl_list) {
-               if (gl_work->gl_lock->l_export == victim_lock->l_export)
-                       GOTO(out_release, rc);
+               if (gl_work->gl_lock->l_export == lock->l_export)
+                       GOTO(out, rc);
        }
 
        if (!CFS_FAIL_CHECK(OBD_FAIL_OST_GL_WORK_ALLOC))
@@ -167,25 +153,22 @@ static enum interval_iter ofd_intent_cb(struct interval_node *n, void *args)
 
        if (!gl_work) {
                arg->error = -ENOMEM;
-               GOTO(out_release, rc = INTERVAL_ITER_STOP);
+               GOTO(out, rc = INTERVAL_ITER_STOP);
        }
 
        /* Populate the gl_work structure. */
-       gl_work->gl_lock = victim_lock;
+       gl_work->gl_lock = LDLM_LOCK_GET(lock);
        list_add_tail(&gl_work->gl_list, &arg->gl_list);
        /* There is actually no need for a glimpse descriptor when glimpsing
-        * extent locks */
+        * extent locks
+        */
        gl_work->gl_desc = NULL;
        /* This tells ldlm_work_gl_ast_lock this was allocated from a slab and
-        * must be freed in a slab-aware manner. */
+        * must be freed in a slab-aware manner.
+        */
        gl_work->gl_flags = LDLM_GL_WORK_SLAB_ALLOCATED;
 
        GOTO(out, rc);
-
-out_release:
-       /* If the victim doesn't go on the glimpse list, we must release it */
-       LDLM_LOCK_RELEASE(victim_lock);
-
 out:
        return rc;
 }