Loading "cpulist->head" outside of the rseq critical section is
unintended: loading cpulist->head loads memory from the per-cpu list
outside of the rseq critical section, which happens to work because the
memory is not actually freed in this specific test case, but would break
if memory would be reclaimed after the rseq fence.
So go back to the originally used rseq_load_add_load_load_add_store__ptr(),
and use the new rseq_percpu_pool_ptr_offset() to pre-calculate the
offset.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I5e621c724e143e38a6dfabd26bbf682a6fcc5182
/* Test MEMBARRIER_CMD_PRIVATE_RESTART_RSEQ_ON_CPU membarrier command. */
#ifdef TEST_MEMBARRIER
struct test_membarrier_thread_args {
/* Test MEMBARRIER_CMD_PRIVATE_RESTART_RSEQ_ON_CPU membarrier command. */
#ifdef TEST_MEMBARRIER
struct test_membarrier_thread_args {
+ struct rseq_percpu_pool *mempool;
struct percpu_list __rseq_percpu *percpu_list_ptr;
int stop;
};
struct percpu_list __rseq_percpu *percpu_list_ptr;
int stop;
};
do {
int cpu = get_current_cpu_id();
do {
int cpu = get_current_cpu_id();
- struct percpu_list __rseq_percpu *list = RSEQ_READ_ONCE(args->percpu_list_ptr);
- struct percpu_list *cpulist = rseq_percpu_ptr(list, cpu);
+ ptrdiff_t mempool_offset = rseq_percpu_pool_ptr_offset(args->mempool, cpu);
- ret = rseq_load_cbne_load_add_store__ptr(RSEQ_MO_RELAXED, RSEQ_PERCPU,
- (intptr_t *) &args->percpu_list_ptr, (intptr_t) list,
- &cpulist->head->data, 1, cpu);
+ ret = rseq_load_add_load_load_add_store__ptr(RSEQ_MO_RELAXED, RSEQ_PERCPU,
+ (intptr_t *) &args->percpu_list_ptr,
+ mempool_offset + offsetof(struct percpu_list, head),
+ 1, cpu);
} while (rseq_unlikely(ret));
}
} while (rseq_unlikely(ret));
}
perror("rseq_percpu_pool_create");
abort();
}
perror("rseq_percpu_pool_create");
abort();
}
+ args->mempool = mempool;
if (rseq_register_current_thread()) {
fprintf(stderr, "Error: rseq_register_current_thread(...) failed(%d): %s\n",
if (rseq_register_current_thread()) {
fprintf(stderr, "Error: rseq_register_current_thread(...) failed(%d): %s\n",