Discussion:
[PATCH] Linux: Implement membarrier function
(too old to reply)
Florian Weimer
2018-11-28 15:05:01 UTC
Permalink
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.

I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.

Thanks,
Florian

2018-11-28 Florian Weimer <***@redhat.com>

Linux: Implement membarrier function.
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
sys/membarrier.h.
(tests): Add tst-membarrier.
* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add membarrier.
* sysdeps/unix/sysv/linux/sys/membarrier.h: New file.
* sysdeps/unix/sysv/linux/tst-membarrier.c: Likewise.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist (GLIBC_2.29): Add
membarrier.
* sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist (GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/hppa/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/i386/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/ia64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/microblaze/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/nios2/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist (GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist (GLIBC_2.29):
Likewise.

diff --git a/NEWS b/NEWS
index 1098be1afb..d5786f4eab 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,9 @@ Major new features:
different directory. This is a GNU extension and similar to the
Solaris function of the same name.

+* The membarrier function and the <sys/membarrier.h> header file have been
+ added.
+
Deprecated and removed features, and other changes affecting compatibility:

* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 362cf3b950..f8c4843ab6 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -43,12 +43,13 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
bits/siginfo-arch.h bits/siginfo-consts-arch.h \
bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
bits/procfs-prregset.h bits/mman-map-flags-generic.h \
- bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h
+ bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h \
+ sys/membarrier.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 \
- tst-rlimit-infinity tst-ofdlocks
+ tst-rlimit-infinity tst-ofdlocks tst-membarrier
tests-internal += tst-ofdlocks-compat


diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 336c13b57d..86db06f403 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -171,6 +171,9 @@ libc {
mlock2;
pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect;
}
+ GLIBC_2.29 {
+ membarrier;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index e66c741d04..c73c731eec 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2138,4 +2138,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 8df162fe99..c9488b3c18 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2033,6 +2033,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 43c804f9dc..2524b6545b 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 88b01c2e75..9baaa34b62 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1880,6 +1880,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 6d02f31612..1b91873f65 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2045,6 +2045,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 4249712611..1b3465c6f4 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1914,6 +1914,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index d47b808862..db22eb4a12 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index d5e38308be..5a93b98e76 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 8596b84399..0142b573ca 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2130,4 +2130,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 88e0f896d5..a84db6e3f4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1967,6 +1967,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index aff7462c34..aed9d20fa5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1965,6 +1965,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 71d82444aa..d117ad299e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1973,6 +1973,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index de6c53d293..3598a33eca 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1968,6 +1968,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e724bab9fb..7ce4aa1841 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2171,4 +2171,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index e9ecbccb71..50fedd0fab 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1993,6 +1993,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index da83ea6028..86862b6e16 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1997,6 +1997,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 4535b40d15..57c0e67347 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2228,4 +2228,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 65725de4f0..7658e2c2b9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 _Exit F
GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index bbb3c4a8e7..f4020e881d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2100,4 +2100,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index e85ac2a178..9476770e5b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2002,6 +2002,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index d56931022c..ee9a87659f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1908,6 +1908,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 __fentry__ F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index ff939a15c4..c2dd2a5f7e 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1884,6 +1884,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 64fa9e10a5..55c6496b96 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1996,6 +1996,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index db909d1506..a0e7f2f221 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1937,6 +1937,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sys/membarrier.h b/sysdeps/unix/sysv/linux/sys/membarrier.h
new file mode 100644
index 0000000000..4c3e6164f7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sys/membarrier.h
@@ -0,0 +1,55 @@
+/* Memory barriers.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _SYS_MEMBARRIER_H
+#define _SYS_MEMBARRIER_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Perform a memory barrier on multiple threads. */
+int membarrier (int __op, int __flags) __THROW;
+
+__END_DECLS
+
+/* Obtain the definitions of the MEMBARRIER_CMD_* constants. */
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
+# include <linux/membarrier.h>
+#else
+
+/* Definitions from Linux 4.16 follow. */
+
+enum membarrier_cmd
+{
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = 1,
+ MEMBARRIER_CMD_GLOBAL = 1,
+ MEMBARRIER_CMD_GLOBAL_EXPEDITED = 2,
+ MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = 4,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = 8,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = 16,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = 32,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = 64,
+};
+
+#endif
+
+#endif /* _SYS_MEMBARRIER_H */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index e24ea29e35..3deee2bc19 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/tst-membarrier.c b/sysdeps/unix/sysv/linux/tst-membarrier.c
new file mode 100644
index 0000000000..aeaccad578
--- /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/membarrier.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 implemented");
+ else
+ FAIL_EXIT1 ("membarrier: %m");
+ }
+
+ if ((supported & MEMBARRIER_CMD_GLOBAL) == 0)
+ FAIL_UNSUPPORTED ("global memory barriers not supported");
+
+ puts ("info: membarrier is supported on this system");
+
+ /* The global barrier is always implemented. */
+ TEST_COMPARE (supported & MEMBARRIER_CMD_GLOBAL, MEMBARRIER_CMD_GLOBAL);
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_GLOBAL, 0), 0);
+
+ /* If the private-expedited barrier is advertised, execute it after
+ registering the intent. */
+ if (supported & MEMBARRIER_CMD_PRIVATE_EXPEDITED)
+ {
+ 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 3b175f104b..f097eb86e2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1895,6 +1895,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 1b57710477..afb1a196fa 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2146,4 +2146,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Torvald Riegel
2018-11-28 22:34:26 UTC
Permalink
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
Florian Weimer
2018-11-29 13:50:39 UTC
Permalink
Post by Torvald Riegel
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
I wrote down what you could, but no one liked it.

<https://sourceware.org/ml/libc-alpha/2017-12/msg00796.html>

I expect that a formalization would interact in non-trivial ways with
any potential formalization of usable relaxed memory order semantics,
and I'm not sure if anyone knows how to do the latter today.

Thanks,
Florian
Mathieu Desnoyers
2018-11-29 14:44:22 UTC
Permalink
Post by Florian Weimer
Post by Torvald Riegel
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
I wrote down what you could, but no one liked it.
<https://sourceware.org/ml/libc-alpha/2017-12/msg00796.html>
I expect that a formalization would interact in non-trivial ways with
any potential formalization of usable relaxed memory order semantics,
and I'm not sure if anyone knows how to do the latter today.
Adding Paul E. McKenney in CC.

Thanks,

Mathieu
Post by Florian Weimer
Thanks,
Florian
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
Paul E. McKenney
2018-11-29 15:04:33 UTC
Permalink
Post by Mathieu Desnoyers
Post by Florian Weimer
Post by Torvald Riegel
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
I wrote down what you could, but no one liked it.
<https://sourceware.org/ml/libc-alpha/2017-12/msg00796.html>
I expect that a formalization would interact in non-trivial ways with
any potential formalization of usable relaxed memory order semantics,
and I'm not sure if anyone knows how to do the latter today.
Adding Paul E. McKenney in CC.
There is some prototype C++ memory model wording from David Goldblatt (CCed)
here (search for "Standarese"):

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1202r0.pdf

David's key insight is that (in Linuxese) light fences cannot pair with
each other.

Thanx, Paul
David Goldblatt
2018-11-29 19:02:17 UTC
Permalink
One note with the suggested patch is that
`atomic_thread_fence(memory_order_acq_rel)` should probably be
`atomic_thread_fence (memory_order_seq_cst)` (otherwise the call would
be a no-op on, say, x86, which it very much isn't).

The non-transitivity thing makes the resulting description arguably
incorrect, but this is informal enough that it might not be a big deal
to add something after "For these threads, the membarrier function
call turns an existing compiler barrier (see above) executed by these
threads into full memory barriers" that clarifies it. E.g. you could
make it into "turns an existing compiler barrier [...] into full
memory barriers, with respect to the calling thread".

Since this is targeting the description of the OS call (and doesn't
have to concern itself with also being implementable by other
asymmetric techniques or degrading to architectural barriers), I think
that the description in "approach 2" in P1202 would also make sense
for a formal description of the syscall. (Of course, without the
kernel itself committing to a rigorous semantics, anything specified
on top of it will be on slightly shaky ground).

- David
Post by Paul E. McKenney
Post by Mathieu Desnoyers
Post by Florian Weimer
Post by Torvald Riegel
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
I wrote down what you could, but no one liked it.
<https://sourceware.org/ml/libc-alpha/2017-12/msg00796.html>
I expect that a formalization would interact in non-trivial ways with
any potential formalization of usable relaxed memory order semantics,
and I'm not sure if anyone knows how to do the latter today.
Adding Paul E. McKenney in CC.
There is some prototype C++ memory model wording from David Goldblatt (CCed)
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1202r0.pdf
David's key insight is that (in Linuxese) light fences cannot pair with
each other.
Thanx, Paul
Paul E. McKenney
2018-12-06 21:54:05 UTC
Permalink
Hello, David,

I took a crack at extending LKMM to accommodate what I think would
support what you have in your paper. Please see the very end of this
email for a patch against the "dev" branch of my -rcu tree.

This gives the expected result for the following three litmus tests,
but is probably deficient or otherwise misguided in other ways. I have
added the LKMM maintainers on CC for their amusement. ;-)

Thoughts?

Thanx, Paul

------------------------------------------------------------------------

C C-Goldblat-memb-1
{
}

P0(int *x0, int *x1)
{
WRITE_ONCE(*x0, 1);
r1 = READ_ONCE(*x1);
}


P1(int *x0, int *x1)
{
WRITE_ONCE(*x1, 1);
smp_memb();
r2 = READ_ONCE(*x0);
}

exists (0:r1=0 /\ 1:r2=0)

------------------------------------------------------------------------

C C-Goldblat-memb-2
{
}

P0(int *x0, int *x1)
{
WRITE_ONCE(*x0, 1);
r1 = READ_ONCE(*x1);
}


P1(int *x1, int *x2)
{
WRITE_ONCE(*x1, 1);
smp_memb();
r1 = READ_ONCE(*x2);
}

P2(int *x2, int *x0)
{
WRITE_ONCE(*x2, 1);
r1 = READ_ONCE(*x0);
}

exists (0:r1=0 /\ 1:r1=0 /\ 2:r1=0)

------------------------------------------------------------------------

C C-Goldblat-memb-3
{
}

P0(int *x0, int *x1)
{
WRITE_ONCE(*x0, 1);
r1 = READ_ONCE(*x1);
}


P1(int *x1, int *x2)
{
WRITE_ONCE(*x1, 1);
smp_memb();
r1 = READ_ONCE(*x2);
}

P2(int *x2, int *x3)
{
WRITE_ONCE(*x2, 1);
r1 = READ_ONCE(*x3);
}

P3(int *x3, int *x0)
{
WRITE_ONCE(*x3, 1);
smp_memb();
r1 = READ_ONCE(*x0);
}

exists (0:r1=0 /\ 1:r1=0 /\ 2:r1=0 /\ 3:r1=0)

------------------------------------------------------------------------
Post by David Goldblatt
One note with the suggested patch is that
`atomic_thread_fence(memory_order_acq_rel)` should probably be
`atomic_thread_fence (memory_order_seq_cst)` (otherwise the call would
be a no-op on, say, x86, which it very much isn't).
The non-transitivity thing makes the resulting description arguably
incorrect, but this is informal enough that it might not be a big deal
to add something after "For these threads, the membarrier function
call turns an existing compiler barrier (see above) executed by these
threads into full memory barriers" that clarifies it. E.g. you could
make it into "turns an existing compiler barrier [...] into full
memory barriers, with respect to the calling thread".
Since this is targeting the description of the OS call (and doesn't
have to concern itself with also being implementable by other
asymmetric techniques or degrading to architectural barriers), I think
that the description in "approach 2" in P1202 would also make sense
for a formal description of the syscall. (Of course, without the
kernel itself committing to a rigorous semantics, anything specified
on top of it will be on slightly shaky ground).
- David
Post by Paul E. McKenney
Post by Mathieu Desnoyers
Post by Florian Weimer
Post by Torvald Riegel
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Fair enough. Nonetheless, can you summarize how far you're along with
properly defining the semantics (eg, based on the C/C++ memory model)?
I wrote down what you could, but no one liked it.
<https://sourceware.org/ml/libc-alpha/2017-12/msg00796.html>
I expect that a formalization would interact in non-trivial ways with
any potential formalization of usable relaxed memory order semantics,
and I'm not sure if anyone knows how to do the latter today.
Adding Paul E. McKenney in CC.
There is some prototype C++ memory model wording from David Goldblatt (CCed)
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1202r0.pdf
David's key insight is that (in Linuxese) light fences cannot pair with
each other.
------------------------------------------------------------------------

commit 17e3b6b60e57d1cb791f68a1a6a36e942cb2baad
Author: Paul E. McKenney <***@linux.ibm.com>
Date: Thu Dec 6 13:40:40 2018 -0800

EXP tools/memory-model: Add semantics for sys_membarrier()

This prototype commit extends LKMM to accommodate sys_membarrier(),
which is a asymmetric barrier with a limited ability to insert full
ordering into tasks that provide only compiler ordering. This commit
currently uses the "po" relation for this purpose, but something more
sophisticated will be required when plain accesses are added, which
the compiler can reorder.

For more detail, please see David Goldblatt's C++ working paper:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1202r0.pdf

Signed-off-by: Paul E. McKenney <***@linux.ibm.com>

diff --git a/tools/memory-model/linux-kernel.bell b/tools/memory-model/linux-kernel.bell
index 9c42cd9ddcb4..4ef41453f569 100644
--- a/tools/memory-model/linux-kernel.bell
+++ b/tools/memory-model/linux-kernel.bell
@@ -24,6 +24,7 @@ instructions RMW[{'once,'acquire,'release}]
enum Barriers = 'wmb (*smp_wmb*) ||
'rmb (*smp_rmb*) ||
'mb (*smp_mb*) ||
+ 'memb (*sys_membarrier*) ||
'rcu-lock (*rcu_read_lock*) ||
'rcu-unlock (*rcu_read_unlock*) ||
'sync-rcu (*synchronize_rcu*) ||
diff --git a/tools/memory-model/linux-kernel.cat b/tools/memory-model/linux-kernel.cat
index 8dcb37835b61..837c3ee20bea 100644
--- a/tools/memory-model/linux-kernel.cat
+++ b/tools/memory-model/linux-kernel.cat
@@ -33,9 +33,10 @@ let mb = ([M] ; fencerel(Mb) ; [M]) |
([M] ; po? ; [LKW] ; fencerel(After-spinlock) ; [M]) |
([M] ; po ; [UL] ; (co | po) ; [LKW] ;
fencerel(After-unlock-lock) ; [M])
+let memb = [M] ; fencerel(Memb) ; [M]
let gp = po ; [Sync-rcu | Sync-srcu] ; po?

-let strong-fence = mb | gp
+let strong-fence = mb | gp | memb

(* Release Acquire *)
let acq-po = [Acquire] ; po ; [M]
@@ -86,6 +87,13 @@ acyclic hb as happens-before
let pb = prop ; strong-fence ; hb*
acyclic pb as propagation

+(********************)
+(* sys_membarrier() *)
+(********************)
+
+let memb-step = ( prop ; po ; prop )? ; memb
+acyclic memb-step as memb-before
+
(*******)
(* RCU *)
(*******)
diff --git a/tools/memory-model/linux-kernel.def b/tools/memory-model/linux-kernel.def
index 1d6a120cde14..9ff0691c5f2c 100644
--- a/tools/memory-model/linux-kernel.def
+++ b/tools/memory-model/linux-kernel.def
@@ -17,6 +17,7 @@ rcu_dereference(X) __load{once}(X)
smp_store_mb(X,V) { __store{once}(X,V); __fence{mb}; }

// Fences
+smp_memb() { __fence{memb}; }
smp_mb() { __fence{mb}; }
smp_rmb() { __fence{rmb}; }
smp_wmb() { __fence{wmb}; }
Paul E. McKenney
2018-12-10 18:25:16 UTC
Permalink
Post by Paul E. McKenney
Hello, David,
I took a crack at extending LKMM to accommodate what I think would
support what you have in your paper. Please see the very end of this
email for a patch against the "dev" branch of my -rcu tree.
This gives the expected result for the following three litmus tests,
but is probably deficient or otherwise misguided in other ways. I have
added the LKMM maintainers on CC for their amusement. ;-)
Thoughts?
Since sys_membarrier() provides a heavyweight barrier comparable to
synchronize_rcu(), the memory model should treat the two in the same
way. That's what this patch does.
The corresponding critical section would be any region of code bounded
by compiler barriers. Since the LKMM doesn't currently handle plain
accesses, the effect is the same as if a compiler barrier were present
between each pair of instructions. Basically, each instruction acts as
its own critical section. Therefore the patch below defines memb-rscsi
as the trivial identity relation. When plain accesses and compiler
barriers are added to the memory model, a different definition will be
needed.
This gives the correct results for the three C-Goldblat-memb-* litmus
tests in Paul's email.
Yow!!!

My first reaction was that this cannot possibly be correct because
sys_membarrier(), which is probably what we should call it, does not
wait for anything. But your formulation has the corresponding readers
being "id", which as you say above is just a single event.

But what makes this work for the following litmus test?

------------------------------------------------------------------------

C membrcu

{
}

P0(intptr_t *x0, intptr_t *x1)
{
WRITE_ONCE(*x0, 2);
smp_memb();
intptr_t r2 = READ_ONCE(*x1);
}


P1(intptr_t *x1, intptr_t *x2)
{
WRITE_ONCE(*x1, 2);
smp_memb();
intptr_t r2 = READ_ONCE(*x2);
}


P2(intptr_t *x2, intptr_t *x3)
{
WRITE_ONCE(*x2, 2);
smp_memb();
intptr_t r2 = READ_ONCE(*x3);
}


P3(intptr_t *x3, intptr_t *x4)
{
rcu_read_lock();
WRITE_ONCE(*x3, 2);
intptr_t r2 = READ_ONCE(*x4);
rcu_read_unlock();
}


P4(intptr_t *x4, intptr_t *x5)
{
rcu_read_lock();
WRITE_ONCE(*x4, 2);
intptr_t r2 = READ_ONCE(*x5);
rcu_read_unlock();
}


P5(intptr_t *x0, intptr_t *x5)
{
rcu_read_lock();
WRITE_ONCE(*x5, 2);
intptr_t r2 = READ_ONCE(*x0);
rcu_read_unlock();
}

exists
(5:r2=0 /\ 0:r2=0 /\ 1:r2=0 /\ 2:r2=0 /\ 3:r2=0 /\ 4:r2=0)

------------------------------------------------------------------------

For this, herd gives "Never". Of course, if I reverse the write and
read in any of P3(), P4(), or P5(), I get "Sometimes", which does make
sense. But what is preserving the order between P3() and P4() and
between P4() and P5()? I am not immediately seeing how the analogy
with RCU carries over to this case.

Thanx, Paul
Alan
PS: The patch below is meant to apply on top of the SRCU patches, which
are not yet in the mainline kernel.
Index: usb-4.x/tools/memory-model/linux-kernel.bell
===================================================================
--- usb-4.x.orig/tools/memory-model/linux-kernel.bell
+++ usb-4.x/tools/memory-model/linux-kernel.bell
@@ -24,6 +24,7 @@ instructions RMW[{'once,'acquire,'releas
enum Barriers = 'wmb (*smp_wmb*) ||
'rmb (*smp_rmb*) ||
'mb (*smp_mb*) ||
+ 'memb (*sys_membarrier*) ||
'rcu-lock (*rcu_read_lock*) ||
'rcu-unlock (*rcu_read_unlock*) ||
'sync-rcu (*synchronize_rcu*) ||
Index: usb-4.x/tools/memory-model/linux-kernel.cat
===================================================================
--- usb-4.x.orig/tools/memory-model/linux-kernel.cat
+++ usb-4.x/tools/memory-model/linux-kernel.cat
@@ -33,7 +33,7 @@ let mb = ([M] ; fencerel(Mb) ; [M]) |
([M] ; po? ; [LKW] ; fencerel(After-spinlock) ; [M]) |
([M] ; po ; [UL] ; (co | po) ; [LKW] ;
fencerel(After-unlock-lock) ; [M])
-let gp = po ; [Sync-rcu | Sync-srcu] ; po?
+let gp = po ; [Sync-rcu | Sync-srcu | Memb] ; po?
let strong-fence = mb | gp
@@ -102,8 +102,10 @@ acyclic pb as propagation
*)
let rcu-gp = [Sync-rcu] (* Compare with gp *)
let srcu-gp = [Sync-srcu]
+let memb-gp = [Memb]
let rcu-rscsi = rcu-rscs^-1
let srcu-rscsi = srcu-rscs^-1
+let memb-rscsi = id
(*
* The synchronize_rcu() strong fence is special in that it can order not
@@ -119,15 +121,19 @@ let rcu-link = po? ; hb* ; pb* ; prop ;
* the synchronize_srcu() and srcu_read_[un]lock() calls refer to the same
* struct srcu_struct location.
*)
-let rec rcu-fence = rcu-gp | srcu-gp |
+let rec rcu-fence = rcu-gp | srcu-gp | memb-gp |
(rcu-gp ; rcu-link ; rcu-rscsi) |
((srcu-gp ; rcu-link ; srcu-rscsi) & loc) |
+ (memb-gp ; rcu-link ; memb-rscsi) |
(rcu-rscsi ; rcu-link ; rcu-gp) |
((srcu-rscsi ; rcu-link ; srcu-gp) & loc) |
+ (memb-rscsi ; rcu-link ; memb-gp) |
(rcu-gp ; rcu-link ; rcu-fence ; rcu-link ; rcu-rscsi) |
((srcu-gp ; rcu-link ; rcu-fence ; rcu-link ; srcu-rscsi) & loc) |
+ (memb-gp ; rcu-link ; rcu-fence ; rcu-link ; memb-rscsi) |
(rcu-rscsi ; rcu-link ; rcu-fence ; rcu-link ; rcu-gp) |
((srcu-rscsi ; rcu-link ; rcu-fence ; rcu-link ; srcu-gp) & loc) |
+ (memb-rscsi ; rcu-link ; rcu-fence ; rcu-link ; memb-gp) |
(rcu-fence ; rcu-link ; rcu-fence)
(* rb orders instructions just as pb does *)
Index: usb-4.x/tools/memory-model/linux-kernel.def
===================================================================
--- usb-4.x.orig/tools/memory-model/linux-kernel.def
+++ usb-4.x/tools/memory-model/linux-kernel.def
@@ -20,6 +20,7 @@ smp_store_mb(X,V) { __store{once}(X,V);
smp_mb() { __fence{mb}; }
smp_rmb() { __fence{rmb}; }
smp_wmb() { __fence{wmb}; }
+smp_memb() { __fence{memb}; }
smp_mb__before_atomic() { __fence{before-atomic}; }
smp_mb__after_atomic() { __fence{after-atomic}; }
smp_mb__after_spinlock() { __fence{after-spinlock}; }
Florian Weimer
2018-12-05 13:20:06 UTC
Permalink
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
Any comments on the technical aspects of the patch? I would like to
commit this.

<https://sourceware.org/ml/libc-alpha/2018-11/msg00750.html>

Thanks,
Florian
Joseph Myers
2018-12-05 16:28:03 UTC
Permalink
Are you going to open a bug report in Bugzilla for the lack of
documentation (discussing exactly what the issues are that need to be
clarified to document the function)?

If in any particular case there is sufficient justification for not
documenting a new function, I'd expect such a bug report as a minimum to
say what needs to be done to add documentation. (The most common case for
not adding documentation is probably that the function joins a whole
family of existing functions lacking documentation, in which case one bug
report for the whole family suffices, like bug 10891 covering all the *_l
functions missing documentation.)
--
Joseph S. Myers
***@codesourcery.com
Florian Weimer
2018-12-05 19:59:38 UTC
Permalink
Post by Joseph Myers
Are you going to open a bug report in Bugzilla for the lack of
documentation (discussing exactly what the issues are that need to be
clarified to document the function)?
A filed a bug for the general issue of lack of documentation for the
memory model:

<https://sourceware.org/bugzilla/show_bug.cgi?id=23955>

Thanks,
Florian
Adhemerval Zanella
2018-12-05 14:12:18 UTC
Permalink
Post by Florian Weimer
This is essentially a repost of last year's patch, rebased to the glibc
2.29 symbol version and reflecting the introduction of
MEMBARRIER_CMD_GLOBAL.
I'm not including any changes to manual/ here because the set of
supported operations is evolving rapidly, we could not get consensus for
the language I proposed the last time, and I do not want to contribute
to the manual for the time being.
I agree that documentation might be added in a subsequent patch. The only
issue I have with this patch is how to handle the kernel header, see comments
below.
Post by Florian Weimer
Thanks,
Florian
Linux: Implement membarrier function.
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
sys/membarrier.h.
(tests): Add tst-membarrier.
* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add membarrier.
* sysdeps/unix/sysv/linux/sys/membarrier.h: New file.
* sysdeps/unix/sysv/linux/tst-membarrier.c: Likewise.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist (GLIBC_2.29): Add
membarrier.
Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist (GLIBC_2.29): Likewise.
Likewise.
Likewise.
Likewise.
Likewise.
Likewise.
Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
(GLIBC_2.29): Likewise.
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
(GLIBC_2.29): Likewise.
Likewise.
Likewise.
Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist (GLIBC_2.29): Likewise.
Likewise.
Likewise.
Likewise.
Likewise.
diff --git a/NEWS b/NEWS
index 1098be1afb..d5786f4eab 100644
--- a/NEWS
+++ b/NEWS
different directory. This is a GNU extension and similar to the
Solaris function of the same name.
+* The membarrier function and the <sys/membarrier.h> header file have been
+ added.
+
* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
Please make explicit this is a Linux only interface.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 362cf3b950..f8c4843ab6 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -43,12 +43,13 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
bits/siginfo-arch.h bits/siginfo-consts-arch.h \
bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
bits/procfs-prregset.h bits/mman-map-flags-generic.h \
- bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h
+ bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h \
+ sys/membarrier.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 \
- tst-rlimit-infinity tst-ofdlocks
+ tst-rlimit-infinity tst-ofdlocks tst-membarrier
tests-internal += tst-ofdlocks-compat
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 336c13b57d..86db06f403 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -171,6 +171,9 @@ libc {
mlock2;
pkey_alloc; pkey_free; pkey_set; pkey_get; pkey_mprotect;
}
+ GLIBC_2.29 {
+ membarrier;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index e66c741d04..c73c731eec 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2138,4 +2138,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 8df162fe99..c9488b3c18 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2033,6 +2033,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 43c804f9dc..2524b6545b 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 88b01c2e75..9baaa34b62 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1880,6 +1880,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 6d02f31612..1b91873f65 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2045,6 +2045,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 4249712611..1b3465c6f4 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1914,6 +1914,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index d47b808862..db22eb4a12 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.4 _Exit F
GLIBC_2.4 _IO_2_1_stderr_ D 0x98
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index d5e38308be..5a93b98e76 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1989,6 +1989,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 8596b84399..0142b573ca 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2130,4 +2130,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 88e0f896d5..a84db6e3f4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1967,6 +1967,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index aff7462c34..aed9d20fa5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1965,6 +1965,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 71d82444aa..d117ad299e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1973,6 +1973,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index de6c53d293..3598a33eca 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1968,6 +1968,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index e724bab9fb..7ce4aa1841 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2171,4 +2171,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index e9ecbccb71..50fedd0fab 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1993,6 +1993,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index da83ea6028..86862b6e16 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1997,6 +1997,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 4535b40d15..57c0e67347 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2228,4 +2228,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 65725de4f0..7658e2c2b9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -123,6 +123,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 _Exit F
GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index bbb3c4a8e7..f4020e881d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2100,4 +2100,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index e85ac2a178..9476770e5b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2002,6 +2002,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index d56931022c..ee9a87659f 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1908,6 +1908,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 __fentry__ F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index ff939a15c4..c2dd2a5f7e 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1884,6 +1884,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 64fa9e10a5..55c6496b96 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1996,6 +1996,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index db909d1506..a0e7f2f221 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1937,6 +1937,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/sys/membarrier.h b/sysdeps/unix/sysv/linux/sys/membarrier.h
new file mode 100644
index 0000000000..4c3e6164f7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sys/membarrier.h
@@ -0,0 +1,55 @@
+/* Memory barriers.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _SYS_MEMBARRIER_H
+#define _SYS_MEMBARRIER_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Perform a memory barrier on multiple threads. */
+int membarrier (int __op, int __flags) __THROW;
+
+__END_DECLS
+
+/* Obtain the definitions of the MEMBARRIER_CMD_* constants. */
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
+# include <linux/membarrier.h>
+#else
+
+/* Definitions from Linux 4.16 follow. */
+
+enum membarrier_cmd
+{
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = 1,
+ MEMBARRIER_CMD_GLOBAL = 1,
+ MEMBARRIER_CMD_GLOBAL_EXPEDITED = 2,
+ MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = 4,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = 8,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = 16,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = 32,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = 64,
+};
+
+#endif
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?

Also I think the minimum kernel that provides this header is 4.3, however
by using 4.3 as the condition to include the kernel header in add another
issue which is glibc will have different semantic depending of the installed
header. This fallback enum definition is also lacking MEMBARRIER_CMD_SHARED,
and although is provided by kernel headers just for compatibility, it is
another interface difference it has depending of the installed kernel
header.

Personally I prefer to decouple glibc headers from kernel ones, so I would
go just with define membarrier_cmd (and the flags once its is implemented
by kernel) with the burden of keep them in sync with kernel releases (as
we do for various syscalls and headers).
Post by Florian Weimer
+
+#endif /* _SYS_MEMBARRIER_H */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index e24ea29e35..3deee2bc19 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
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/tst-membarrier.c b/sysdeps/unix/sysv/linux/tst-membarrier.c
new file mode 100644
index 0000000000..aeaccad578
--- /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.
Update copyright year.
Post by Florian Weimer
+ 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/membarrier.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 implemented");
+ else
+ FAIL_EXIT1 ("membarrier: %m");
+ }
+
+ if ((supported & MEMBARRIER_CMD_GLOBAL) == 0)
+ FAIL_UNSUPPORTED ("global memory barriers not supported");
+
+ puts ("info: membarrier is supported on this system");
+
+ /* The global barrier is always implemented. */
+ TEST_COMPARE (supported & MEMBARRIER_CMD_GLOBAL, MEMBARRIER_CMD_GLOBAL);
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_GLOBAL, 0), 0);
+
+ /* If the private-expedited barrier is advertised, execute it after
+ registering the intent. */
+ if (supported & MEMBARRIER_CMD_PRIVATE_EXPEDITED)
+ {
+ 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>
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 3b175f104b..f097eb86e2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1895,6 +1895,7 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
Ok.
Post by Florian Weimer
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 1b57710477..afb1a196fa 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2146,4 +2146,5 @@ GLIBC_2.28 thrd_current F
GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
Ok.
Florian Weimer
2018-12-05 14:51:42 UTC
Permalink
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.

If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
Post by Adhemerval Zanella
Also I think the minimum kernel that provides this header is 4.3, however
by using 4.3 as the condition to include the kernel header in add another
issue which is glibc will have different semantic depending of the installed
header. This fallback enum definition is also lacking MEMBARRIER_CMD_SHARED,
and although is provided by kernel headers just for compatibility, it is
another interface difference it has depending of the installed kernel
header.
MEMBARRIER_CMD_SHARED is included.

Thanks,
Florian
Adhemerval Zanella
2018-12-05 16:54:08 UTC
Permalink
Post by Florian Weimer
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.
If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
My point is exactly to *not* rely on kernel headers.
Post by Florian Weimer
Post by Adhemerval Zanella
Also I think the minimum kernel that provides this header is 4.3, however
by using 4.3 as the condition to include the kernel header in add another
issue which is glibc will have different semantic depending of the installed
header. This fallback enum definition is also lacking MEMBARRIER_CMD_SHARED,
and although is provided by kernel headers just for compatibility, it is
another interface difference it has depending of the installed kernel
header.
MEMBARRIER_CMD_SHARED is included.
Right, my mistake here.
Florian Weimer
2018-12-05 18:11:22 UTC
Permalink
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.
If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
My point is exactly to *not* rely on kernel headers.
I thought there was a general desire to move in the opposite direction,
avoiding copying declarations and definitions in clean/new headers that
are dedicated to a specific purpose?

I don't think we can add much value by copying the contents of those
headers. We can even relax the version check if we use __has_include
(which has to be remain optional in installed headers, of course).

Thanks,
Florian
Adhemerval Zanella
2018-12-05 19:15:24 UTC
Permalink
Post by Florian Weimer
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.
If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
My point is exactly to *not* rely on kernel headers.
I thought there was a general desire to move in the opposite direction,
avoiding copying declarations and definitions in clean/new headers that
are dedicated to a specific purpose?
I don't recall this discussion, do you have the link? In any case I still
think mixing header inclusion with the definition duplication is just
a double effort, it will still require syncing the definitions on each
kernel release.
Post by Florian Weimer
I don't think we can add much value by copying the contents of those
headers. We can even relax the version check if we use __has_include
(which has to be remain optional in installed headers, of course).
This example give us why trying to relying in kernel header to provide
glibc exported interfaces are at least tricky, imho. The issues I can
think of are:

- The header would require to be include safe in all possible releases
and for all possible permutations, which means if something is broken
we need to rely on kernel to actually fix it.

- glibc might provide different semantic to users depending of the
underlying installed kernel header version. It means for two
identical glibc versions, some programs might fail to build
depending of the installed kernel version.
Florian Weimer
2018-12-05 19:53:14 UTC
Permalink
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.
If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
My point is exactly to *not* rely on kernel headers.
I thought there was a general desire to move in the opposite direction,
avoiding copying declarations and definitions in clean/new headers that
are dedicated to a specific purpose?
I don't recall this discussion, do you have the link?
I will try to find it.
Post by Adhemerval Zanella
In any case I still think mixing header inclusion with the definition
duplication is just a double effort, it will still require syncing the
definitions on each kernel release.
I think that's not actually true. We only need to do this if we need
newer definitions for building glibc itself (including the test suite).
Post by Adhemerval Zanella
Post by Florian Weimer
I don't think we can add much value by copying the contents of those
headers. We can even relax the version check if we use __has_include
(which has to be remain optional in installed headers, of course).
This example give us why trying to relying in kernel header to provide
glibc exported interfaces are at least tricky, imho. The issues I can
- The header would require to be include safe in all possible releases
and for all possible permutations, which means if something is broken
we need to rely on kernel to actually fix it.
I'm not too worried about this for new headers with a dedicated purpose.
Using the UAPI will actually make things work in more cases; see below.
Post by Adhemerval Zanella
- glibc might provide different semantic to users depending of the
underlying installed kernel header version. It means for two
identical glibc versions, some programs might fail to build
depending of the installed kernel version.
Well, that already happens with the duplicated header approach if users
want to use UAPI headers, too. It requires complicated synchronization
to make it work.

We can tweak the conditional for the header inclusion further, like
this:

+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) \
+ || __glibc_has_include (<linux/membarrier.h>) \
+# include <linux/membarrier.h>
+#else

With GCC 5 and later, this would always prefer the kernel header if
available. There would never be a conflict between the definitions,
irrespective of header file inclusion order.

What do you think?

Thanks,
Florian
Adhemerval Zanella
2018-12-05 20:17:53 UTC
Permalink
Post by Florian Weimer
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
Post by Florian Weimer
Post by Adhemerval Zanella
If we are replicating the values, meaning the idea is to keep it sync at least
when we have the minimum supported kernel of 4.16, why just not add a comment
to add linux/membarrier.h once the minimum supported kernel provides this
header and not rely on linux/membarrier.h?
This way, we can compile the test with any supported kernel headers for
glibc.
If we defer to <linux/membarrier.h> unconditionally, we cannot build the
test with all kernel headers. The current approach definitely makes the
test case much cleaner.
My point is exactly to *not* rely on kernel headers.
I thought there was a general desire to move in the opposite direction,
avoiding copying declarations and definitions in clean/new headers that
are dedicated to a specific purpose?
I don't recall this discussion, do you have the link?
I will try to find it.
Post by Adhemerval Zanella
In any case I still think mixing header inclusion with the definition
duplication is just a double effort, it will still require syncing the
definitions on each kernel release.
I think that's not actually true. We only need to do this if we need
newer definitions for building glibc itself (including the test suite).
Post by Adhemerval Zanella
Post by Florian Weimer
I don't think we can add much value by copying the contents of those
headers. We can even relax the version check if we use __has_include
(which has to be remain optional in installed headers, of course).
This example give us why trying to relying in kernel header to provide
glibc exported interfaces are at least tricky, imho. The issues I can
- The header would require to be include safe in all possible releases
and for all possible permutations, which means if something is broken
we need to rely on kernel to actually fix it.
I'm not too worried about this for new headers with a dedicated purpose.
Using the UAPI will actually make things work in more cases; see below.
Post by Adhemerval Zanella
- glibc might provide different semantic to users depending of the
underlying installed kernel header version. It means for two
identical glibc versions, some programs might fail to build
depending of the installed kernel version.
Well, that already happens with the duplicated header approach if users
want to use UAPI headers, too. It requires complicated synchronization
to make it work.
But at least glibc is not imposing it, if user want to use kernel uapi
header he will explicit include it and it is up to kernel provide a sane
implementation.
Post by Florian Weimer
We can tweak the conditional for the header inclusion further, like
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) \
+ || __glibc_has_include (<linux/membarrier.h>) \
+# include <linux/membarrier.h>
+#else
With GCC 5 and later, this would always prefer the kernel header if
available. There would never be a conflict between the definitions,
irrespective of header file inclusion order.
What do you think?
In any case I don't think my suggestion should be a blocker, we already rely
on linux header for some cases and it seems I am alone in trying to decouple
glibc from kernel headers.
Loading...