|
@@ -88,6 +88,57 @@ static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
|
|
|
return root->gfp_mask & __GFP_BITS_MASK;
|
|
|
}
|
|
|
|
|
|
+static inline void tag_set(struct radix_tree_node *node, unsigned int tag,
|
|
|
+ int offset)
|
|
|
+{
|
|
|
+ __set_bit(offset, node->tags[tag]);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void tag_clear(struct radix_tree_node *node, unsigned int tag,
|
|
|
+ int offset)
|
|
|
+{
|
|
|
+ __clear_bit(offset, node->tags[tag]);
|
|
|
+}
|
|
|
+
|
|
|
+static inline int tag_get(struct radix_tree_node *node, unsigned int tag,
|
|
|
+ int offset)
|
|
|
+{
|
|
|
+ return test_bit(offset, node->tags[tag]);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag)
|
|
|
+{
|
|
|
+ root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT));
|
|
|
+}
|
|
|
+
|
|
|
+static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag)
|
|
|
+{
|
|
|
+ root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT));
|
|
|
+}
|
|
|
+
|
|
|
+static inline void root_tag_clear_all(struct radix_tree_root *root)
|
|
|
+{
|
|
|
+ root->gfp_mask &= __GFP_BITS_MASK;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag)
|
|
|
+{
|
|
|
+ return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT));
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Returns 1 if any slot in the node has this tag set.
|
|
|
+ * Otherwise returns 0.
|
|
|
+ */
|
|
|
+static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag)
|
|
|
+{
|
|
|
+ int idx;
|
|
|
+ for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
|
|
|
+ if (node->tags[tag][idx])
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
/*
|
|
|
* This assumes that the caller has performed appropriate preallocation, and
|
|
|
* that the caller has pinned this thread of control to the current CPU.
|
|
@@ -124,6 +175,17 @@ static void radix_tree_node_rcu_free(struct rcu_head *head)
|
|
|
{
|
|
|
struct radix_tree_node *node =
|
|
|
container_of(head, struct radix_tree_node, rcu_head);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * must only free zeroed nodes into the slab. radix_tree_shrink
|
|
|
+ * can leave us with a non-NULL entry in the first slot, so clear
|
|
|
+ * that here to make sure.
|
|
|
+ */
|
|
|
+ tag_clear(node, 0, 0);
|
|
|
+ tag_clear(node, 1, 0);
|
|
|
+ node->slots[0] = NULL;
|
|
|
+ node->count = 0;
|
|
|
+
|
|
|
kmem_cache_free(radix_tree_node_cachep, node);
|
|
|
}
|
|
|
|
|
@@ -165,59 +227,6 @@ out:
|
|
|
}
|
|
|
EXPORT_SYMBOL(radix_tree_preload);
|
|
|
|
|
|
-static inline void tag_set(struct radix_tree_node *node, unsigned int tag,
|
|
|
- int offset)
|
|
|
-{
|
|
|
- __set_bit(offset, node->tags[tag]);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void tag_clear(struct radix_tree_node *node, unsigned int tag,
|
|
|
- int offset)
|
|
|
-{
|
|
|
- __clear_bit(offset, node->tags[tag]);
|
|
|
-}
|
|
|
-
|
|
|
-static inline int tag_get(struct radix_tree_node *node, unsigned int tag,
|
|
|
- int offset)
|
|
|
-{
|
|
|
- return test_bit(offset, node->tags[tag]);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag)
|
|
|
-{
|
|
|
- root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT));
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag)
|
|
|
-{
|
|
|
- root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT));
|
|
|
-}
|
|
|
-
|
|
|
-static inline void root_tag_clear_all(struct radix_tree_root *root)
|
|
|
-{
|
|
|
- root->gfp_mask &= __GFP_BITS_MASK;
|
|
|
-}
|
|
|
-
|
|
|
-static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag)
|
|
|
-{
|
|
|
- return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT));
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Returns 1 if any slot in the node has this tag set.
|
|
|
- * Otherwise returns 0.
|
|
|
- */
|
|
|
-static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag)
|
|
|
-{
|
|
|
- int idx;
|
|
|
- for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
|
|
|
- if (node->tags[tag][idx])
|
|
|
- return 1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Return the maximum key which can be store into a
|
|
|
* radix tree with height HEIGHT.
|
|
@@ -930,11 +939,6 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
|
|
|
newptr = radix_tree_ptr_to_indirect(newptr);
|
|
|
root->rnode = newptr;
|
|
|
root->height--;
|
|
|
- /* must only free zeroed nodes into the slab */
|
|
|
- tag_clear(to_free, 0, 0);
|
|
|
- tag_clear(to_free, 1, 0);
|
|
|
- to_free->slots[0] = NULL;
|
|
|
- to_free->count = 0;
|
|
|
radix_tree_node_free(to_free);
|
|
|
}
|
|
|
}
|