|
26 | 26 | * Bitmask made from a "or" of all commands within enum membarrier_cmd, |
27 | 27 | * except MEMBARRIER_CMD_QUERY. |
28 | 28 | */ |
| 29 | +#ifdef CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE |
| 30 | +#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \ |
| 31 | + (MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE \ |
| 32 | + | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE) |
| 33 | +#else |
| 34 | +#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK 0 |
| 35 | +#endif |
| 36 | + |
29 | 37 | #define MEMBARRIER_CMD_BITMASK \ |
30 | 38 | (MEMBARRIER_CMD_GLOBAL | MEMBARRIER_CMD_GLOBAL_EXPEDITED \ |
31 | 39 | | MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED \ |
32 | 40 | | MEMBARRIER_CMD_PRIVATE_EXPEDITED \ |
33 | | - | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED) |
| 41 | + | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED \ |
| 42 | + | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK) |
34 | 43 |
|
35 | 44 | static void ipi_mb(void *info) |
36 | 45 | { |
@@ -104,15 +113,23 @@ static int membarrier_global_expedited(void) |
104 | 113 | return 0; |
105 | 114 | } |
106 | 115 |
|
107 | | -static int membarrier_private_expedited(void) |
| 116 | +static int membarrier_private_expedited(int flags) |
108 | 117 | { |
109 | 118 | int cpu; |
110 | 119 | bool fallback = false; |
111 | 120 | cpumask_var_t tmpmask; |
112 | 121 |
|
113 | | - if (!(atomic_read(¤t->mm->membarrier_state) |
114 | | - & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)) |
115 | | - return -EPERM; |
| 122 | + if (flags & MEMBARRIER_FLAG_SYNC_CORE) { |
| 123 | + if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE)) |
| 124 | + return -EINVAL; |
| 125 | + if (!(atomic_read(¤t->mm->membarrier_state) & |
| 126 | + MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY)) |
| 127 | + return -EPERM; |
| 128 | + } else { |
| 129 | + if (!(atomic_read(¤t->mm->membarrier_state) & |
| 130 | + MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)) |
| 131 | + return -EPERM; |
| 132 | + } |
116 | 133 |
|
117 | 134 | if (num_online_cpus() == 1) |
118 | 135 | return 0; |
@@ -205,29 +222,37 @@ static int membarrier_register_global_expedited(void) |
205 | 222 | return 0; |
206 | 223 | } |
207 | 224 |
|
208 | | -static int membarrier_register_private_expedited(void) |
| 225 | +static int membarrier_register_private_expedited(int flags) |
209 | 226 | { |
210 | 227 | struct task_struct *p = current; |
211 | 228 | struct mm_struct *mm = p->mm; |
| 229 | + int state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY; |
| 230 | + |
| 231 | + if (flags & MEMBARRIER_FLAG_SYNC_CORE) { |
| 232 | + if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE)) |
| 233 | + return -EINVAL; |
| 234 | + state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY; |
| 235 | + } |
212 | 236 |
|
213 | 237 | /* |
214 | 238 | * We need to consider threads belonging to different thread |
215 | 239 | * groups, which use the same mm. (CLONE_VM but not |
216 | 240 | * CLONE_THREAD). |
217 | 241 | */ |
218 | | - if (atomic_read(&mm->membarrier_state) |
219 | | - & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY) |
| 242 | + if (atomic_read(&mm->membarrier_state) & state) |
220 | 243 | return 0; |
221 | 244 | atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED, &mm->membarrier_state); |
| 245 | + if (flags & MEMBARRIER_FLAG_SYNC_CORE) |
| 246 | + atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE, |
| 247 | + &mm->membarrier_state); |
222 | 248 | if (!(atomic_read(&mm->mm_users) == 1 && get_nr_threads(p) == 1)) { |
223 | 249 | /* |
224 | 250 | * Ensure all future scheduler executions will observe the |
225 | 251 | * new thread flag state for this process. |
226 | 252 | */ |
227 | 253 | synchronize_sched(); |
228 | 254 | } |
229 | | - atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY, |
230 | | - &mm->membarrier_state); |
| 255 | + atomic_or(state, &mm->membarrier_state); |
231 | 256 | return 0; |
232 | 257 | } |
233 | 258 |
|
@@ -283,9 +308,13 @@ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) |
283 | 308 | case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED: |
284 | 309 | return membarrier_register_global_expedited(); |
285 | 310 | case MEMBARRIER_CMD_PRIVATE_EXPEDITED: |
286 | | - return membarrier_private_expedited(); |
| 311 | + return membarrier_private_expedited(0); |
287 | 312 | case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: |
288 | | - return membarrier_register_private_expedited(); |
| 313 | + return membarrier_register_private_expedited(0); |
| 314 | + case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE: |
| 315 | + return membarrier_private_expedited(MEMBARRIER_FLAG_SYNC_CORE); |
| 316 | + case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE: |
| 317 | + return membarrier_register_private_expedited(MEMBARRIER_FLAG_SYNC_CORE); |
289 | 318 | default: |
290 | 319 | return -EINVAL; |
291 | 320 | } |
|
0 commit comments