#define MAPLE_RESERVED_RANGE 4096
struct maple_tree {
- spinlock_t ma_lock;
+ union {
+ spinlock_t ma_lock;
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map *ma_external_lock;
+#endif
+ };
unsigned int ma_flags;
void __rcu *ma_root;
};
.ma_root = NULL, \
}
+#ifdef CONFIG_LOCKDEP
+#define MTREE_INIT_EXT(name, flags, lock) { \
+ .ma_external_lock = &(lock).dep_map, \
+ .ma_flags = flags, \
+ .ma_root = NULL, \
+}
+#else
+#define MTREE_INIT_EXT(name, flags, lock) MTREE_INIT(name, flags)
+#endif
+
#define DEFINE_MTREE(name) \
struct maple_tree name = MTREE_INIT(name, 0)
#define mtree_lock(mt) spin_lock((&(mt)->ma_lock))
#define mtree_unlock(mt) spin_unlock((&(mt)->ma_lock))
+#ifdef CONFIG_LOCKDEP
+#define mt_set_external_lock(mt, lock) \
+ (mt)->ma_external_lock = &(lock)->dep_map;
+#else
+#define mt_set_external_lock(mt, lock) do { } while (0)
+#endif
struct maple_node {
union {
mas_set_range(mas, index, index);
}
+static inline bool mt_external_lock(const struct maple_tree *mt)
+{
+ return (mt->ma_flags & MT_FLAGS_LOCK_MASK) == MT_FLAGS_LOCK_EXTERN;
+}
+
/**
* mt_init_flags() - Initialise an empty maple tree with flags.
* @mt: Maple Tree
* @flags: maple tree flags.
*
- * If you need to initialise a Maple Tree with special falgs (eg, an
+ * If you need to initialise a Maple Tree with special flags (eg, an
* allocation tree), use this function.
*
* Context: Any context.
- *
*/
static inline void mt_init_flags(struct maple_tree *mt, unsigned int flags)
{
- spin_lock_init(&mt->ma_lock);
mt->ma_flags = flags;
- mt->ma_root = NULL;
+ if (mt_external_lock(mt))
+#ifdef CONFIG_LOCKDEP
+ mt->ma_external_lock = NULL;
+#else
+ do { } while (0);
+#endif
+ else
+ spin_lock_init(&mt->ma_lock);
+ rcu_assign_pointer(mt->ma_root, NULL);
}
/**
}
}
-static inline bool mt_external_lock(const struct maple_tree *mt)
-{
- return (mt->ma_flags & MT_FLAGS_LOCK_MASK) == MT_FLAGS_LOCK_EXTERN;
-}
-
static inline bool mt_locked(const struct maple_tree *mt)
{
- return mt_external_lock(mt) || lockdep_is_held(&mt->ma_lock);
+#ifdef CONFIG_LOCKDEP
+ return mt_external_lock(mt) ?
+ lock_is_held(mt->ma_external_lock) :
+ lockdep_is_held(&mt->ma_lock);
+#else
+ return true;
+#endif
}
static inline void *mt_slot(const struct maple_tree *mt,
return slots;
}
+
static void mt_free_walk(struct rcu_head *head)
{
void __rcu **slots;
if (ma_is_leaf(node->type))
goto free_leaf;
- mtree_init(&mt, node->ma_flags);
+ mt_init_flags(&mt, node->ma_flags);
mas_lock(&mas);
start = node;
mas.node = mt_mk_node(node, node->type);
if (mte_is_leaf(enode))
goto free_leaf;
- mtree_init(&mt, ma_flags);
+ mt_init_flags(&mt, ma_flags);
mas_lock(&mas);
mas.node = start = enode;
SLAB_PANIC, NULL);
}
-/*
- * mtree_init() - Initialize a maple tree.
- * @mt: The maple tree
- * @ma_flags: The flags to use for the tree.
- */
-void mtree_init(struct maple_tree *mt, unsigned int ma_flags)
-{
- mt->ma_flags = ma_flags;
- spin_lock_init(&mt->ma_lock);
- rcu_assign_pointer(mt->ma_root, NULL);
-}
-EXPORT_SYMBOL(mtree_init);
-
/*
* mtree_load() - Load a value stored in a maple tree
* @mt: The maple tree