aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2024-03-04 11:34:41 -0500
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>2024-03-04 11:34:41 -0500
commit8fde749f442d4052fe2be0541e134b44f18dfab7 (patch)
tree00597fdd64f1d180d75d2eef373ea572aeecd8b9
parent8aa1462dcd0c8f23b9d8d7668cd59f87b1a693ec (diff)
downloadlibrseq-8fde749f442d4052fe2be0541e134b44f18dfab7.tar.gz
percpu alloc: introduce rseq_percpu_pool_ptr_offset
Introduce rseq_percpu_pool_ptr_offset to pre-decode the offset from all __rseq_percpu pointers for a given pool. This is useful to prepare offsets that would need to be calculated within rseq critical sections. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Change-Id: I42d2669ed5ed81d74aae551b721c9cb04b25fe45
-rw-r--r--include/rseq/percpu-alloc.h10
-rw-r--r--src/rseq-percpu-alloc.c8
2 files changed, 18 insertions, 0 deletions
diff --git a/include/rseq/percpu-alloc.h b/include/rseq/percpu-alloc.h
index 0761acc..0bd7a91 100644
--- a/include/rseq/percpu-alloc.h
+++ b/include/rseq/percpu-alloc.h
@@ -169,6 +169,16 @@ void *__rseq_percpu_ptr(void __rseq_percpu *ptr, int cpu);
#define rseq_percpu_ptr(ptr, cpu) ((__typeof__(*(ptr)) *) __rseq_percpu_ptr(ptr, cpu))
/*
+ * rseq_percpu_pool_cpu_offset: Return the offset from encoded to decoded percpu pointer.
+ *
+ * Calculate the offset from any __rseq_percpu pointer allocated from
+ * the pool to its associated per-cpu data for @cpu.
+ *
+ * This API is MT-safe.
+ */
+ptrdiff_t rseq_percpu_pool_ptr_offset(struct rseq_percpu_pool *pool, int cpu);
+
+/*
* rseq_percpu_pool_set_create: Create a pool set.
*
* Create a set of pools. Its purpose is to offer a memory allocator API
diff --git a/src/rseq-percpu-alloc.c b/src/rseq-percpu-alloc.c
index 7d6498f..781a22d 100644
--- a/src/rseq-percpu-alloc.c
+++ b/src/rseq-percpu-alloc.c
@@ -116,6 +116,14 @@ void *__rseq_pool_percpu_ptr(struct rseq_percpu_pool *pool, int cpu, uintptr_t i
return pool->base + (pool->percpu_len * cpu) + item_offset;
}
+ptrdiff_t rseq_percpu_pool_ptr_offset(struct rseq_percpu_pool *pool, int cpu)
+{
+ uintptr_t rseq_percpu_base = (uintptr_t) pool->index << POOL_INDEX_SHIFT;
+ uintptr_t refptr = (uintptr_t) __rseq_pool_percpu_ptr(pool, cpu, 0);
+
+ return (ptrdiff_t) (refptr - rseq_percpu_base);
+}
+
void *__rseq_percpu_ptr(void __rseq_percpu *_ptr, int cpu)
{
uintptr_t ptr = (uintptr_t) _ptr;