Skip to content

Commit 01959df

Browse files
author
Matthew Wilcox
committed
xarray: Define struct xa_node
This is a direct replacement for struct radix_tree_node. A couple of struct members have changed name, so convert those. Use a #define so that radix tree users continue to work without change. Signed-off-by: Matthew Wilcox <willy@infradead.org> Reviewed-by: Josef Bacik <jbacik@fb.com>
1 parent f8d5d0c commit 01959df

File tree

5 files changed

+77
-73
lines changed

5 files changed

+77
-73
lines changed

include/linux/radix-tree.h

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
/* Keep unconverted code working */
3434
#define radix_tree_root xarray
35+
#define radix_tree_node xa_node
3536

3637
/*
3738
* The bottom two bits of the slot determine how the remaining bits in the
@@ -60,41 +61,17 @@ static inline bool radix_tree_is_internal_node(void *ptr)
6061

6162
/*** radix-tree API starts here ***/
6263

63-
#define RADIX_TREE_MAX_TAGS 3
64-
6564
#define RADIX_TREE_MAP_SHIFT XA_CHUNK_SHIFT
6665
#define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT)
6766
#define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1)
6867

69-
#define RADIX_TREE_TAG_LONGS \
70-
((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG)
68+
#define RADIX_TREE_MAX_TAGS XA_MAX_MARKS
69+
#define RADIX_TREE_TAG_LONGS XA_MARK_LONGS
7170

7271
#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
7372
#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \
7473
RADIX_TREE_MAP_SHIFT))
7574

76-
/*
77-
* @count is the count of every non-NULL element in the ->slots array
78-
* whether that is a value entry, a retry entry, a user pointer,
79-
* a sibling entry or a pointer to the next level of the tree.
80-
* @exceptional is the count of every element in ->slots which is
81-
* either a value entry or a sibling of a value entry.
82-
*/
83-
struct radix_tree_node {
84-
unsigned char shift; /* Bits remaining in each slot */
85-
unsigned char offset; /* Slot offset in parent */
86-
unsigned char count; /* Total entry count */
87-
unsigned char exceptional; /* Exceptional entry count */
88-
struct radix_tree_node *parent; /* Used when ascending tree */
89-
struct radix_tree_root *root; /* The tree we belong to */
90-
union {
91-
struct list_head private_list; /* For tree user */
92-
struct rcu_head rcu_head; /* Used when freeing node */
93-
};
94-
void __rcu *slots[RADIX_TREE_MAP_SIZE];
95-
unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
96-
};
97-
9875
/* The IDR tag is stored in the low bits of xa_flags */
9976
#define ROOT_IS_IDR ((__force gfp_t)4)
10077
/* The top bits of xa_flags are used to store the root tags */

include/linux/xarray.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,33 @@ static inline void xa_init(struct xarray *xa)
252252
#endif
253253
#define XA_CHUNK_SIZE (1UL << XA_CHUNK_SHIFT)
254254
#define XA_CHUNK_MASK (XA_CHUNK_SIZE - 1)
255+
#define XA_MAX_MARKS 3
256+
#define XA_MARK_LONGS DIV_ROUND_UP(XA_CHUNK_SIZE, BITS_PER_LONG)
257+
258+
/*
259+
* @count is the count of every non-NULL element in the ->slots array
260+
* whether that is a value entry, a retry entry, a user pointer,
261+
* a sibling entry or a pointer to the next level of the tree.
262+
* @nr_values is the count of every element in ->slots which is
263+
* either a value entry or a sibling of a value entry.
264+
*/
265+
struct xa_node {
266+
unsigned char shift; /* Bits remaining in each slot */
267+
unsigned char offset; /* Slot offset in parent */
268+
unsigned char count; /* Total entry count */
269+
unsigned char nr_values; /* Value entry count */
270+
struct xa_node __rcu *parent; /* NULL at top of tree */
271+
struct xarray *array; /* The array we belong to */
272+
union {
273+
struct list_head private_list; /* For tree user */
274+
struct rcu_head rcu_head; /* Used when freeing node */
275+
};
276+
void __rcu *slots[XA_CHUNK_SIZE];
277+
union {
278+
unsigned long tags[XA_MAX_MARKS][XA_MARK_LONGS];
279+
unsigned long marks[XA_MAX_MARKS][XA_MARK_LONGS];
280+
};
281+
};
255282

256283
/* Private */
257284
static inline bool xa_is_node(const void *entry)

lib/radix-tree.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,11 @@ static void dump_node(struct radix_tree_node *node, unsigned long index)
260260
{
261261
unsigned long i;
262262

263-
pr_debug("radix node: %p offset %d indices %lu-%lu parent %p tags %lx %lx %lx shift %d count %d exceptional %d\n",
263+
pr_debug("radix node: %p offset %d indices %lu-%lu parent %p tags %lx %lx %lx shift %d count %d nr_values %d\n",
264264
node, node->offset, index, index | node_maxindex(node),
265265
node->parent,
266266
node->tags[0][0], node->tags[1][0], node->tags[2][0],
267-
node->shift, node->count, node->exceptional);
267+
node->shift, node->count, node->nr_values);
268268

269269
for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
270270
unsigned long first = index | (i << node->shift);
@@ -354,7 +354,7 @@ static struct radix_tree_node *
354354
radix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent,
355355
struct radix_tree_root *root,
356356
unsigned int shift, unsigned int offset,
357-
unsigned int count, unsigned int exceptional)
357+
unsigned int count, unsigned int nr_values)
358358
{
359359
struct radix_tree_node *ret = NULL;
360360

@@ -401,9 +401,9 @@ radix_tree_node_alloc(gfp_t gfp_mask, struct radix_tree_node *parent,
401401
ret->shift = shift;
402402
ret->offset = offset;
403403
ret->count = count;
404-
ret->exceptional = exceptional;
404+
ret->nr_values = nr_values;
405405
ret->parent = parent;
406-
ret->root = root;
406+
ret->array = root;
407407
}
408408
return ret;
409409
}
@@ -633,8 +633,8 @@ static int radix_tree_extend(struct radix_tree_root *root, gfp_t gfp,
633633
if (radix_tree_is_internal_node(entry)) {
634634
entry_to_node(entry)->parent = node;
635635
} else if (xa_is_value(entry)) {
636-
/* Moving an exceptional root->xa_head to a node */
637-
node->exceptional = 1;
636+
/* Moving a value entry root->xa_head to a node */
637+
node->nr_values = 1;
638638
}
639639
/*
640640
* entry was already in the radix tree, so we do not need
@@ -928,12 +928,12 @@ static inline int insert_entries(struct radix_tree_node *node,
928928
if (xa_is_node(old))
929929
radix_tree_free_nodes(old);
930930
if (xa_is_value(old))
931-
node->exceptional--;
931+
node->nr_values--;
932932
}
933933
if (node) {
934934
node->count += n;
935935
if (xa_is_value(item))
936-
node->exceptional += n;
936+
node->nr_values += n;
937937
}
938938
return n;
939939
}
@@ -947,7 +947,7 @@ static inline int insert_entries(struct radix_tree_node *node,
947947
if (node) {
948948
node->count++;
949949
if (xa_is_value(item))
950-
node->exceptional++;
950+
node->nr_values++;
951951
}
952952
return 1;
953953
}
@@ -1083,7 +1083,7 @@ void *radix_tree_lookup(const struct radix_tree_root *root, unsigned long index)
10831083
EXPORT_SYMBOL(radix_tree_lookup);
10841084

10851085
static inline void replace_sibling_entries(struct radix_tree_node *node,
1086-
void __rcu **slot, int count, int exceptional)
1086+
void __rcu **slot, int count, int values)
10871087
{
10881088
#ifdef CONFIG_RADIX_TREE_MULTIORDER
10891089
unsigned offset = get_slot_offset(node, slot);
@@ -1096,18 +1096,18 @@ static inline void replace_sibling_entries(struct radix_tree_node *node,
10961096
node->slots[offset] = NULL;
10971097
node->count--;
10981098
}
1099-
node->exceptional += exceptional;
1099+
node->nr_values += values;
11001100
}
11011101
#endif
11021102
}
11031103

11041104
static void replace_slot(void __rcu **slot, void *item,
1105-
struct radix_tree_node *node, int count, int exceptional)
1105+
struct radix_tree_node *node, int count, int values)
11061106
{
1107-
if (node && (count || exceptional)) {
1107+
if (node && (count || values)) {
11081108
node->count += count;
1109-
node->exceptional += exceptional;
1110-
replace_sibling_entries(node, slot, count, exceptional);
1109+
node->nr_values += values;
1110+
replace_sibling_entries(node, slot, count, values);
11111111
}
11121112

11131113
rcu_assign_pointer(*slot, item);
@@ -1161,17 +1161,17 @@ void __radix_tree_replace(struct radix_tree_root *root,
11611161
radix_tree_update_node_t update_node)
11621162
{
11631163
void *old = rcu_dereference_raw(*slot);
1164-
int exceptional = !!xa_is_value(item) - !!xa_is_value(old);
1164+
int values = !!xa_is_value(item) - !!xa_is_value(old);
11651165
int count = calculate_count(root, node, slot, item, old);
11661166

11671167
/*
1168-
* This function supports replacing exceptional entries and
1168+
* This function supports replacing value entries and
11691169
* deleting entries, but that needs accounting against the
11701170
* node unless the slot is root->xa_head.
11711171
*/
11721172
WARN_ON_ONCE(!node && (slot != (void __rcu **)&root->xa_head) &&
1173-
(count || exceptional));
1174-
replace_slot(slot, item, node, count, exceptional);
1173+
(count || values));
1174+
replace_slot(slot, item, node, count, values);
11751175

11761176
if (!node)
11771177
return;
@@ -1193,7 +1193,7 @@ void __radix_tree_replace(struct radix_tree_root *root,
11931193
* across slot lookup and replacement.
11941194
*
11951195
* NOTE: This cannot be used to switch between non-entries (empty slots),
1196-
* regular entries, and exceptional entries, as that requires accounting
1196+
* regular entries, and value entries, as that requires accounting
11971197
* inside the radix tree node. When switching from one type of entry or
11981198
* deleting, use __radix_tree_lookup() and __radix_tree_replace() or
11991199
* radix_tree_iter_replace().
@@ -1301,7 +1301,7 @@ int radix_tree_split(struct radix_tree_root *root, unsigned long index,
13011301
rcu_assign_pointer(parent->slots[end], RADIX_TREE_RETRY);
13021302
}
13031303
rcu_assign_pointer(parent->slots[offset], RADIX_TREE_RETRY);
1304-
parent->exceptional -= (end - offset);
1304+
parent->nr_values -= (end - offset);
13051305

13061306
if (order == parent->shift)
13071307
return 0;
@@ -1961,7 +1961,7 @@ static bool __radix_tree_delete(struct radix_tree_root *root,
19611961
struct radix_tree_node *node, void __rcu **slot)
19621962
{
19631963
void *old = rcu_dereference_raw(*slot);
1964-
int exceptional = xa_is_value(old) ? -1 : 0;
1964+
int values = xa_is_value(old) ? -1 : 0;
19651965
unsigned offset = get_slot_offset(node, slot);
19661966
int tag;
19671967

@@ -1971,7 +1971,7 @@ static bool __radix_tree_delete(struct radix_tree_root *root,
19711971
for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
19721972
node_tag_clear(root, node, tag, offset);
19731973

1974-
replace_slot(slot, NULL, node, -1, exceptional);
1974+
replace_slot(slot, NULL, node, -1, values);
19751975
return node && delete_node(root, node, NULL);
19761976
}
19771977

mm/workingset.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ void workingset_update_node(struct radix_tree_node *node)
349349
* already where they should be. The list_empty() test is safe
350350
* as node->private_list is protected by the i_pages lock.
351351
*/
352-
if (node->count && node->count == node->exceptional) {
352+
if (node->count && node->count == node->nr_values) {
353353
if (list_empty(&node->private_list))
354354
list_lru_add(&shadow_nodes, &node->private_list);
355355
} else {
@@ -428,8 +428,8 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
428428
* to reclaim, take the node off-LRU, and drop the lru_lock.
429429
*/
430430

431-
node = container_of(item, struct radix_tree_node, private_list);
432-
mapping = container_of(node->root, struct address_space, i_pages);
431+
node = container_of(item, struct xa_node, private_list);
432+
mapping = container_of(node->array, struct address_space, i_pages);
433433

434434
/* Coming from the list, invert the lock order */
435435
if (!xa_trylock(&mapping->i_pages)) {
@@ -446,25 +446,25 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
446446
* no pages, so we expect to be able to remove them all and
447447
* delete and free the empty node afterwards.
448448
*/
449-
if (WARN_ON_ONCE(!node->exceptional))
449+
if (WARN_ON_ONCE(!node->nr_values))
450450
goto out_invalid;
451-
if (WARN_ON_ONCE(node->count != node->exceptional))
451+
if (WARN_ON_ONCE(node->count != node->nr_values))
452452
goto out_invalid;
453453
for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
454454
if (node->slots[i]) {
455455
if (WARN_ON_ONCE(!xa_is_value(node->slots[i])))
456456
goto out_invalid;
457-
if (WARN_ON_ONCE(!node->exceptional))
457+
if (WARN_ON_ONCE(!node->nr_values))
458458
goto out_invalid;
459459
if (WARN_ON_ONCE(!mapping->nrexceptional))
460460
goto out_invalid;
461461
node->slots[i] = NULL;
462-
node->exceptional--;
462+
node->nr_values--;
463463
node->count--;
464464
mapping->nrexceptional--;
465465
}
466466
}
467-
if (WARN_ON_ONCE(node->exceptional))
467+
if (WARN_ON_ONCE(node->nr_values))
468468
goto out_invalid;
469469
inc_lruvec_page_state(virt_to_page(node), WORKINGSET_NODERECLAIM);
470470
__radix_tree_delete_node(&mapping->i_pages, node,

0 commit comments

Comments
 (0)