mas->min = min;
}
}
+
+/*
+ * mas_lookup_walk() - Internal quick lookup that does not keep maple state up
+ * to date.
+ *
+ * @mas: The maple state.
+ *
+ * Return: The entry for @mas->index or %NULL on dead node.
+ */
+static inline void *mas_lookup_walk(struct ma_state *mas)
+{
+ unsigned long *pivots;
+ unsigned char offset;
+ struct maple_node *node;
+ struct maple_enode *next;
+ enum maple_type type;
+ void __rcu **slots;
+ unsigned char end;
+ unsigned long max;
+
+ next = mas->node;
+ max = ULONG_MAX;
+ do {
+ offset = 0;
+ node = mte_to_node(next);
+ type = mte_node_type(next);
+ pivots = ma_pivots(node, type);
+ end = ma_data_end(node, type, pivots, max);
+ if (unlikely(ma_dead_node(node)))
+ goto dead_node;
+
+ while((offset < end) &&
+ (pivots[offset] < mas->index))
+ offset++;
+
+ if (likely(offset > mt_pivots[type]) && pivots[offset])
+ max = pivots[offset];
+
+ slots = ma_slots(node, type);
+ next = mt_slot(mas->tree, slots, offset);
+ if (unlikely(ma_dead_node(node)))
+ goto dead_node;
+ } while (!ma_is_leaf(type));
+
+ return (void *) next;
+
+dead_node:
+ mas_reset(mas);
+ return NULL;
+}
+
+/*
+ * mt_lookup() - Fast value lookup.
+ *
+ */
+void *mt_lookup(struct maple_tree *mt, unsigned long index)
+{
+ MA_STATE(mas, mt, index, index);
+ void *entry;
+
+retry:
+ entry = mas_start(&mas);
+ if (unlikely(mas_is_none(&mas)))
+ return NULL;
+
+ if (unlikely(mas_is_ptr(&mas))) {
+ if (!index)
+ return entry;
+
+ return NULL;
+ }
+
+ entry = mas_lookup_walk(&mas);
+ if (!entry && unlikely(mas_is_start(&mas)))
+ goto retry;
+
+ return entry;
+}
+EXPORT_SYMBOL_GPL(mt_lookup);
+
/*
* mas_descend_walk(): Locates a value and sets the mas->node and slot
* accordingly. range_min and range_max are set to the range which the entry is
{
void *ret = mtree_test_load(mt, index);
+ if (ret != mt_lookup(mt, index)) {
+ pr_err("lookup of %lu %p expected %p\n", index, mt_lookup(mt, index), ret);
+ }
+ MT_BUG_ON(mt, ret != mt_lookup(mt, index));
+
if (ret != ptr)
pr_err("Load %lu returned %p expect %p\n", index, ret, ptr);
MT_BUG_ON(mt, ret != ptr);