Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/membarrier: Introduce MEMBARRIER_CMD_GET_REGISTRATIONS

Provide a method to query previously issued registrations.

Signed-off-by: Michal Clapinski <mclapinski@google.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://lore.kernel.org/r/20221207164338.1535591-2-mclapinski@google.com

authored by

Michal Clapinski and committed by
Ingo Molnar
544a4f2e 948fb4c4

+42 -1
+4
include/uapi/linux/membarrier.h
··· 137 137 * @MEMBARRIER_CMD_SHARED: 138 138 * Alias to MEMBARRIER_CMD_GLOBAL. Provided for 139 139 * header backward compatibility. 140 + * @MEMBARRIER_CMD_GET_REGISTRATIONS: 141 + * Returns a bitmask of previously issued 142 + * registration commands. 140 143 * 141 144 * Command to be passed to the membarrier system call. The commands need to 142 145 * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to ··· 156 153 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6), 157 154 MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = (1 << 7), 158 155 MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = (1 << 8), 156 + MEMBARRIER_CMD_GET_REGISTRATIONS = (1 << 9), 159 157 160 158 /* Alias for header backward compatibility. */ 161 159 MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
+38 -1
kernel/sched/membarrier.c
··· 159 159 | MEMBARRIER_CMD_PRIVATE_EXPEDITED \ 160 160 | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED \ 161 161 | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \ 162 - | MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK) 162 + | MEMBARRIER_PRIVATE_EXPEDITED_RSEQ_BITMASK \ 163 + | MEMBARRIER_CMD_GET_REGISTRATIONS) 163 164 164 165 static void ipi_mb(void *info) 165 166 { ··· 541 540 return 0; 542 541 } 543 542 543 + static int membarrier_get_registrations(void) 544 + { 545 + struct task_struct *p = current; 546 + struct mm_struct *mm = p->mm; 547 + int registrations_mask = 0, membarrier_state, i; 548 + static const int states[] = { 549 + MEMBARRIER_STATE_GLOBAL_EXPEDITED | 550 + MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY, 551 + MEMBARRIER_STATE_PRIVATE_EXPEDITED | 552 + MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY, 553 + MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE | 554 + MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY, 555 + MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ | 556 + MEMBARRIER_STATE_PRIVATE_EXPEDITED_RSEQ_READY 557 + }; 558 + static const int registration_cmds[] = { 559 + MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, 560 + MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 561 + MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, 562 + MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ 563 + }; 564 + BUILD_BUG_ON(ARRAY_SIZE(states) != ARRAY_SIZE(registration_cmds)); 565 + 566 + membarrier_state = atomic_read(&mm->membarrier_state); 567 + for (i = 0; i < ARRAY_SIZE(states); ++i) { 568 + if (membarrier_state & states[i]) { 569 + registrations_mask |= registration_cmds[i]; 570 + membarrier_state &= ~states[i]; 571 + } 572 + } 573 + WARN_ON_ONCE(membarrier_state != 0); 574 + return registrations_mask; 575 + } 576 + 544 577 /** 545 578 * sys_membarrier - issue memory barriers on a set of threads 546 579 * @cmd: Takes command values defined in enum membarrier_cmd. ··· 658 623 return membarrier_private_expedited(MEMBARRIER_FLAG_RSEQ, cpu_id); 659 624 case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ: 660 625 return membarrier_register_private_expedited(MEMBARRIER_FLAG_RSEQ); 626 + case MEMBARRIER_CMD_GET_REGISTRATIONS: 627 + return membarrier_get_registrations(); 661 628 default: 662 629 return -EINVAL; 663 630 }