@@ -244,6 +244,42 @@ rb_find_add(struct rb_node *node, struct rb_root *tree,
244
244
return NULL ;
245
245
}
246
246
247
+ /**
248
+ * rb_find_add_rcu() - find equivalent @node in @tree, or add @node
249
+ * @node: node to look-for / insert
250
+ * @tree: tree to search / modify
251
+ * @cmp: operator defining the node order
252
+ *
253
+ * Adds a Store-Release for link_node.
254
+ *
255
+ * Returns the rb_node matching @node, or NULL when no match is found and @node
256
+ * is inserted.
257
+ */
258
+ static __always_inline struct rb_node *
259
+ rb_find_add_rcu (struct rb_node * node , struct rb_root * tree ,
260
+ int (* cmp )(struct rb_node * , const struct rb_node * ))
261
+ {
262
+ struct rb_node * * link = & tree -> rb_node ;
263
+ struct rb_node * parent = NULL ;
264
+ int c ;
265
+
266
+ while (* link ) {
267
+ parent = * link ;
268
+ c = cmp (node , parent );
269
+
270
+ if (c < 0 )
271
+ link = & parent -> rb_left ;
272
+ else if (c > 0 )
273
+ link = & parent -> rb_right ;
274
+ else
275
+ return parent ;
276
+ }
277
+
278
+ rb_link_node_rcu (node , parent , link );
279
+ rb_insert_color (node , tree );
280
+ return NULL ;
281
+ }
282
+
247
283
/**
248
284
* rb_find() - find @key in tree @tree
249
285
* @key: key to match
@@ -272,6 +308,37 @@ rb_find(const void *key, const struct rb_root *tree,
272
308
return NULL ;
273
309
}
274
310
311
+ /**
312
+ * rb_find_rcu() - find @key in tree @tree
313
+ * @key: key to match
314
+ * @tree: tree to search
315
+ * @cmp: operator defining the node order
316
+ *
317
+ * Notably, tree descent vs concurrent tree rotations is unsound and can result
318
+ * in false-negatives.
319
+ *
320
+ * Returns the rb_node matching @key or NULL.
321
+ */
322
+ static __always_inline struct rb_node *
323
+ rb_find_rcu (const void * key , const struct rb_root * tree ,
324
+ int (* cmp )(const void * key , const struct rb_node * ))
325
+ {
326
+ struct rb_node * node = tree -> rb_node ;
327
+
328
+ while (node ) {
329
+ int c = cmp (key , node );
330
+
331
+ if (c < 0 )
332
+ node = rcu_dereference_raw (node -> rb_left );
333
+ else if (c > 0 )
334
+ node = rcu_dereference_raw (node -> rb_right );
335
+ else
336
+ return node ;
337
+ }
338
+
339
+ return NULL ;
340
+ }
341
+
275
342
/**
276
343
* rb_find_first() - find the first @key in @tree
277
344
* @key: key to match
0 commit comments