diff options
author | Matthew Wilcox <mawilcox@microsoft.com> | 2016-12-14 18:08:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-14 19:04:10 -0500 |
commit | 268f42de718128cd0301293177e79c08c38e39a6 (patch) | |
tree | 6668c85388c327f64ce9b51e77d70e245ec52b57 /include/linux/radix-tree.h | |
parent | 478922e2b0f41567e4a530771bfb3f693f857d45 (diff) |
radix-tree: delete radix_tree_range_tag_if_tagged()
This is an exceptionally complicated function with just one caller
(tag_pages_for_writeback). We devote a large portion of the runtime of
the test suite to testing this one function which has one caller. By
introducing the new function radix_tree_iter_tag_set(), we can eliminate
all of the complexity while keeping the performance. The caller can now
use a fairly standard radix_tree_for_each() loop, and it doesn't need to
worry about tricksy things like 'start' wrapping.
The test suite continues to spend a large amount of time investigating
this function, but now it's testing the underlying primitives such as
radix_tree_iter_resume() and the radix_tree_for_each_tagged() iterator
which are also used by other parts of the kernel.
Link: http://lkml.kernel.org/r/1480369871-5271-57-git-send-email-mawilcox@linuxonhyperv.com
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Cc: Matthew Wilcox <mawilcox@microsoft.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/radix-tree.h')
-rw-r--r-- | include/linux/radix-tree.h | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index a13d3f7c6c65..7a8d2516c73a 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -121,6 +121,41 @@ static inline bool radix_tree_empty(struct radix_tree_root *root) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * struct radix_tree_iter - radix tree iterator state | ||
125 | * | ||
126 | * @index: index of current slot | ||
127 | * @next_index: one beyond the last index for this chunk | ||
128 | * @tags: bit-mask for tag-iterating | ||
129 | * @node: node that contains current slot | ||
130 | * @shift: shift for the node that holds our slots | ||
131 | * | ||
132 | * This radix tree iterator works in terms of "chunks" of slots. A chunk is a | ||
133 | * subinterval of slots contained within one radix tree leaf node. It is | ||
134 | * described by a pointer to its first slot and a struct radix_tree_iter | ||
135 | * which holds the chunk's position in the tree and its size. For tagged | ||
136 | * iteration radix_tree_iter also holds the slots' bit-mask for one chosen | ||
137 | * radix tree tag. | ||
138 | */ | ||
139 | struct radix_tree_iter { | ||
140 | unsigned long index; | ||
141 | unsigned long next_index; | ||
142 | unsigned long tags; | ||
143 | struct radix_tree_node *node; | ||
144 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
145 | unsigned int shift; | ||
146 | #endif | ||
147 | }; | ||
148 | |||
149 | static inline unsigned int iter_shift(const struct radix_tree_iter *iter) | ||
150 | { | ||
151 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
152 | return iter->shift; | ||
153 | #else | ||
154 | return 0; | ||
155 | #endif | ||
156 | } | ||
157 | |||
158 | /** | ||
124 | * Radix-tree synchronization | 159 | * Radix-tree synchronization |
125 | * | 160 | * |
126 | * The radix-tree API requires that users provide all synchronisation (with | 161 | * The radix-tree API requires that users provide all synchronisation (with |
@@ -283,6 +318,8 @@ void *radix_tree_tag_clear(struct radix_tree_root *root, | |||
283 | unsigned long index, unsigned int tag); | 318 | unsigned long index, unsigned int tag); |
284 | int radix_tree_tag_get(struct radix_tree_root *root, | 319 | int radix_tree_tag_get(struct radix_tree_root *root, |
285 | unsigned long index, unsigned int tag); | 320 | unsigned long index, unsigned int tag); |
321 | void radix_tree_iter_tag_set(struct radix_tree_root *root, | ||
322 | const struct radix_tree_iter *iter, unsigned int tag); | ||
286 | unsigned int | 323 | unsigned int |
287 | radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, | 324 | radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, |
288 | unsigned long first_index, unsigned int max_items, | 325 | unsigned long first_index, unsigned int max_items, |
@@ -291,10 +328,6 @@ unsigned int | |||
291 | radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, | 328 | radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, |
292 | unsigned long first_index, unsigned int max_items, | 329 | unsigned long first_index, unsigned int max_items, |
293 | unsigned int tag); | 330 | unsigned int tag); |
294 | unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | ||
295 | unsigned long *first_indexp, unsigned long last_index, | ||
296 | unsigned long nr_to_tag, | ||
297 | unsigned int fromtag, unsigned int totag); | ||
298 | int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); | 331 | int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); |
299 | 332 | ||
300 | static inline void radix_tree_preload_end(void) | 333 | static inline void radix_tree_preload_end(void) |
@@ -302,39 +335,6 @@ static inline void radix_tree_preload_end(void) | |||
302 | preempt_enable(); | 335 | preempt_enable(); |
303 | } | 336 | } |
304 | 337 | ||
305 | /** | ||
306 | * struct radix_tree_iter - radix tree iterator state | ||
307 | * | ||
308 | * @index: index of current slot | ||
309 | * @next_index: one beyond the last index for this chunk | ||
310 | * @tags: bit-mask for tag-iterating | ||
311 | * @shift: shift for the node that holds our slots | ||
312 | * | ||
313 | * This radix tree iterator works in terms of "chunks" of slots. A chunk is a | ||
314 | * subinterval of slots contained within one radix tree leaf node. It is | ||
315 | * described by a pointer to its first slot and a struct radix_tree_iter | ||
316 | * which holds the chunk's position in the tree and its size. For tagged | ||
317 | * iteration radix_tree_iter also holds the slots' bit-mask for one chosen | ||
318 | * radix tree tag. | ||
319 | */ | ||
320 | struct radix_tree_iter { | ||
321 | unsigned long index; | ||
322 | unsigned long next_index; | ||
323 | unsigned long tags; | ||
324 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
325 | unsigned int shift; | ||
326 | #endif | ||
327 | }; | ||
328 | |||
329 | static inline unsigned int iter_shift(struct radix_tree_iter *iter) | ||
330 | { | ||
331 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
332 | return iter->shift; | ||
333 | #else | ||
334 | return 0; | ||
335 | #endif | ||
336 | } | ||
337 | |||
338 | #define RADIX_TREE_ITER_TAG_MASK 0x00FF /* tag index in lower byte */ | 338 | #define RADIX_TREE_ITER_TAG_MASK 0x00FF /* tag index in lower byte */ |
339 | #define RADIX_TREE_ITER_TAGGED 0x0100 /* lookup tagged slots */ | 339 | #define RADIX_TREE_ITER_TAGGED 0x0100 /* lookup tagged slots */ |
340 | #define RADIX_TREE_ITER_CONTIG 0x0200 /* stop at first hole */ | 340 | #define RADIX_TREE_ITER_CONTIG 0x0200 /* stop at first hole */ |