Skip to content

Commit f7b01bb

Browse files
compudjPeter Zijlstra
authored and
Peter Zijlstra
committed
rseq: Extend struct rseq with per-memory-map concurrency ID
If a memory map has fewer threads than there are cores on the system, or is limited to run on few cores concurrently through sched affinity or cgroup cpusets, the concurrency IDs will be values close to 0, thus allowing efficient use of user-space memory for per-cpu data structures. Signed-off-by: Mathieu Desnoyers <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent af7f588 commit f7b01bb

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

include/uapi/linux/rseq.h

+9
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ struct rseq {
139139
*/
140140
__u32 node_id;
141141

142+
/*
143+
* Restartable sequences mm_cid field. Updated by the kernel. Read by
144+
* user-space with single-copy atomicity semantics. This field should
145+
* only be read by the thread which registered this data structure.
146+
* Aligned on 32-bit. Contains the current thread's concurrency ID
147+
* (allocated uniquely within a memory map).
148+
*/
149+
__u32 mm_cid;
150+
142151
/*
143152
* Flexible array member at end of structure, after last feature field.
144153
*/

kernel/rseq.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,15 @@ static int rseq_update_cpu_node_id(struct task_struct *t)
9090
struct rseq __user *rseq = t->rseq;
9191
u32 cpu_id = raw_smp_processor_id();
9292
u32 node_id = cpu_to_node(cpu_id);
93+
u32 mm_cid = task_mm_cid(t);
9394

95+
WARN_ON_ONCE((int) mm_cid < 0);
9496
if (!user_write_access_begin(rseq, t->rseq_len))
9597
goto efault;
9698
unsafe_put_user(cpu_id, &rseq->cpu_id_start, efault_end);
9799
unsafe_put_user(cpu_id, &rseq->cpu_id, efault_end);
98100
unsafe_put_user(node_id, &rseq->node_id, efault_end);
101+
unsafe_put_user(mm_cid, &rseq->mm_cid, efault_end);
99102
/*
100103
* Additional feature fields added after ORIG_RSEQ_SIZE
101104
* need to be conditionally updated only if
@@ -113,7 +116,8 @@ static int rseq_update_cpu_node_id(struct task_struct *t)
113116

114117
static int rseq_reset_rseq_cpu_node_id(struct task_struct *t)
115118
{
116-
u32 cpu_id_start = 0, cpu_id = RSEQ_CPU_ID_UNINITIALIZED, node_id = 0;
119+
u32 cpu_id_start = 0, cpu_id = RSEQ_CPU_ID_UNINITIALIZED, node_id = 0,
120+
mm_cid = 0;
117121

118122
/*
119123
* Reset cpu_id_start to its initial state (0).
@@ -132,6 +136,11 @@ static int rseq_reset_rseq_cpu_node_id(struct task_struct *t)
132136
*/
133137
if (put_user(node_id, &t->rseq->node_id))
134138
return -EFAULT;
139+
/*
140+
* Reset mm_cid to its initial state (0).
141+
*/
142+
if (put_user(mm_cid, &t->rseq->mm_cid))
143+
return -EFAULT;
135144
/*
136145
* Additional feature fields added after ORIG_RSEQ_SIZE
137146
* need to be conditionally reset only if

0 commit comments

Comments
 (0)