Blame view

include/linux/radix-tree.h 9.51 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   * Copyright (C) 2001 Momchil Velikov
   * Portions Copyright (C) 2001 Christoph Hellwig
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
4
   * Copyright (C) 2006 Nick Piggin
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
   * published by the Free Software Foundation; either version 2, or (at
   * your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  #ifndef _LINUX_RADIX_TREE_H
  #define _LINUX_RADIX_TREE_H
  
  #include <linux/preempt.h>
  #include <linux/types.h>
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
25
26
27
28
  #include <linux/kernel.h>
  #include <linux/rcupdate.h>
  
  /*
c0bc9875b   Nick Piggin   radix-tree: use i...
29
30
31
   * An indirect pointer (root->rnode pointing to a radix_tree_node, rather
   * than a data item) is signalled by the low bit set in the root->rnode
   * pointer.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
32
   *
c0bc9875b   Nick Piggin   radix-tree: use i...
33
34
35
36
   * In this case root->height is > 0, but the indirect pointer tests are
   * needed for RCU lookups (because root->height is unreliable). The only
   * time callers need worry about this is when doing a lookup_slot under
   * RCU.
27d20fddc   Nick Piggin   radix-tree: fix R...
37
38
39
40
   *
   * Indirect pointer in fact is also used to tag the last pointer of a node
   * when it is shrunk, before we rcu free the node. See shrink code for
   * details.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
41
   */
6328650bb   Hugh Dickins   radix_tree: excep...
42
43
44
45
46
47
48
49
50
  #define RADIX_TREE_INDIRECT_PTR		1
  /*
   * A common use of the radix tree is to store pointers to struct pages;
   * but shmem/tmpfs needs also to store swap entries in the same tree:
   * those are marked as exceptional entries to distinguish them.
   * EXCEPTIONAL_ENTRY tests the bit, EXCEPTIONAL_SHIFT shifts content past it.
   */
  #define RADIX_TREE_EXCEPTIONAL_ENTRY	2
  #define RADIX_TREE_EXCEPTIONAL_SHIFT	2
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
51

c0bc9875b   Nick Piggin   radix-tree: use i...
52
  static inline int radix_tree_is_indirect_ptr(void *ptr)
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
53
  {
c0bc9875b   Nick Piggin   radix-tree: use i...
54
  	return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
55
56
57
  }
  
  /*** radix-tree API starts here ***/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58

f446daaea   Jan Kara   mm: implement wri...
59
  #define RADIX_TREE_MAX_TAGS 3
612d6c19d   Nick Piggin   [PATCH] radix-tre...
60
61
  
  /* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
  struct radix_tree_root {
  	unsigned int		height;
fd4f2df24   Al Viro   [PATCH] gfp_t: lib/*
64
  	gfp_t			gfp_mask;
a1115570b   Arnd Bergmann   radix-tree: __rcu...
65
  	struct radix_tree_node	__rcu *rnode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  };
  
  #define RADIX_TREE_INIT(mask)	{					\
  	.height = 0,							\
  	.gfp_mask = (mask),						\
  	.rnode = NULL,							\
  }
  
  #define RADIX_TREE(name, mask) \
  	struct radix_tree_root name = RADIX_TREE_INIT(mask)
  
  #define INIT_RADIX_TREE(root, mask)					\
  do {									\
  	(root)->height = 0;						\
  	(root)->gfp_mask = (mask);					\
  	(root)->rnode = NULL;						\
  } while (0)
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
83
84
85
86
87
88
89
90
91
92
  /**
   * Radix-tree synchronization
   *
   * The radix-tree API requires that users provide all synchronisation (with
   * specific exceptions, noted below).
   *
   * Synchronization of access to the data items being stored in the tree, and
   * management of their lifetimes must be completely managed by API users.
   *
   * For API usage, in general,
59c51591a   Michael Opdenacker   Fix occurrences o...
93
   * - any function _modifying_ the tree or tags (inserting or deleting
eb8dc5e7b   Tim Pepper   radix_tree.h triv...
94
   *   items, setting or clearing tags) must exclude other modifications, and
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
95
   *   exclude any functions reading the tree.
59c51591a   Michael Opdenacker   Fix occurrences o...
96
   * - any function _reading_ the tree or tags (looking up items or tags,
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
97
98
99
100
101
   *   gang lookups) must exclude modifications to the tree, but may occur
   *   concurrently with other readers.
   *
   * The notable exceptions to this rule are the following functions:
   * radix_tree_lookup
47feff2c8   Nick Piggin   radix-tree: add g...
102
   * radix_tree_lookup_slot
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
103
104
   * radix_tree_tag_get
   * radix_tree_gang_lookup
47feff2c8   Nick Piggin   radix-tree: add g...
105
   * radix_tree_gang_lookup_slot
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
106
   * radix_tree_gang_lookup_tag
47feff2c8   Nick Piggin   radix-tree: add g...
107
   * radix_tree_gang_lookup_tag_slot
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
108
109
   * radix_tree_tagged
   *
47feff2c8   Nick Piggin   radix-tree: add g...
110
   * The first 7 functions are able to be called locklessly, using RCU. The
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
111
112
113
114
115
116
117
118
119
120
121
122
123
   * caller must ensure calls to these functions are made within rcu_read_lock()
   * regions. Other readers (lock-free or otherwise) and modifications may be
   * running concurrently.
   *
   * It is still required that the caller manage the synchronization and lifetimes
   * of the items. So if RCU lock-free lookups are used, typically this would mean
   * that the items have their own locks, or are amenable to lock-free access; and
   * that the items are freed by RCU (or only freed after having been deleted from
   * the radix tree *and* a synchronize_rcu() grace period).
   *
   * (Note, rcu_assign_pointer and rcu_dereference are not needed to control
   * access to data items when inserting into or looking up from the radix tree)
   *
ce82653d6   David Howells   radix_tree_tag_ge...
124
125
126
127
128
129
130
   * Note that the value returned by radix_tree_tag_get() may not be relied upon
   * if only the RCU read lock is held.  Functions to set/clear tags and to
   * delete nodes running concurrently with it may affect its result such that
   * two consecutive reads in the same locked section may return different
   * values.  If reliability is required, modification functions must also be
   * excluded from concurrency.
   *
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
131
132
133
134
135
136
137
138
139
140
   * radix_tree_tagged is able to be called without locking or RCU.
   */
  
  /**
   * radix_tree_deref_slot	- dereference a slot
   * @pslot:	pointer to slot, returned by radix_tree_lookup_slot
   * Returns:	item that was stored in that slot with any direct pointer flag
   *		removed.
   *
   * For use with radix_tree_lookup_slot().  Caller must hold tree at least read
27d20fddc   Nick Piggin   radix-tree: fix R...
141
142
143
144
145
   * locked across slot lookup and dereference. Not required if write lock is
   * held (ie. items cannot be concurrently inserted).
   *
   * radix_tree_deref_retry must be used to confirm validity of the pointer if
   * only the read lock is held.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
146
147
148
   */
  static inline void *radix_tree_deref_slot(void **pslot)
  {
27d20fddc   Nick Piggin   radix-tree: fix R...
149
  	return rcu_dereference(*pslot);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
150
  }
27d20fddc   Nick Piggin   radix-tree: fix R...
151
152
  
  /**
29c1f677d   Mel Gorman   mm: migration: us...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
   * radix_tree_deref_slot_protected	- dereference a slot without RCU lock but with tree lock held
   * @pslot:	pointer to slot, returned by radix_tree_lookup_slot
   * Returns:	item that was stored in that slot with any direct pointer flag
   *		removed.
   *
   * Similar to radix_tree_deref_slot but only used during migration when a pages
   * mapping is being moved. The caller does not hold the RCU read lock but it
   * must hold the tree lock to prevent parallel updates.
   */
  static inline void *radix_tree_deref_slot_protected(void **pslot,
  							spinlock_t *treelock)
  {
  	return rcu_dereference_protected(*pslot, lockdep_is_held(treelock));
  }
  
  /**
27d20fddc   Nick Piggin   radix-tree: fix R...
169
170
171
172
173
174
175
176
177
178
   * radix_tree_deref_retry	- check radix_tree_deref_slot
   * @arg:	pointer returned by radix_tree_deref_slot
   * Returns:	0 if retry is not required, otherwise retry is required
   *
   * radix_tree_deref_retry must be used with radix_tree_deref_slot.
   */
  static inline int radix_tree_deref_retry(void *arg)
  {
  	return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR);
  }
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
179
  /**
6328650bb   Hugh Dickins   radix_tree: excep...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
   * radix_tree_exceptional_entry	- radix_tree_deref_slot gave exceptional entry?
   * @arg:	value returned by radix_tree_deref_slot
   * Returns:	0 if well-aligned pointer, non-0 if exceptional entry.
   */
  static inline int radix_tree_exceptional_entry(void *arg)
  {
  	/* Not unlikely because radix_tree_exception often tested first */
  	return (unsigned long)arg & RADIX_TREE_EXCEPTIONAL_ENTRY;
  }
  
  /**
   * radix_tree_exception	- radix_tree_deref_slot returned either exception?
   * @arg:	value returned by radix_tree_deref_slot
   * Returns:	0 if well-aligned pointer, non-0 if either kind of exception.
   */
  static inline int radix_tree_exception(void *arg)
  {
  	return unlikely((unsigned long)arg &
  		(RADIX_TREE_INDIRECT_PTR | RADIX_TREE_EXCEPTIONAL_ENTRY));
  }
  
  /**
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
202
203
204
205
206
207
208
209
210
   * radix_tree_replace_slot	- replace item in a slot
   * @pslot:	pointer to slot, returned by radix_tree_lookup_slot
   * @item:	new item to store in the slot.
   *
   * For use with radix_tree_lookup_slot().  Caller must hold tree write locked
   * across slot lookup and replacement.
   */
  static inline void radix_tree_replace_slot(void **pslot, void *item)
  {
c0bc9875b   Nick Piggin   radix-tree: use i...
211
212
  	BUG_ON(radix_tree_is_indirect_ptr(item));
  	rcu_assign_pointer(*pslot, item);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
213
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
  int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
  void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
a43313668   Hans Reiser   [PATCH] reiser4: ...
216
  void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
  void *radix_tree_delete(struct radix_tree_root *, unsigned long);
  unsigned int
  radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
  			unsigned long first_index, unsigned int max_items);
6328650bb   Hugh Dickins   radix_tree: excep...
221
222
  unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root,
  			void ***results, unsigned long *indices,
47feff2c8   Nick Piggin   radix-tree: add g...
223
  			unsigned long first_index, unsigned int max_items);
6df8ba4f8   Fengguang Wu   radixtree: introd...
224
225
  unsigned long radix_tree_next_hole(struct radix_tree_root *root,
  				unsigned long index, unsigned long max_scan);
dc566127d   Wu Fengguang   radix-tree: add r...
226
227
  unsigned long radix_tree_prev_hole(struct radix_tree_root *root,
  				unsigned long index, unsigned long max_scan);
dd0fc66fb   Al Viro   [PATCH] gfp flags...
228
  int radix_tree_preload(gfp_t gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
  void radix_tree_init(void);
  void *radix_tree_tag_set(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
231
  			unsigned long index, unsigned int tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
  void *radix_tree_tag_clear(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
233
  			unsigned long index, unsigned int tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  int radix_tree_tag_get(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
235
  			unsigned long index, unsigned int tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
  unsigned int
  radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
238
239
  		unsigned long first_index, unsigned int max_items,
  		unsigned int tag);
47feff2c8   Nick Piggin   radix-tree: add g...
240
241
242
243
  unsigned int
  radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results,
  		unsigned long first_index, unsigned int max_items,
  		unsigned int tag);
ebf8aa44b   Jan Kara   radix-tree: omple...
244
245
246
247
  unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
  		unsigned long *first_indexp, unsigned long last_index,
  		unsigned long nr_to_tag,
  		unsigned int fromtag, unsigned int totag);
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
248
  int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag);
e504f3fdd   Hugh Dickins   tmpfs radix_tree:...
249
  unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
254
255
256
  
  static inline void radix_tree_preload_end(void)
  {
  	preempt_enable();
  }
  
  #endif /* _LINUX_RADIX_TREE_H */