This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Linux: Add membarrier system call wrapper
- From: Florian Weimer <fweimer at redhat dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Cc: "Paul E. McKenney" <paulmck at linux dot vnet dot ibm dot com>, Mathieu Desnoyers <mathieu dot desnoyers at efficios dot com>, Torvald Riegel <triegel at redhat dot com>
- Date: Thu, 21 Dec 2017 15:08:54 +0100
- Subject: [PATCH] Linux: Add membarrier system call wrapper
- Authentication-results: sourceware.org; auth=none
The documentation part of this patch was circulated off-list previously.
The text received some positive feedback, some criticism, but no one
proposed an alternative wording.
Due to lack of consensus, we could add the system call without
documentation. I do not think the documentation issue should block
acceptance of the system call wrapper.
Thanks,
Florian
Subject: [PATCH] Linux: Add membarrier system call wrapper
To: libc-alpha@sourceware.org
2017-12-20 Florian Weimer <fweimer@redhat.com>
Linux: Add membarrier system call wrapper.
* manual/memory.texi (Memory): Reference Memory Barriers.
(Memory Barriers): New node.
* sysdeps/unix/sysv/linux/Makefile [misc] (sysdep_routines): Add
membarrier.
[misc] (tests): Add tst-membarrier.
* sysdeps/unix/sysv/linux/Versions (GLIBC_2.17): Export membarrier.
* sysdeps/unix/sysv/linux/bits/mman-shared.h
(MEMBARRIER_CMD_QUERY, MEMBARRIER_CMD_SHARED)
(MEMBARRIER_CMD_PRIVATE_EXPEDITED)
(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED): Define.
(membarrier): Declare.
* sysdeps/unix/sysv/linux/syscalls.list (membarrier): Add.
* sysdeps/unix/sysv/linux/tst-membarrier.c: New file.
* sysdeps/unix/sysv/linux/**.abilist: Update.
diff --git a/manual/memory.texi b/manual/memory.texi
index b95f6aa1b9..276b132d8b 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -19,6 +19,7 @@ and allocation of real memory.
* Resizing the Data Segment:: @code{brk}, @code{sbrk}
* Memory Protection:: Controlling access to memory regions.
* Locking Pages:: Preventing page faults
+* Memory Barriers:: System support for concurrent programming.
@end menu
Memory mapped I/O is not discussed in this chapter. @xref{Memory-mapped I/O}.
@@ -3839,3 +3840,99 @@ full, and when it becomes 95% full. Above 95% you get another warning
each time memory usage increases.
@end ignore
+
+@node Memory Barriers
+@section Memory Barriers
+@cindex fences
+@cindex barriers
+@cindex memory barriers
+@cindex concurrency barriers
+
+This section discusses facilities which implement certain forms of
+memory barriers which can be used in the implementation of concurrent
+algorithms. Note that these barriers can be very costly and do not by
+themselves ensure the correct operation of concurrent algorithms.
+
+The barriers discussed here do not imply compiler barriers, which have
+to be supplied separately by the programmer (for example, using
+@samp{atomic_signal_fence (memory_order_acq_rel)} in C11 and later, or
+@samp{std::atomic_signal_fence (std::memory_order_acq_rel)} in C++11 and
+later). Alternatively, you can use the GCC builtin,
+@samp{__atomic_signal_fence (__ATOMIC_ACQ_REL)}. @xref{__atomic
+Builtins, __atomic Builtins, Built-in Functions for Memory Model Aware
+Atomic Operations, gcc, The GNU Compiler Collection}.
+
+@deftypefun int membarrier (int @var{op}, int @var{flags})
+@standards{Linux, sys/mman.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This function performs operations related to memory barriers, depending
+on the value of @var{op}.
+
+The @var{flags} argument is currently reserved and must be zero.
+
+For the operations which perform a memory barrier, there is a set of
+participating threads. For these threads, the @code{membarrier}
+function call turns an existing compiler barrier (see above) executed by
+these threads into full memory barriers (of the
+@samp{atomic_thread_fence (memory_order_acq_rel)} variety).
+
+The @var{op} argument is one of the following values. Except for
+@code{MEMBARRIER_CMD_QUERY}, these values are powers of two:
+
+@vtable @code
+@item MEMBARRIER_CMD_QUERY
+@standards{Linux, sys/mman.h}
+
+Return a bitmap of the @code{MEMBARRIER_CMD_}* operations supported by
+this system. An application can check whether a particular
+@code{MEMBARRIER_CMD_}* (except @code{MEMBARRIER_CMD_QUERY} itself) is
+supported by calling @samp{membarrier (MEMBARRIER_CMD_QUERY, 0)} and
+checking if the @code{MEMBARRIER_CMD_}* bit is set in the result.
+
+@item MEMBARRIER_CMD_SHARED
+@standards{Linux, sys/mman.h}
+
+This command performs a memory barrier, and the set of participating
+threads consists of all threads in the system. On success, the return
+value is @math{0}.
+
+@item MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED
+@standards{Linux, sys/mman.h}
+
+This command advertises that this process might perform a
+@code{MEMBARRIER_CMD_PRIVATE_EXPEDITED} memory in the future. It does
+not itself perform a barrier. On success, the return value is @math{0}.
+
+@item MEMBARRIER_CMD_PRIVATE_EXPEDITED
+@standards{Linux, sys/mman.h}
+
+This command performs a memory barrier, and the set of participating
+threads consists of all threads belonging to the current process. This
+type of barrier is less costly than the system-wide barrier provided by
+@code{MEMBARRIER_CMD_SHARED}.
+
+This command fails unless it has previously been enabled using the
+@code{MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED} command.
+
+On success, the return value is @math{0}.
+@end vtable
+
+The @code{membarrier} function returns @math{-1} on failure. The
+following @code{errno} values are specific to this function:
+
+@table @code
+@item ENOSYS
+The system does not implement this function.
+
+@item EINVAL
+The @var{op} argument is not valid, or the @var{flags} argument is not
+zero.
+
+@item EPERM
+An attempt was made to perform a @code{MEMBARRIER_CMD_PRIVATE_EXPEDITED}
+memory barrier without first registering the intent using
+@code{MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED}.
+
+@end table
+
+@end deftypefun
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 8a17828d9d..efcb467c32 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -18,7 +18,8 @@ sysdep_routines += clone umount umount2 readahead \
setfsuid setfsgid epoll_pwait signalfd \
eventfd eventfd_read eventfd_write prlimit \
personality epoll_wait tee vmsplice splice \
- open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get
+ open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \
+ membarrier
CFLAGS-gethostid.c = -fexceptions
CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
@@ -44,7 +45,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
- test-errno-linux tst-memfd_create tst-mlock2 tst-pkey
+ test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
+ tst-membarrier \
# Generate the list of SYS_* macros for the system calls (__NR_*
# macros). The file syscall-names.list contains all possible system
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 336c13b57d..7698b2beb2 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -170,6 +170,7 @@ libc {
memfd_create;
mlock2;
pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect;
+ membarrier;
}
GLIBC_PRIVATE {
# functions used in other libraries
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index ec0ead15dd..4ba25d00e2 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 5355769974..f6deada3ae 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2017,6 +2017,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 9bafe71b51..8153d24b0a 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -107,6 +107,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/bits/mman-shared.h b/sysdeps/unix/sysv/linux/bits/mman-shared.h
index 9e532adb23..c998b64759 100644
--- a/sysdeps/unix/sysv/linux/bits/mman-shared.h
+++ b/sysdeps/unix/sysv/linux/bits/mman-shared.h
@@ -39,6 +39,14 @@
# define PKEY_DISABLE_WRITE 0x2
# endif
+/* Command values for membarrier. */
+# ifndef MEMBARRIER_CMD_QUERY
+# define MEMBARRIER_CMD_QUERY 0
+# define MEMBARRIER_CMD_SHARED 1
+# define MEMBARRIER_CMD_PRIVATE_EXPEDITED 8
+# define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED 16
+# endif
+
__BEGIN_DECLS
/* Create a new memory file descriptor. NAME is a name for debugging.
@@ -71,6 +79,9 @@ int pkey_free (int __key) __THROW;
range. */
int pkey_mprotect (void *__addr, size_t __len, int __prot, int __pkey) __THROW;
+/* Perform a memory barrier on multiple threads. */
+int membarrier (int __op, int __flags) __THROW;
+
__END_DECLS
#endif /* __USE_GNU */
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 90aa8d034f..eaf8d74265 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1871,6 +1871,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 4d44c30c64..6c5fef6852 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2036,6 +2036,7 @@ GLIBC_2.26 wcstof128_l F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 112fc57634..07a1212b71 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1900,6 +1900,7 @@ GLIBC_2.26 wcstof128_l F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 2e8b6a4586..35885743dc 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 3c33400f67..14ab516721 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1985,6 +1985,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index e1b1a579d2..3cadb1a176 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2106,6 +2106,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index c1550323f3..7689032095 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1960,6 +1960,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 3b3a172e4f..cd6211d985 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1958,6 +1958,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 101ca7a241..0d19e1f56c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1956,6 +1956,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 2d129f7170..ae51b78081 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1951,6 +1951,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 8bc350aff8..57d909d7f7 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2147,6 +2147,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 127c426e1c..2bf065039a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index a9411318e2..89c859d2be 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1994,6 +1994,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index d7bf5db601..018fd34be7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2201,6 +2201,7 @@ GLIBC_2.26 wcstof128_l F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index a3415a72ac..f3e8475052 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -108,6 +108,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 414338f9a2..dc6f8e91bc 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index f0f7a69b64..ccef685f4e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1890,6 +1890,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 9f95aba898..8c499219a4 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1875,6 +1875,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 83fbdf2d7e..e09b9a488a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1982,6 +1982,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index ee84ad10bc..dafb177878 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1919,6 +1919,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index e3dfd0c8db..65b3d6f9dc 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -112,3 +112,4 @@ process_vm_writev EXTRA process_vm_writev i:ipipii process_vm_writev
memfd_create EXTRA memfd_create i:si memfd_create
pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc
pkey_free EXTRA pkey_free i:i pkey_free
+membarrier EXTRA membarrier i:ii membarrier
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx32/libc.abilist
index dcbfbc05ac..cbbf622825 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx32/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx64/libc.abilist
index 53dc99c45a..8a87aa20cb 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx64/libc.abilist
@@ -2113,6 +2113,7 @@ GLIBC_2.26 reallocarray F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/tst-membarrier.c b/sysdeps/unix/sysv/linux/tst-membarrier.c
new file mode 100644
index 0000000000..1065785ae0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-membarrier.c
@@ -0,0 +1,61 @@
+/* Tests for the membarrier function.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <sys/mman.h>
+
+static int
+do_test (void)
+{
+ int supported = membarrier (MEMBARRIER_CMD_QUERY, 0);
+ if (supported == -1)
+ {
+ if (errno == ENOSYS)
+ FAIL_UNSUPPORTED ("membarrier system call not iplemented");
+ else
+ FAIL_EXIT1 ("membarrier: %m");
+ }
+
+ if (supported & MEMBARRIER_CMD_SHARED)
+ {
+ puts ("info: MEMBARRIER_CMD_SHARED supported");
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_SHARED, 0), 0);
+ }
+ else
+ puts ("info: MEMBARRIER_CMD_SHARED not supported");
+
+ /* If the private-expedited barrier is advertised, execute it after
+ registering the intent. */
+ if (supported & MEMBARRIER_CMD_PRIVATE_EXPEDITED)
+ {
+ puts ("info: MEMBARRIER_CMD_PRIVATE_EXPEDITED supported");
+ TEST_COMPARE (supported & MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED);
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0),
+ 0);
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0), 0);
+ }
+ else
+ puts ("info: MEMBARRIER_CMD_PRIVATE_EXPEDITED not supported");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index ae4dcaa47e..9ac3118b26 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1877,6 +1877,7 @@ GLIBC_2.26 wcstof128_l F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 0dbda14796..2359a7cd48 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2120,6 +2120,7 @@ GLIBC_2.26 wcstof128_l F
GLIBC_2.27 GLIBC_2.27 A
GLIBC_2.27 glob F
GLIBC_2.27 glob64 F
+GLIBC_2.27 membarrier F
GLIBC_2.27 memfd_create F
GLIBC_2.27 mlock2 F
GLIBC_2.27 pkey_alloc F