> From: "Milosz Tanski" <milosz@adfin.com>
> While trying to use the BP flavor of RCU I ran into random crashes. I
> tracked it down to issues with resizing of the BP RCU memory pool.
>
> The problem is in the urcu-bp.c file in the resize_arena() function.
> On successful allocation / remapping the len member of the
> registry_arena struct is never set anywhere function. On the second
> resize of the arena the code in resize_arena() still thinks the
> previous size is equal to the original mapping size. I've fixed this
> issue locally by just adding the following code at the bottom of
> resize_arena().
Good catch !!
However, I think your fix misses one case: if we happen to re-use the
same region, we want to update the length too.
Reported-by: Milosz Tanski <milosz@adfin.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*/
static void resize_arena(struct registry_arena *arena, size_t len)
{
*/
static void resize_arena(struct registry_arena *arena, size_t len)
{
+ void *new_p;
+ size_t old_len;
+
+ old_len = arena->len;
- new_arena = mmap(arena->p, len,
- PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE,
- -1, 0);
+ new_p = mmap(arena->p, len,
+ PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE,
+ -1, 0);
- new_arena = mremap_wrapper(arena->p, arena->len,
- len, MREMAP_MAYMOVE);
- assert(new_arena != MAP_FAILED);
+ new_p = mremap_wrapper(arena->p, old_len,
+ len, MREMAP_MAYMOVE);
+ assert(new_p != MAP_FAILED);
+
+ /*
+ * Zero the newly allocated memory. Since mmap() does not
+ * clearly specify if memory is zeroed or not (although it is
+ * very likely that it is), be extra careful by not expecting
+ * the new range to be zeroed by mremap.
+ */
+ bzero(new_p + old_len, len - old_len);
- * re-used the same region ?
+ * If we did not re-use the same region, we need to update the
+ * arena pointer.
- if (new_arena == arena->p)
- return;
+ if (new_p != arena->p)
+ arena->p = new_p;
- bzero(new_arena + arena->len, len - arena->len);
- arena->p = new_arena;
}
/* Called with signals off and mutex locked */
}
/* Called with signals off and mutex locked */