Skip to content

Commit d7b6272

Browse files
author
Matthew Wilcox
committed
radix-tree: Fix __rcu annotations
Many places were missing __rcu annotations. A few places needed a few lines of explanation about why it was safe to not use RCU accessors. Add a custom CFLAGS setting to the Makefile to ensure that new patches don't miss RCU annotations. Signed-off-by: Matthew Wilcox <[email protected]>
1 parent 12320d0 commit d7b6272

File tree

3 files changed

+122
-115
lines changed

3 files changed

+122
-115
lines changed

include/linux/radix-tree.h

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -221,37 +221,36 @@ static inline unsigned int iter_shift(const struct radix_tree_iter *iter)
221221
*/
222222

223223
/**
224-
* radix_tree_deref_slot - dereference a slot
225-
* @pslot: pointer to slot, returned by radix_tree_lookup_slot
226-
* Returns: item that was stored in that slot with any direct pointer flag
227-
* removed.
224+
* radix_tree_deref_slot - dereference a slot
225+
* @slot: slot pointer, returned by radix_tree_lookup_slot
228226
*
229227
* For use with radix_tree_lookup_slot(). Caller must hold tree at least read
230228
* locked across slot lookup and dereference. Not required if write lock is
231229
* held (ie. items cannot be concurrently inserted).
232230
*
233231
* radix_tree_deref_retry must be used to confirm validity of the pointer if
234232
* only the read lock is held.
233+
*
234+
* Return: entry stored in that slot.
235235
*/
236-
static inline void *radix_tree_deref_slot(void **pslot)
236+
static inline void *radix_tree_deref_slot(void __rcu **slot)
237237
{
238-
return rcu_dereference(*pslot);
238+
return rcu_dereference(*slot);
239239
}
240240

241241
/**
242-
* radix_tree_deref_slot_protected - dereference a slot without RCU lock but with tree lock held
243-
* @pslot: pointer to slot, returned by radix_tree_lookup_slot
244-
* Returns: item that was stored in that slot with any direct pointer flag
245-
* removed.
246-
*
247-
* Similar to radix_tree_deref_slot but only used during migration when a pages
248-
* mapping is being moved. The caller does not hold the RCU read lock but it
249-
* must hold the tree lock to prevent parallel updates.
242+
* radix_tree_deref_slot_protected - dereference a slot with tree lock held
243+
* @slot: slot pointer, returned by radix_tree_lookup_slot
244+
*
245+
* Similar to radix_tree_deref_slot. The caller does not hold the RCU read
246+
* lock but it must hold the tree lock to prevent parallel updates.
247+
*
248+
* Return: entry stored in that slot.
250249
*/
251-
static inline void *radix_tree_deref_slot_protected(void **pslot,
250+
static inline void *radix_tree_deref_slot_protected(void __rcu **slot,
252251
spinlock_t *treelock)
253252
{
254-
return rcu_dereference_protected(*pslot, lockdep_is_held(treelock));
253+
return rcu_dereference_protected(*slot, lockdep_is_held(treelock));
255254
}
256255

257256
/**
@@ -287,9 +286,9 @@ static inline int radix_tree_exception(void *arg)
287286
return unlikely((unsigned long)arg & RADIX_TREE_ENTRY_MASK);
288287
}
289288

290-
int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
289+
int __radix_tree_create(struct radix_tree_root *, unsigned long index,
291290
unsigned order, struct radix_tree_node **nodep,
292-
void ***slotp);
291+
void __rcu ***slotp);
293292
int __radix_tree_insert(struct radix_tree_root *, unsigned long index,
294293
unsigned order, void *);
295294
static inline int radix_tree_insert(struct radix_tree_root *root,
@@ -298,58 +297,55 @@ static inline int radix_tree_insert(struct radix_tree_root *root,
298297
return __radix_tree_insert(root, index, 0, entry);
299298
}
300299
void *__radix_tree_lookup(const struct radix_tree_root *, unsigned long index,
301-
struct radix_tree_node **nodep, void ***slotp);
300+
struct radix_tree_node **nodep, void __rcu ***slotp);
302301
void *radix_tree_lookup(const struct radix_tree_root *, unsigned long);
303-
void **radix_tree_lookup_slot(const struct radix_tree_root *, unsigned long);
302+
void __rcu **radix_tree_lookup_slot(const struct radix_tree_root *,
303+
unsigned long index);
304304
typedef void (*radix_tree_update_node_t)(struct radix_tree_node *, void *);
305-
void __radix_tree_replace(struct radix_tree_root *root,
306-
struct radix_tree_node *node,
307-
void **slot, void *item,
305+
void __radix_tree_replace(struct radix_tree_root *, struct radix_tree_node *,
306+
void __rcu **slot, void *entry,
308307
radix_tree_update_node_t update_node, void *private);
309308
void radix_tree_iter_replace(struct radix_tree_root *,
310-
const struct radix_tree_iter *, void **slot, void *item);
311-
void radix_tree_replace_slot(struct radix_tree_root *root,
312-
void **slot, void *item);
313-
void __radix_tree_delete_node(struct radix_tree_root *root,
314-
struct radix_tree_node *node,
309+
const struct radix_tree_iter *, void __rcu **slot, void *entry);
310+
void radix_tree_replace_slot(struct radix_tree_root *,
311+
void __rcu **slot, void *entry);
312+
void __radix_tree_delete_node(struct radix_tree_root *,
313+
struct radix_tree_node *,
315314
radix_tree_update_node_t update_node,
316315
void *private);
317316
void radix_tree_iter_delete(struct radix_tree_root *,
318-
struct radix_tree_iter *iter, void **slot);
317+
struct radix_tree_iter *iter, void __rcu **slot);
319318
void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
320319
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
321-
void radix_tree_clear_tags(struct radix_tree_root *root,
322-
struct radix_tree_node *node,
323-
void **slot);
320+
void radix_tree_clear_tags(struct radix_tree_root *, struct radix_tree_node *,
321+
void __rcu **slot);
324322
unsigned int radix_tree_gang_lookup(const struct radix_tree_root *,
325323
void **results, unsigned long first_index,
326324
unsigned int max_items);
327325
unsigned int radix_tree_gang_lookup_slot(const struct radix_tree_root *,
328-
void ***results, unsigned long *indices,
326+
void __rcu ***results, unsigned long *indices,
329327
unsigned long first_index, unsigned int max_items);
330328
int radix_tree_preload(gfp_t gfp_mask);
331329
int radix_tree_maybe_preload(gfp_t gfp_mask);
332330
int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order);
333331
void radix_tree_init(void);
334-
void *radix_tree_tag_set(struct radix_tree_root *root,
332+
void *radix_tree_tag_set(struct radix_tree_root *,
335333
unsigned long index, unsigned int tag);
336-
void *radix_tree_tag_clear(struct radix_tree_root *root,
334+
void *radix_tree_tag_clear(struct radix_tree_root *,
337335
unsigned long index, unsigned int tag);
338336
int radix_tree_tag_get(const struct radix_tree_root *,
339337
unsigned long index, unsigned int tag);
340338
void radix_tree_iter_tag_set(struct radix_tree_root *,
341339
const struct radix_tree_iter *iter, unsigned int tag);
342340
void radix_tree_iter_tag_clear(struct radix_tree_root *,
343341
const struct radix_tree_iter *iter, unsigned int tag);
344-
unsigned int
345-
radix_tree_gang_lookup_tag(const struct radix_tree_root *, void **results,
346-
unsigned long first_index, unsigned int max_items,
347-
unsigned int tag);
348-
unsigned int
349-
radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *, void ***results,
350-
unsigned long first_index, unsigned int max_items,
351-
unsigned int tag);
352-
int radix_tree_tagged(const struct radix_tree_root *root, unsigned int tag);
342+
unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *,
343+
void **results, unsigned long first_index,
344+
unsigned int max_items, unsigned int tag);
345+
unsigned int radix_tree_gang_lookup_tag_slot(const struct radix_tree_root *,
346+
void __rcu ***results, unsigned long first_index,
347+
unsigned int max_items, unsigned int tag);
348+
int radix_tree_tagged(const struct radix_tree_root *, unsigned int tag);
353349

354350
static inline void radix_tree_preload_end(void)
355351
{
@@ -361,7 +357,7 @@ int radix_tree_split(struct radix_tree_root *, unsigned long index,
361357
unsigned new_order);
362358
int radix_tree_join(struct radix_tree_root *, unsigned long index,
363359
unsigned new_order, void *);
364-
void **idr_get_free(struct radix_tree_root *, struct radix_tree_iter *,
360+
void __rcu **idr_get_free(struct radix_tree_root *, struct radix_tree_iter *,
365361
gfp_t, int end);
366362

367363
enum {
@@ -377,7 +373,7 @@ enum {
377373
* @start: iteration starting index
378374
* Returns: NULL
379375
*/
380-
static __always_inline void **
376+
static __always_inline void __rcu **
381377
radix_tree_iter_init(struct radix_tree_iter *iter, unsigned long start)
382378
{
383379
/*
@@ -406,7 +402,7 @@ radix_tree_iter_init(struct radix_tree_iter *iter, unsigned long start)
406402
* Also it fills @iter with data about chunk: position in the tree (index),
407403
* its end (next_index), and constructs a bit mask for tagged iterating (tags).
408404
*/
409-
void **radix_tree_next_chunk(const struct radix_tree_root *,
405+
void __rcu **radix_tree_next_chunk(const struct radix_tree_root *,
410406
struct radix_tree_iter *iter, unsigned flags);
411407

412408
/**
@@ -419,7 +415,8 @@ void **radix_tree_next_chunk(const struct radix_tree_root *,
419415
* containing it and updates @iter to describe the entry. If @index is not
420416
* present, it returns NULL.
421417
*/
422-
static inline void **radix_tree_iter_lookup(const struct radix_tree_root *root,
418+
static inline void __rcu **
419+
radix_tree_iter_lookup(const struct radix_tree_root *root,
423420
struct radix_tree_iter *iter, unsigned long index)
424421
{
425422
radix_tree_iter_init(iter, index);
@@ -436,7 +433,8 @@ static inline void **radix_tree_iter_lookup(const struct radix_tree_root *root,
436433
* which is at least @index. If @index is larger than any present entry, this
437434
* function returns NULL. The @iter is updated to describe the entry found.
438435
*/
439-
static inline void **radix_tree_iter_find(const struct radix_tree_root *root,
436+
static inline void __rcu **
437+
radix_tree_iter_find(const struct radix_tree_root *root,
440438
struct radix_tree_iter *iter, unsigned long index)
441439
{
442440
radix_tree_iter_init(iter, index);
@@ -453,7 +451,7 @@ static inline void **radix_tree_iter_find(const struct radix_tree_root *root,
453451
* and continue the iteration.
454452
*/
455453
static inline __must_check
456-
void **radix_tree_iter_retry(struct radix_tree_iter *iter)
454+
void __rcu **radix_tree_iter_retry(struct radix_tree_iter *iter)
457455
{
458456
iter->next_index = iter->index;
459457
iter->tags = 0;
@@ -476,7 +474,7 @@ __radix_tree_iter_add(struct radix_tree_iter *iter, unsigned long slots)
476474
* have been invalidated by an insertion or deletion. Call this function
477475
* before releasing the lock to continue the iteration from the next index.
478476
*/
479-
void **__must_check radix_tree_iter_resume(void **slot,
477+
void __rcu **__must_check radix_tree_iter_resume(void __rcu **slot,
480478
struct radix_tree_iter *iter);
481479

482480
/**
@@ -492,11 +490,11 @@ radix_tree_chunk_size(struct radix_tree_iter *iter)
492490
}
493491

494492
#ifdef CONFIG_RADIX_TREE_MULTIORDER
495-
void ** __radix_tree_next_slot(void **slot, struct radix_tree_iter *iter,
496-
unsigned flags);
493+
void __rcu **__radix_tree_next_slot(void __rcu **slot,
494+
struct radix_tree_iter *iter, unsigned flags);
497495
#else
498496
/* Can't happen without sibling entries, but the compiler can't tell that */
499-
static inline void ** __radix_tree_next_slot(void **slot,
497+
static inline void __rcu **__radix_tree_next_slot(void __rcu **slot,
500498
struct radix_tree_iter *iter, unsigned flags)
501499
{
502500
return slot;
@@ -522,8 +520,8 @@ static inline void ** __radix_tree_next_slot(void **slot,
522520
* b) we are doing non-tagged iteration, and iter->index and iter->next_index
523521
* have been set up so that radix_tree_chunk_size() returns 1 or 0.
524522
*/
525-
static __always_inline void **
526-
radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags)
523+
static __always_inline void __rcu **radix_tree_next_slot(void __rcu **slot,
524+
struct radix_tree_iter *iter, unsigned flags)
527525
{
528526
if (flags & RADIX_TREE_ITER_TAGGED) {
529527
iter->tags >>= 1;

lib/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
2424
is_single_threaded.o plist.o decompress.o kobject_uevent.o \
2525
earlycpio.o seq_buf.o nmi_backtrace.o nodemask.o win_minmax.o
2626

27+
CFLAGS_radix-tree.o += -DCONFIG_SPARSE_RCU_POINTER
28+
2729
lib-$(CONFIG_MMU) += ioremap.o
2830
lib-$(CONFIG_SMP) += cpumask.o
2931
lib-$(CONFIG_HAS_DMA) += dma-noop.o

0 commit comments

Comments
 (0)