]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/membarrier.2
mmap.2: srcfix: note kernel commit that caused MAP_POPULATE | MAP_NONBLOCK to be...
[thirdparty/man-pages.git] / man2 / membarrier.2
CommitLineData
c50f154e 1.\" Copyright 2015-2017 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
d06aa1bf
MD
2.\"
3.\" %%%LICENSE_START(VERBATIM)
4.\" Permission is granted to make and distribute verbatim copies of this
5.\" manual provided the copyright notice and this permission notice are
6.\" preserved on all copies.
7.\"
8.\" Permission is granted to copy and distribute modified versions of this
9.\" manual under the conditions for verbatim copying, provided that the
10.\" entire resulting derived work is distributed under the terms of a
11.\" permission notice identical to this one.
12.\"
13.\" Since the Linux kernel and libraries are constantly changing, this
14.\" manual page may be incorrect or out-of-date. The author(s) assume no
15.\" responsibility for errors or omissions, or for damages resulting from
16.\" the use of the information contained herein. The author(s) may not
17.\" have taken the same level of care in the production of this manual,
18.\" which is licensed free of charge, as they might when working
19.\" professionally.
20.\"
21.\" Formatted or processed versions of this manual, if unaccompanied by
22.\" the source, must acknowledge the copyright and authors of this work.
23.\" %%%LICENSE_END
24.\"
09b8afdc 25.TH MEMBARRIER 2 2018-04-30 "Linux" "Linux Programmer's Manual"
d06aa1bf
MD
26.SH NAME
27membarrier \- issue memory barriers on a set of threads
28.SH SYNOPSIS
29.B #include <linux/membarrier.h>
68e4db0a 30.PP
d06aa1bf 31.BI "int membarrier(int " cmd ", int " flags ");
d06aa1bf 32.SH DESCRIPTION
7e6241dc
MK
33The
34.BR membarrier ()
35system call helps reducing the overhead of the memory barrier
d06aa1bf
MD
36instructions required to order memory accesses on multi-core systems.
37However, this system call is heavier than a memory barrier, so using it
38effectively is
7e6241dc 39.I not
d06aa1bf 40as simple as replacing memory barriers with this
7e6241dc 41system call, but requires understanding of the details below.
efeece04 42.PP
d06aa1bf
MD
43Use of memory barriers needs to be done taking into account that a
44memory barrier always needs to be either matched with its memory barrier
7e6241dc 45counterparts, or that the architecture's memory model doesn't require the
d06aa1bf 46matching barriers.
efeece04 47.PP
d06aa1bf
MD
48There are cases where one side of the matching barriers (which we will
49refer to as "fast side") is executed much more often than the other
7e6241dc
MK
50(which we will refer to as "slow side").
51This is a prime target for the use of
52.BR membarrier ().
53The key idea is to replace, for these matching
54barriers, the fast-side memory barriers by simple compiler barriers,
55for example:
efeece04 56.PP
1afb17b7
MK
57.in +4n
58.EX
59asm volatile ("" : : : "memory")
60.EE
61.in
efeece04 62.PP
7e6241dc
MK
63and replace the slow-side memory barriers by calls to
64.BR membarrier ().
efeece04 65.PP
d06aa1bf
MD
66This will add overhead to the slow side, and remove overhead from the
67fast side, thus resulting in an overall performance increase as long as
7e6241dc
MK
68the slow side is infrequent enough that the overhead of the
69.BR membarrier ()
70calls does not outweigh the performance gain on the fast side.
efeece04 71.PP
d06aa1bf
MD
72The
73.I cmd
74argument is one of the following:
d06aa1bf 75.TP
26fac2d0 76.BR MEMBARRIER_CMD_QUERY " (since Linux 4.3)"
7e6241dc
MK
77Query the set of supported commands.
78The return value of the call is a bit mask of supported
d06aa1bf 79commands.
84015a22
MK
80.BR MEMBARRIER_CMD_QUERY ,
81which has the value 0,
82is not itself included in this bit mask.
83This command is always supported (on kernels where
84.BR membarrier ()
85is provided).
d06aa1bf 86.TP
8fb5a3b5 87.BR MEMBARRIER_CMD_GLOBAL " (since Linux 4.16)"
d06aa1bf
MD
88Ensure that all threads from all processes on the system pass through a
89state where all memory accesses to user-space addresses match program
7e6241dc
MK
90order between entry to and return from the
91.BR membarrier ()
92system call.
93All threads on the system are targeted by this command.
c50f154e 94.TP
8fb5a3b5 95.BR MEMBARRIER_CMD_GLOBAL_EXPEDITED " (since Linux 4.16)"
13d4ca14 96Execute a memory barrier on all running threads of all processes that
f5a563c0
MD
97previously registered with
98.BR MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED .
d8b2fd50 99.IP
e8edc891 100Upon return from the system call, the calling thread has a guarantee that all
f5a563c0
MD
101running threads have passed through a state where all memory accesses to
102user-space addresses match program order between entry to and return
103from the system call (non-running threads are de facto in such a state).
e8edc891
MK
104This guarantee is provided only for the threads of processes that
105previously registered with
f5a563c0 106.BR MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED .
d8b2fd50 107.IP
f5a563c0
MD
108Given that registration is about the intent to receive the barriers, it
109is valid to invoke
110.BR MEMBARRIER_CMD_GLOBAL_EXPEDITED
e8edc891
MK
111from a process that has not employed
112.BR MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED .
f5a563c0
MD
113.IP
114The "expedited" commands complete faster than the non-expedited ones;
115they never block, but have the downside of causing extra overhead.
116.TP
8fb5a3b5 117.BR MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED " (since Linux 4.16)"
13d4ca14 118Register the process's intent to receive
f5a563c0
MD
119.BR MEMBARRIER_CMD_GLOBAL_EXPEDITED
120memory barriers.
121.TP
8fb5a3b5 122.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED " (since Linux 4.14)"
c50f154e 123Execute a memory barrier on each running thread belonging to the same
e8edc891 124process as the calling thread.
d8b2fd50 125.IP
e8edc891
MK
126Upon return from the system call, the calling
127thread has a guarantee that all its running thread siblings have passed
c50f154e
MD
128through a state where all memory accesses to user-space addresses match
129program order between entry to and return from the system call
20fe2509 130(non-running threads are de facto in such a state).
e8edc891
MK
131This guarantee is provided only for threads in
132the same process as the calling thread.
d1555345
MK
133.IP
134The "expedited" commands complete faster than the non-expedited ones;
20fe2509 135they never block, but have the downside of causing extra overhead.
d8b2fd50 136.IP
e8edc891 137A process must register its intent to use the private
20fe2509 138expedited command prior to using it.
c50f154e 139.TP
8fb5a3b5 140.BR MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED " (since Linux 4.14)"
d1555345 141Register the process's intent to use
8fb5a3b5 142.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED .
f5a563c0 143.TP
8fb5a3b5 144.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE " (since Linux 4.16)"
13d4ca14 145In addition to providing the memory ordering guarantees described in
f5a563c0 146.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED ,
e8edc891
MK
147upon return from system call the calling thread has a guarantee that all its
148running thread siblings have executed a core serializing instruction.
149This guarantee is provided only for threads in
150the same process as the calling thread.
d8b2fd50 151.IP
f5a563c0 152The "expedited" commands complete faster than the non-expedited ones,
8d23228c 153they never block, but have the downside of causing extra overhead.
d8b2fd50 154.IP
e8edc891 155A process must register its intent to use the private expedited sync
f5a563c0
MD
156core command prior to using it.
157.TP
8fb5a3b5 158.BR MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE " (since Linux 4.16)"
13d4ca14 159Register the process's intent to use
f5a563c0
MD
160.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE .
161.TP
26fac2d0 162.BR MEMBARRIER_CMD_SHARED " (since Linux 4.3)"
46dc0687
MK
163This is an alias for
164.BR MEMBARRIER_CMD_GLOBAL
165that exists for header backward compatibility.
d06aa1bf
MD
166.PP
167The
168.I flags
7e6241dc 169argument is currently unused and must be specified as 0.
d06aa1bf
MD
170.PP
171All memory accesses performed in program order from each targeted thread
7e6241dc
MK
172are guaranteed to be ordered with respect to
173.BR membarrier ().
efeece04 174.PP
7e6241dc
MK
175If we use the semantic
176.I barrier()
177to represent a compiler barrier forcing memory
d06aa1bf 178accesses to be performed in program order across the barrier, and
7e6241dc
MK
179.I smp_mb()
180to represent explicit memory barriers forcing full memory
d06aa1bf 181ordering across the barrier, we have the following ordering table for
7e6241dc
MK
182each pairing of
183.IR barrier() ,
184.BR membarrier ()
185and
186.IR smp_mb() .
d06aa1bf 187The pair ordering is detailed as (O: ordered, X: not ordered):
efeece04 188.PP
7e6241dc
MK
189 barrier() smp_mb() membarrier()
190 barrier() X X O
191 smp_mb() X O O
51866840 192 membarrier() O O O
d06aa1bf 193.SH RETURN VALUE
9eb5be29
MK
194On success, the
195.B MEMBARRIER_CMD_QUERY
c50f154e 196operation returns a bit mask of supported commands, and the
8fb5a3b5
MK
197.BR MEMBARRIER_CMD_GLOBAL ,
198.BR MEMBARRIER_CMD_GLOBAL_EXPEDITED ,
199.BR MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED ,
200.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED ,
201.BR MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED ,
202.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE ,
f5a563c0
MD
203and
204.B MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE
c50f154e 205operations return zero.
7e6241dc 206On error, \-1 is returned,
d06aa1bf
MD
207and
208.I errno
209is set appropriately.
efeece04 210.PP
7a9c62ef
MK
211For a given command, with
212.I flags
213set to 0, this system call is
7e6241dc 214guaranteed to always return the same value until reboot.
7a9c62ef
MK
215Further calls with the same arguments will lead to the same result.
216Therefore, with
217.I flags
218set to 0, error handling is required only for the first call to
219.BR membarrier ().
d06aa1bf
MD
220.SH ERRORS
221.TP
d06aa1bf
MD
222.B EINVAL
223.I cmd
c50f154e 224is invalid, or
d06aa1bf 225.I flags
58440555 226is nonzero, or the
f5a563c0 227.BR MEMBARRIER_CMD_GLOBAL
c50f154e
MD
228command is disabled because the
229.I nohz_full
f5a563c0
MD
230CPU parameter has been set, or the
231.BR MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE
232and
233.BR MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE
234commands are not implemented by the architecture.
7e6241dc
MK
235.TP
236.B ENOSYS
237The
238.BR membarrier ()
239system call is not implemented by this kernel.
eddeaded 240.TP
c50f154e
MD
241.B EPERM
242The current process was not registered prior to using private expedited
243commands.
d06aa1bf 244.SH VERSIONS
7e6241dc
MK
245The
246.BR membarrier ()
247system call was added in Linux 4.3.
787dd4ad 248.\"
d06aa1bf
MD
249.SH CONFORMING TO
250.BR membarrier ()
251is Linux-specific.
ee595da3
MK
252.\" .SH SEE ALSO
253.\" FIXME See if the following syscalls make it into Linux 4.15 or later
254.\" .BR cpu_opv (2),
255.\" .BR rseq (2)
d06aa1bf 256.SH NOTES
d06aa1bf 257A memory barrier instruction is part of the instruction set of
7e6241dc
MK
258architectures with weakly-ordered memory models.
259It orders memory
d06aa1bf 260accesses prior to the barrier and after the barrier with respect to
7e6241dc
MK
261matching barriers on other cores.
262For instance, a load fence can order
d06aa1bf
MD
263loads prior to and following that fence with respect to stores ordered
264by store fences.
efeece04 265.PP
d06aa1bf
MD
266Program order is the order in which instructions are ordered in the
267program assembly code.
efeece04 268.PP
7e6241dc
MK
269Examples where
270.BR membarrier ()
271can be useful include implementations
9f4d4beb 272of Read-Copy-Update libraries and garbage collectors.
d06aa1bf 273.SH EXAMPLE
d06aa1bf
MD
274Assuming a multithreaded application where "fast_path()" is executed
275very frequently, and where "slow_path()" is executed infrequently, the
276following code (x86) can be transformed using
7e6241dc 277.BR membarrier ():
efeece04 278.PP
7e6241dc 279.in +4n
b8302363 280.EX
d06aa1bf
MD
281#include <stdlib.h>
282
283static volatile int a, b;
284
7e6241dc 285static void
b9aff60e 286fast_path(int *read_b)
d06aa1bf 287{
b9aff60e 288 a = 1;
7e6241dc 289 asm volatile ("mfence" : : : "memory");
b9aff60e 290 *read_b = b;
d06aa1bf
MD
291}
292
7e6241dc 293static void
b9aff60e 294slow_path(int *read_a)
d06aa1bf 295{
7e6241dc 296 b = 1;
b9aff60e
MD
297 asm volatile ("mfence" : : : "memory");
298 *read_a = a;
d06aa1bf
MD
299}
300
7e6241dc
MK
301int
302main(int argc, char **argv)
d06aa1bf 303{
b9aff60e
MD
304 int read_a, read_b;
305
7e6241dc
MK
306 /*
307 * Real applications would call fast_path() and slow_path()
308 * from different threads. Call those from main() to keep
309 * this example short.
310 */
311
b9aff60e
MD
312 slow_path(&read_a);
313 fast_path(&read_b);
314
315 /*
316 * read_b == 0 implies read_a == 1 and
317 * read_a == 0 implies read_b == 1.
318 */
319
320 if (read_b == 0 && read_a == 0)
321 abort();
7e6241dc
MK
322
323 exit(EXIT_SUCCESS);
d06aa1bf 324}
b8302363 325.EE
7e6241dc 326.in
efeece04 327.PP
7e6241dc
MK
328The code above transformed to use
329.BR membarrier ()
330becomes:
efeece04 331.PP
7e6241dc 332.in +4n
b8302363 333.EX
d06aa1bf
MD
334#define _GNU_SOURCE
335#include <stdlib.h>
336#include <stdio.h>
337#include <unistd.h>
338#include <sys/syscall.h>
339#include <linux/membarrier.h>
340
341static volatile int a, b;
342
7e6241dc
MK
343static int
344membarrier(int cmd, int flags)
d06aa1bf 345{
7e6241dc 346 return syscall(__NR_membarrier, cmd, flags);
d06aa1bf
MD
347}
348
7e6241dc
MK
349static int
350init_membarrier(void)
d06aa1bf 351{
7e6241dc
MK
352 int ret;
353
354 /* Check that membarrier() is supported. */
355
356 ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
357 if (ret < 0) {
358 perror("membarrier");
359 return \-1;
360 }
361
f5a563c0 362 if (!(ret & MEMBARRIER_CMD_GLOBAL)) {
7e6241dc 363 fprintf(stderr,
d1a71985 364 "membarrier does not support MEMBARRIER_CMD_GLOBAL\en");
7e6241dc
MK
365 return \-1;
366 }
367
368 return 0;
d06aa1bf
MD
369}
370
7e6241dc 371static void
b9aff60e 372fast_path(int *read_b)
d06aa1bf 373{
b9aff60e 374 a = 1;
7e6241dc 375 asm volatile ("" : : : "memory");
b9aff60e 376 *read_b = b;
d06aa1bf
MD
377}
378
7e6241dc 379static void
b9aff60e 380slow_path(int *read_a)
d06aa1bf 381{
7e6241dc 382 b = 1;
f5a563c0 383 membarrier(MEMBARRIER_CMD_GLOBAL, 0);
b9aff60e 384 *read_a = a;
d06aa1bf
MD
385}
386
7e6241dc
MK
387int
388main(int argc, char **argv)
d06aa1bf 389{
b9aff60e
MD
390 int read_a, read_b;
391
7e6241dc
MK
392 if (init_membarrier())
393 exit(EXIT_FAILURE);
394
395 /*
396 * Real applications would call fast_path() and slow_path()
397 * from different threads. Call those from main() to keep
398 * this example short.
399 */
400
b9aff60e
MD
401 slow_path(&read_a);
402 fast_path(&read_b);
403
404 /*
405 * read_b == 0 implies read_a == 1 and
406 * read_a == 0 implies read_b == 1.
407 */
408
409 if (read_b == 0 && read_a == 0)
410 abort();
7e6241dc
MK
411
412 exit(EXIT_SUCCESS);
d06aa1bf 413}
b8302363 414.EE
7e6241dc 415.in