*/
void mt_replace(struct ma_state *mas, void *p_entry, bool leaf)
{
- struct maple_node *mn = mt_to_node(mas->node);
+ struct maple_node *mn;
+
+ if (mas->node == p_entry)
+ return;
+
+ mn = mt_to_node(mas->node);
mn->parent = mt_to_node(p_entry)->parent;
if (!leaf)
ma_adopt_children(mn);
RCU_INIT_POINTER(parent->slot[slot], mas->node);
}
- mt_free(mt_to_node(p_entry));
+ mt_free(mt_to_node(p_entry));
}
+
void *ma_insert(struct ma_state *mas, void *entry)
{
void *p_entry; // Previous entry.
unsigned char slot = MAPLE_NODE_SLOTS;
+ unsigned long last = mas->max;
+ struct maple_range_64 *src;
+ bool coalesce = false;
+ unsigned char s_slot;
bool leaf;
leaf = _mas_walk(mas);
slot = ma_get_slot(mas);
+ src = mt_to_node(mas->node);
if (leaf == true && slot != MAPLE_NODE_SLOTS) {
- if (mt_to_node(mas->node)->slot[slot]) {
+ if (src->slot[slot]) {
mas_set_err(mas, -EEXIST);
goto exists;
}
}
p_entry = mas->node;
- mas_coalesce(mas);
- if (mas_is_err(mas))
- goto error;
+ for (s_slot = 0; s_slot < MAPLE_RANGE64_SLOTS - 1; s_slot++) {
+ if (last == src->pivot[s_slot]) {
+ coalesce = true;
+ break;
+ }
+ last = src->pivot[s_slot];
+ }
+
+ if (coalesce) {
+ mas_coalesce(mas);
+ if (mas_is_err(mas))
+ goto error;
+ }
/* Do the insert */
_ma_insert(mas, entry, slot);
mas_coalesce(mas);
if (mas_is_err(mas))
goto error;
+
mt_replace(mas, p_entry, leaf);
error:
else
mt_dump_node(entry, 0, mt_max[mt_node_type(entry)], 0);
}
+
void mt_set_non_kernel(unsigned int val)
{
kmem_cache_set_non_kernel(maple_node_cache, val);