Skip to content

Commit 139e561

Browse files
hnaztorvalds
authored andcommitted
lib: radix_tree: tree node interface
Make struct radix_tree_node part of the public interface and provide API functions to create, look up, and delete whole nodes. Refactor the existing insert, look up, delete functions on top of these new node primitives. This will allow the VM to track and garbage collect page cache radix tree nodes. [[email protected]: return correct error code on insertion failure] Signed-off-by: Johannes Weiner <[email protected]> Reviewed-by: Rik van Riel <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Bob Liu <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Greg Thelen <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Jan Kara <[email protected]> Cc: KOSAKI Motohiro <[email protected]> Cc: Luigi Semenzato <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Metin Doslu <[email protected]> Cc: Michel Lespinasse <[email protected]> Cc: Ozgun Erdogan <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Ryan Mallon <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a528910 commit 139e561

File tree

2 files changed

+182
-115
lines changed

2 files changed

+182
-115
lines changed

include/linux/radix-tree.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,33 @@ static inline int radix_tree_is_indirect_ptr(void *ptr)
6060

6161
#define RADIX_TREE_MAX_TAGS 3
6262

63+
#ifdef __KERNEL__
64+
#define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6)
65+
#else
66+
#define RADIX_TREE_MAP_SHIFT 3 /* For more stressful testing */
67+
#endif
68+
69+
#define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
70+
#define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1)
71+
72+
#define RADIX_TREE_TAG_LONGS \
73+
((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG)
74+
75+
struct radix_tree_node {
76+
unsigned int height; /* Height from the bottom */
77+
unsigned int count;
78+
union {
79+
struct radix_tree_node *parent; /* Used when ascending tree */
80+
struct rcu_head rcu_head; /* Used when freeing node */
81+
};
82+
void __rcu *slots[RADIX_TREE_MAP_SIZE];
83+
unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
84+
};
85+
86+
#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
87+
#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \
88+
RADIX_TREE_MAP_SHIFT))
89+
6390
/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */
6491
struct radix_tree_root {
6592
unsigned int height;
@@ -101,6 +128,7 @@ do { \
101128
* concurrently with other readers.
102129
*
103130
* The notable exceptions to this rule are the following functions:
131+
* __radix_tree_lookup
104132
* radix_tree_lookup
105133
* radix_tree_lookup_slot
106134
* radix_tree_tag_get
@@ -216,9 +244,15 @@ static inline void radix_tree_replace_slot(void **pslot, void *item)
216244
rcu_assign_pointer(*pslot, item);
217245
}
218246

247+
int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
248+
struct radix_tree_node **nodep, void ***slotp);
219249
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
250+
void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
251+
struct radix_tree_node **nodep, void ***slotp);
220252
void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
221253
void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
254+
bool __radix_tree_delete_node(struct radix_tree_root *root, unsigned long index,
255+
struct radix_tree_node *node);
222256
void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
223257
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
224258
unsigned int

0 commit comments

Comments
 (0)