signal: don't remove SIGNAL_UNKILLABLE for traced tasks.
[platform/kernel/linux-rpi.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 #include <linux/tick.h>
20
21 /*
22  * Bitmask made from a "or" of all commands within enum membarrier_cmd,
23  * except MEMBARRIER_CMD_QUERY.
24  */
25 #define MEMBARRIER_CMD_BITMASK  (MEMBARRIER_CMD_SHARED)
26
27 /**
28  * sys_membarrier - issue memory barriers on a set of threads
29  * @cmd:   Takes command values defined in enum membarrier_cmd.
30  * @flags: Currently needs to be 0. For future extensions.
31  *
32  * If this system call is not implemented, -ENOSYS is returned. If the
33  * command specified does not exist, or if the command argument is invalid,
34  * this system call returns -EINVAL. For a given command, with flags argument
35  * set to 0, this system call is guaranteed to always return the same value
36  * until reboot.
37  *
38  * All memory accesses performed in program order from each targeted thread
39  * is guaranteed to be ordered with respect to sys_membarrier(). If we use
40  * the semantic "barrier()" to represent a compiler barrier forcing memory
41  * accesses to be performed in program order across the barrier, and
42  * smp_mb() to represent explicit memory barriers forcing full memory
43  * ordering across the barrier, we have the following ordering table for
44  * each pair of barrier(), sys_membarrier() and smp_mb():
45  *
46  * The pair ordering is detailed as (O: ordered, X: not ordered):
47  *
48  *                        barrier()   smp_mb() sys_membarrier()
49  *        barrier()          X           X            O
50  *        smp_mb()           X           O            O
51  *        sys_membarrier()   O           O            O
52  */
53 SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
54 {
55         /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
56         if (tick_nohz_full_enabled())
57                 return -ENOSYS;
58         if (unlikely(flags))
59                 return -EINVAL;
60         switch (cmd) {
61         case MEMBARRIER_CMD_QUERY:
62                 return MEMBARRIER_CMD_BITMASK;
63         case MEMBARRIER_CMD_SHARED:
64                 if (num_online_cpus() > 1)
65                         synchronize_sched();
66                 return 0;
67         default:
68                 return -EINVAL;
69         }
70 }