Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b3f9da79
Commit
b3f9da79
authored
Aug 10, 2024
by
Kent Overstreet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lib/generic-radix-tree.c: add preallocation
Signed-off-by:
Kent Overstreet
<
kent.overstreet@linux.dev
>
parent
f6594633
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
37 additions
and
17 deletions
+37
-17
include/linux/generic-radix-tree.h
include/linux/generic-radix-tree.h
+32
-6
lib/generic-radix-tree.c
lib/generic-radix-tree.c
+5
-11
No files found.
include/linux/generic-radix-tree.h
View file @
b3f9da79
...
...
@@ -41,6 +41,7 @@
#include <linux/limits.h>
#include <linux/log2.h>
#include <linux/math.h>
#include <linux/slab.h>
#include <linux/types.h>
struct
genradix_root
;
...
...
@@ -81,6 +82,10 @@ static inline struct genradix_node *genradix_root_to_node(struct genradix_root *
return
(
void
*
)
((
unsigned
long
)
r
&
~
GENRADIX_DEPTH_MASK
);
}
struct
__genradix
{
struct
genradix_root
*
root
;
};
struct
genradix_node
{
union
{
/* Interior node: */
...
...
@@ -91,9 +96,15 @@ struct genradix_node {
};
};
struct
__genradix
{
struct
genradix_root
*
root
;
};
static
inline
struct
genradix_node
*
genradix_alloc_node
(
gfp_t
gfp_mask
)
{
return
kzalloc
(
GENRADIX_NODE_SIZE
,
gfp_mask
);
}
static
inline
void
genradix_free_node
(
struct
genradix_node
*
node
)
{
kfree
(
node
);
}
/*
* NOTE: currently, sizeof(_type) must not be larger than GENRADIX_NODE_SIZE:
...
...
@@ -209,7 +220,8 @@ void *__genradix_ptr(struct __genradix *, size_t);
__genradix_ptr(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx)))
void
*
__genradix_ptr_alloc
(
struct
__genradix
*
,
size_t
,
gfp_t
);
void
*
__genradix_ptr_alloc
(
struct
__genradix
*
,
size_t
,
struct
genradix_node
**
,
gfp_t
);
#define genradix_ptr_alloc_inlined(_radix, _idx, _gfp) \
(__genradix_cast(_radix) \
...
...
@@ -217,7 +229,15 @@ void *__genradix_ptr_alloc(struct __genradix *, size_t, gfp_t);
__genradix_idx_to_offset(_radix, _idx)) ?: \
__genradix_ptr_alloc(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx), \
_gfp)))
NULL, _gfp)))
#define genradix_ptr_alloc_preallocated_inlined(_radix, _idx, _new_node, _gfp)\
(__genradix_cast(_radix) \
(__genradix_ptr_inlined(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx)) ?: \
__genradix_ptr_alloc(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx), \
_new_node, _gfp)))
/**
* genradix_ptr_alloc - get a pointer to a genradix entry, allocating it
...
...
@@ -232,7 +252,13 @@ void *__genradix_ptr_alloc(struct __genradix *, size_t, gfp_t);
(__genradix_cast(_radix) \
__genradix_ptr_alloc(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx), \
_gfp))
NULL, _gfp))
#define genradix_ptr_alloc_preallocated(_radix, _idx, _new_node, _gfp)\
(__genradix_cast(_radix) \
__genradix_ptr_alloc(&(_radix)->tree, \
__genradix_idx_to_offset(_radix, _idx), \
_new_node, _gfp))
struct
genradix_iter
{
size_t
offset
;
...
...
lib/generic-radix-tree.c
View file @
b3f9da79
...
...
@@ -15,27 +15,21 @@ void *__genradix_ptr(struct __genradix *radix, size_t offset)
}
EXPORT_SYMBOL
(
__genradix_ptr
);
static
inline
struct
genradix_node
*
genradix_alloc_node
(
gfp_t
gfp_mask
)
{
return
kzalloc
(
GENRADIX_NODE_SIZE
,
gfp_mask
);
}
static
inline
void
genradix_free_node
(
struct
genradix_node
*
node
)
{
kfree
(
node
);
}
/*
* Returns pointer to the specified byte @offset within @radix, allocating it if
* necessary - newly allocated slots are always zeroed out:
*/
void
*
__genradix_ptr_alloc
(
struct
__genradix
*
radix
,
size_t
offset
,
struct
genradix_node
**
preallocated
,
gfp_t
gfp_mask
)
{
struct
genradix_root
*
v
=
READ_ONCE
(
radix
->
root
);
struct
genradix_node
*
n
,
*
new_node
=
NULL
;
unsigned
level
;
if
(
preallocated
)
swap
(
new_node
,
*
preallocated
);
/* Increase tree depth if necessary: */
while
(
1
)
{
struct
genradix_root
*
r
=
v
,
*
new_root
;
...
...
@@ -219,7 +213,7 @@ int __genradix_prealloc(struct __genradix *radix, size_t size,
size_t
offset
;
for
(
offset
=
0
;
offset
<
size
;
offset
+=
GENRADIX_NODE_SIZE
)
if
(
!
__genradix_ptr_alloc
(
radix
,
offset
,
gfp_mask
))
if
(
!
__genradix_ptr_alloc
(
radix
,
offset
,
NULL
,
gfp_mask
))
return
-
ENOMEM
;
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment