diff options
Diffstat (limited to 'kernel/sched/membarrier.c')
| -rw-r--r-- | kernel/sched/membarrier.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c index a92fddc22747..dd7908743dab 100644 --- a/kernel/sched/membarrier.c +++ b/kernel/sched/membarrier.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/membarrier.h> | 18 | #include <linux/membarrier.h> |
| 19 | #include <linux/tick.h> | 19 | #include <linux/tick.h> |
| 20 | #include <linux/cpumask.h> | 20 | #include <linux/cpumask.h> |
| 21 | #include <linux/atomic.h> | ||
| 21 | 22 | ||
| 22 | #include "sched.h" /* for cpu_rq(). */ | 23 | #include "sched.h" /* for cpu_rq(). */ |
| 23 | 24 | ||
| @@ -26,21 +27,26 @@ | |||
| 26 | * except MEMBARRIER_CMD_QUERY. | 27 | * except MEMBARRIER_CMD_QUERY. |
| 27 | */ | 28 | */ |
| 28 | #define MEMBARRIER_CMD_BITMASK \ | 29 | #define MEMBARRIER_CMD_BITMASK \ |
| 29 | (MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED) | 30 | (MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED \ |
| 31 | | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED) | ||
| 30 | 32 | ||
| 31 | static void ipi_mb(void *info) | 33 | static void ipi_mb(void *info) |
| 32 | { | 34 | { |
| 33 | smp_mb(); /* IPIs should be serializing but paranoid. */ | 35 | smp_mb(); /* IPIs should be serializing but paranoid. */ |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | static void membarrier_private_expedited(void) | 38 | static int membarrier_private_expedited(void) |
| 37 | { | 39 | { |
| 38 | int cpu; | 40 | int cpu; |
| 39 | bool fallback = false; | 41 | bool fallback = false; |
| 40 | cpumask_var_t tmpmask; | 42 | cpumask_var_t tmpmask; |
| 41 | 43 | ||
| 44 | if (!(atomic_read(¤t->mm->membarrier_state) | ||
| 45 | & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)) | ||
| 46 | return -EPERM; | ||
| 47 | |||
| 42 | if (num_online_cpus() == 1) | 48 | if (num_online_cpus() == 1) |
| 43 | return; | 49 | return 0; |
| 44 | 50 | ||
| 45 | /* | 51 | /* |
| 46 | * Matches memory barriers around rq->curr modification in | 52 | * Matches memory barriers around rq->curr modification in |
| @@ -94,6 +100,24 @@ static void membarrier_private_expedited(void) | |||
| 94 | * rq->curr modification in scheduler. | 100 | * rq->curr modification in scheduler. |
| 95 | */ | 101 | */ |
| 96 | smp_mb(); /* exit from system call is not a mb */ | 102 | smp_mb(); /* exit from system call is not a mb */ |
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static void membarrier_register_private_expedited(void) | ||
| 107 | { | ||
| 108 | struct task_struct *p = current; | ||
| 109 | struct mm_struct *mm = p->mm; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * We need to consider threads belonging to different thread | ||
| 113 | * groups, which use the same mm. (CLONE_VM but not | ||
| 114 | * CLONE_THREAD). | ||
| 115 | */ | ||
| 116 | if (atomic_read(&mm->membarrier_state) | ||
| 117 | & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY) | ||
| 118 | return; | ||
| 119 | atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY, | ||
| 120 | &mm->membarrier_state); | ||
| 97 | } | 121 | } |
| 98 | 122 | ||
| 99 | /** | 123 | /** |
| @@ -144,7 +168,9 @@ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) | |||
| 144 | synchronize_sched(); | 168 | synchronize_sched(); |
| 145 | return 0; | 169 | return 0; |
| 146 | case MEMBARRIER_CMD_PRIVATE_EXPEDITED: | 170 | case MEMBARRIER_CMD_PRIVATE_EXPEDITED: |
| 147 | membarrier_private_expedited(); | 171 | return membarrier_private_expedited(); |
| 172 | case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED: | ||
| 173 | membarrier_register_private_expedited(); | ||
| 148 | return 0; | 174 | return 0; |
| 149 | default: | 175 | default: |
| 150 | return -EINVAL; | 176 | return -EINVAL; |
