#include <linux/maple_tree.h>
#include <linux/export.h>
#include <linux/slab.h>
+#include <asm/barrier.h>
#define MA_ROOT_PARENT 1
if (o_end == slot) { // Appending
/* zero the new end if the pivot exists. */
if (n_end < MAPLE_RANGE64_SLOTS - 2)
- mr64->pivot[n_end+1] = 0;
+ mr64->pivot[n_end + 1] = 0;
} else {
while (o_end > slot) {
+ RCU_INIT_POINTER(mr64->slot[n_end],
+ mr64->slot[o_end]);
if (n_end < MAPLE_RANGE64_SLOTS - 2)
mr64->pivot[n_end] = mr64->pivot[o_end];
- RCU_INIT_POINTER(mr64->slot[n_end--],
- mr64->slot[o_end--]);
+ n_end--;
+ o_end--;
}
}
- /* Set the entry value */
- mr64->pivot[n_end] = ms->last;
- RCU_INIT_POINTER(mr64->slot[n_end--], entry);
-
- /* Create a NULL gap, if necessary */
- if ((ms->index - 1 != mr64->pivot[n_end]) ||
+ RCU_INIT_POINTER(mr64->slot[n_end], entry);
+ if ((ms->index - 1 != mr64->pivot[n_end - 1]) ||
(ms->index != ms->last)) {
+ /* Set the entry value */
+ mr64->pivot[n_end--] = ms->last;
+ /* Create a NULL gap */
RCU_INIT_POINTER(mr64->slot[n_end], NULL);
+ wmb(); /* slot needs to be written before readers can see. */
mr64->pivot[n_end] = ms->index - 1;
+ } else {
+ wmb(); /* slot needs to be written before readers can see. */
+ /* Set the entry value */
+ mr64->pivot[n_end] = ms->last;
}
return added;
}
void *mas_walk(struct ma_state *ms)
{
void *entry = mas_start(ms);
- unsigned char slot;
+ unsigned char slot = MAPLE_NODE_SLOTS;
/* Outside this nodes range, it doesn't exist. */
if (ms->min > ms->index ||