param tests: membarrier: pre-decode pointer offset
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 4 Mar 2024 16:36:03 +0000 (11:36 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 4 Mar 2024 16:36:03 +0000 (11:36 -0500)
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

tests/param_test.c

index a32f1f4f29eb3ac4661169bca265c3d10ebf1635..252a0a7dec663743681bf750371089803882abc2 100644 (file)
@@ -1363,6 +1363,7 @@ bool membarrier_private_expedited_rseq_available(void)
 /* 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;
 };
@@ -1390,12 +1391,12 @@ void *test_membarrier_worker_thread(void *arg)
 
                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));
        }
 
@@ -1463,6 +1464,7 @@ void *test_membarrier_manager_thread(void *arg)
                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",
This page took 0.025264 seconds and 4 git commands to generate.