]> git.karo-electronics.de Git - karo-tx-linux.git/blob - kernel/membarrier.c
perf tools arm64: Add support for generating bpf prologue
[karo-tx-linux.git] / kernel / membarrier.c
1 /*
2  * Copyright (C) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3  *
4  * membarrier system call
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <linux/syscalls.h>
18 #include <linux/membarrier.h>
19
20 /*
21  * Bitmask made from a "or" of all commands within enum membarrier_cmd,
22  * except MEMBARRIER_CMD_QUERY.
23  */
24 #define MEMBARRIER_CMD_BITMASK  (MEMBARRIER_CMD_SHARED)
25
26 /**
27  * sys_membarrier - issue memory barriers on a set of threads
28  * @cmd:   Takes command values defined in enum membarrier_cmd.
29  * @flags: Currently needs to be 0. For future extensions.
30  *
31  * If this system call is not implemented, -ENOSYS is returned. If the
32  * command specified does not exist, or if the command argument is invalid,
33  * this system call returns -EINVAL. For a given command, with flags argument
34  * set to 0, this system call is guaranteed to always return the same value
35  * until reboot.
36  *
37  * All memory accesses performed in program order from each targeted thread
38  * is guaranteed to be ordered with respect to sys_membarrier(). If we use
39  * the semantic "barrier()" to represent a compiler barrier forcing memory
40  * accesses to be performed in program order across the barrier, and
41  * smp_mb() to represent explicit memory barriers forcing full memory
42  * ordering across the barrier, we have the following ordering table for
43  * each pair of barrier(), sys_membarrier() and smp_mb():
44  *
45  * The pair ordering is detailed as (O: ordered, X: not ordered):
46  *
47  *                        barrier()   smp_mb() sys_membarrier()
48  *        barrier()          X           X            O
49  *        smp_mb()           X           O            O
50  *        sys_membarrier()   O           O            O
51  */
52 SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
53 {
54         if (unlikely(flags))
55                 return -EINVAL;
56         switch (cmd) {
57         case MEMBARRIER_CMD_QUERY:
58                 return MEMBARRIER_CMD_BITMASK;
59         case MEMBARRIER_CMD_SHARED:
60                 if (num_online_cpus() > 1)
61                         synchronize_sched();
62                 return 0;
63         default:
64                 return -EINVAL;
65         }
66 }