History

Merge branch 'akpm' (patches from Andrew)

Merge fourth patch-bomb from Andrew Morton: - sys_membarier syscall - seq_file interface changes - a few misc fixups * emailed patches from Andrew Morton <akpm@linux-foundation.org>: revert "ocfs2/dlm: use list_for_each_entry instead of list_for_each" mm/early_ioremap: add explicit #include of asm/early_ioremap.h fs/seq_file: convert int seq_vprint/seq_printf/etc... returns to void selftests: enhance membarrier syscall test selftests: add membarrier syscall test sys_membarrier(): system-wide memory barrier (generic, x86) MODSIGN: fix a compilation warning in extract-cert

Linus Torvalds committed 11 years ago

Commit 01b0c012 parents 3ebb054 e527b2222 files · +336 −54Browse files

Unified · Split

22 files
  1. MAINTAINERS +8 −0
  2. arch/x86/entry/syscalls/syscall_32.tbl +1 −0
  3. arch/x86/entry/syscalls/syscall_64.tbl +1 −0
  4. drivers/iommu/omap-iommu-debug.c +2 −1
  5. fs/nsfs.c +2 −1
  6. fs/ocfs2/dlm/dlmrecovery.c +4 −2
  7. fs/seq_file.c +31 −39
  8. include/linux/seq_file.h +10 −9
  9. include/linux/syscalls.h +2 −0
  10. include/uapi/asm-generic/unistd.h +3 −1
  11. include/uapi/linux/Kbuild +1 −0
  12. include/uapi/linux/membarrier.h +53 −0
  13. init/Kconfig +12 −0
  14. kernel/Makefile +1 −0
  15. kernel/membarrier.c +66 −0
  16. kernel/sys_ni.c +3 −0
  17. mm/early_ioremap.c +1 −0
  18. scripts/extract-cert.c +1 −1
  19. tools/testing/selftests/Makefile +1 −0
  20. tools/testing/selftests/membarrier/.gitignore +1 −0
  21. tools/testing/selftests/membarrier/Makefile +11 −0
  22. tools/testing/selftests/membarrier/membarrier_test.c +121 −0
MAINTAINERS+8−0
@@ -6789,6 +6789,14 @@ W: http://www.mellanox.com · 6788 unmodified lines
67896789 Q: http://patchwork.ozlabs.org/project/netdev/list/
67906790 F: drivers/net/ethernet/mellanox/mlxsw/
67916791
6792+MEMBARRIER SUPPORT
6793+M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6794+M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
6795+L: linux-kernel@vger.kernel.org
6796+S: Supported
6797+F: kernel/membarrier.c
6798+F: include/uapi/linux/membarrier.h
6799+
67926800 MEMORY MANAGEMENT
67936801 L: linux-mm@kvack.org
67946802 W: http://www.linux-mm.org
arch/x86/entry/syscalls/syscall_32.tbl+1−0
@@ -381,3 +381,4 @@ · 380 unmodified lines
381381 372 i386 recvmsg sys_recvmsg compat_sys_recvmsg
382382 373 i386 shutdown sys_shutdown
383383 374 i386 userfaultfd sys_userfaultfd
384+375 i386 membarrier sys_membarrier
arch/x86/entry/syscalls/syscall_64.tbl+1−0
@@ -330,6 +330,7 @@ · 329 unmodified lines
330330 321 common bpf sys_bpf
331331 322 64 execveat stub_execveat
332332 323 common userfaultfd sys_userfaultfd
333+324 common membarrier sys_membarrier
333334
334335 #
335336 # x32-specific system call numbers start at 512 to avoid cache impact
drivers/iommu/omap-iommu-debug.c+2−1
@@ -135,8 +135,9 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num) · 134 unmodified lines
135135 static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr,
136136 struct seq_file *s)
137137 {
138− return seq_printf(s, "%08x %08x %01x\n", cr->cam, cr->ram,
138+ seq_printf(s, "%08x %08x %01x\n", cr->cam, cr->ram,
139139 (cr->cam & MMU_CAM_P) ? 1 : 0);
140+ return 0;
140141 }
141142
142143 static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)
fs/nsfs.c+2−1
@@ -142,7 +142,8 @@ static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry) · 141 unmodified lines
142142 struct inode *inode = d_inode(dentry);
143143 const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
144144
145− return seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino);
145+ seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino);
146+ return 0;
146147 }
147148
148149 static const struct super_operations nsfs_ops = {
fs/ocfs2/dlm/dlmrecovery.c+4−2
@@ -1776,7 +1776,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, · 1775 unmodified lines
17761776 struct dlm_migratable_lockres *mres)
17771777 {
17781778 struct dlm_migratable_lock *ml;
1779− struct list_head *queue;
1779+ struct list_head *queue, *iter;
17801780 struct list_head *tmpq = NULL;
17811781 struct dlm_lock *newlock = NULL;
17821782 struct dlm_lockstatus *lksb = NULL;
@@ -1821,7 +1821,9 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, · 38 unmodified lines
18211821 spin_lock(&res->spinlock);
18221822 for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) {
18231823 tmpq = dlm_list_idx_to_ptr(res, j);
1824− list_for_each_entry(lock, tmpq, list) {
1824+ list_for_each(iter, tmpq) {
1825+ lock = list_entry(iter,
1826+ struct dlm_lock, list);
18251827 if (lock->ml.cookie == ml->cookie)
18261828 break;
18271829 lock = NULL;
fs/seq_file.c+31−39
@@ -372,16 +372,16 @@ EXPORT_SYMBOL(seq_release); · 371 unmodified lines
372372 * @esc: set of characters that need escaping
373373 *
374374 * Puts string into buffer, replacing each occurrence of character from
375− * @esc with usual octal escape. Returns 0 in case of success, -1 - in
376− * case of overflow.
375+ * @esc with usual octal escape.
376+ * Use seq_has_overflowed() to check for errors.
377377 */
378−int seq_escape(struct seq_file *m, const char *s, const char *esc)
378+void seq_escape(struct seq_file *m, const char *s, const char *esc)
379379 {
380380 char *end = m->buf + m->size;
381− char *p;
381+ char *p;
382382 char c;
383383
384− for (p = m->buf + m->count; (c = *s) != '\0' && p < end; s++) {
384+ for (p = m->buf + m->count; (c = *s) != '\0' && p < end; s++) {
385385 if (!strchr(esc, c)) {
386386 *p++ = c;
387387 continue;
@@ -394,14 +394,13 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc) · 6 unmodified lines
394394 continue;
395395 }
396396 seq_set_overflow(m);
397− return -1;
398− }
397+ return;
398+ }
399399 m->count = p - m->buf;
400− return 0;
401400 }
402401 EXPORT_SYMBOL(seq_escape);
403402
404−int seq_vprintf(struct seq_file *m, const char *f, va_list args)
403+void seq_vprintf(struct seq_file *m, const char *f, va_list args)
405404 {
406405 int len;
407406
@@ -409,24 +408,20 @@ int seq_vprintf(struct seq_file *m, const char *f, va_list args) · 1 unmodified line
409408 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
410409 if (m->count + len < m->size) {
411410 m->count += len;
412− return 0;
411+ return;
413412 }
414413 }
415414 seq_set_overflow(m);
416− return -1;
417415 }
418416 EXPORT_SYMBOL(seq_vprintf);
419417
420−int seq_printf(struct seq_file *m, const char *f, ...)
418+void seq_printf(struct seq_file *m, const char *f, ...)
421419 {
422− int ret;
423420 va_list args;
424421
425422 va_start(args, f);
426− ret = seq_vprintf(m, f, args);
423+ seq_vprintf(m, f, args);
427424 va_end(args);
428−
429− return ret;
430425 }
431426 EXPORT_SYMBOL(seq_printf);
432427
@@ -664,26 +659,25 @@ int seq_open_private(struct file *filp, const struct seq_operations *ops, · 231 unmodified lines
664659 }
665660 EXPORT_SYMBOL(seq_open_private);
666661
667−int seq_putc(struct seq_file *m, char c)
662+void seq_putc(struct seq_file *m, char c)
668663 {
669− if (m->count < m->size) {
670− m->buf[m->count++] = c;
671− return 0;
672− }
673− return -1;
664+ if (m->count >= m->size)
665+ return;
666+
667+ m->buf[m->count++] = c;
674668 }
675669 EXPORT_SYMBOL(seq_putc);
676670
677−int seq_puts(struct seq_file *m, const char *s)
671+void seq_puts(struct seq_file *m, const char *s)
678672 {
679673 int len = strlen(s);
680− if (m->count + len < m->size) {
681− memcpy(m->buf + m->count, s, len);
682− m->count += len;
683− return 0;
674+
675+ if (m->count + len >= m->size) {
676+ seq_set_overflow(m);
677+ return;
684678 }
685− seq_set_overflow(m);
686− return -1;
679+ memcpy(m->buf + m->count, s, len);
680+ m->count += len;
687681 }
688682 EXPORT_SYMBOL(seq_puts);
689683
@@ -694,8 +688,8 @@ EXPORT_SYMBOL(seq_puts); · 4 unmodified lines
694688 * This routine is very quick when you show lots of numbers.
695689 * In usual cases, it will be better to use seq_printf(). It's easier to read.
696690 */
697−int seq_put_decimal_ull(struct seq_file *m, char delimiter,
698− unsigned long long num)
691+void seq_put_decimal_ull(struct seq_file *m, char delimiter,
692+ unsigned long long num)
699693 {
700694 int len;
701695
@@ -707,35 +701,33 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, · 5 unmodified lines
707701
708702 if (num < 10) {
709703 m->buf[m->count++] = num + '0';
710− return 0;
704+ return;
711705 }
712706
713707 len = num_to_str(m->buf + m->count, m->size - m->count, num);
714708 if (!len)
715709 goto overflow;
716710 m->count += len;
717− return 0;
711+ return;
712+
718713 overflow:
719714 seq_set_overflow(m);
720− return -1;
721715 }
722716 EXPORT_SYMBOL(seq_put_decimal_ull);
723717
724−int seq_put_decimal_ll(struct seq_file *m, char delimiter,
725− long long num)
718+void seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num)
726719 {
727720 if (num < 0) {
728721 if (m->count + 3 >= m->size) {
729722 seq_set_overflow(m);
730− return -1;
723+ return;
731724 }
732725 if (delimiter)
733726 m->buf[m->count++] = delimiter;
734727 num = -num;
735728 delimiter = '-';
736729 }
737− return seq_put_decimal_ull(m, delimiter, num);
738−
730+ seq_put_decimal_ull(m, delimiter, num);
739731 }
740732 EXPORT_SYMBOL(seq_put_decimal_ll);
741733
include/linux/seq_file.h+10−9
@@ -114,13 +114,18 @@ int seq_open(struct file *, const struct seq_operations *); · 113 unmodified lines
114114 ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
115115 loff_t seq_lseek(struct file *, loff_t, int);
116116 int seq_release(struct inode *, struct file *);
117−int seq_escape(struct seq_file *, const char *, const char *);
118−int seq_putc(struct seq_file *m, char c);
119−int seq_puts(struct seq_file *m, const char *s);
120117 int seq_write(struct seq_file *seq, const void *data, size_t len);
121118
122−__printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
123−__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);
119+__printf(2, 0)
120+void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
121+__printf(2, 3)
122+void seq_printf(struct seq_file *m, const char *fmt, ...);
123+void seq_putc(struct seq_file *m, char c);
124+void seq_puts(struct seq_file *m, const char *s);
125+void seq_put_decimal_ull(struct seq_file *m, char delimiter,
126+ unsigned long long num);
127+void seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num);
128+void seq_escape(struct seq_file *m, const char *s, const char *esc);
124129
125130 void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
126131 int rowsize, int groupsize, const void *buf, size_t len,
@@ -138,10 +143,6 @@ int single_release(struct inode *, struct file *); · 11 unmodified lines
138143 void *__seq_open_private(struct file *, const struct seq_operations *, int);
139144 int seq_open_private(struct file *, const struct seq_operations *, int);
140145 int seq_release_private(struct inode *, struct file *);
141−int seq_put_decimal_ull(struct seq_file *m, char delimiter,
142− unsigned long long num);
143−int seq_put_decimal_ll(struct seq_file *m, char delimiter,
144− long long num);
145146
146147 static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
147148 {
include/linux/syscalls.h+2−0
@@ -885,4 +885,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename, · 884 unmodified lines
885885 const char __user *const __user *argv,
886886 const char __user *const __user *envp, int flags);
887887
888+asmlinkage long sys_membarrier(int cmd, int flags);
889+
888890 #endif
include/uapi/asm-generic/unistd.h+3−1
@@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create) · 708 unmodified lines
709709 __SYSCALL(__NR_bpf, sys_bpf)
710710 #define __NR_execveat 281
711711 __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
712+#define __NR_membarrier 282
713+__SYSCALL(__NR_membarrier, sys_membarrier)
712714
713715 #undef __NR_syscalls
714−#define __NR_syscalls 282
716+#define __NR_syscalls 283
715717
716718 /*
717719 * All syscalls below here should go away really,
include/uapi/linux/Kbuild+1−0
@@ -252,6 +252,7 @@ header-y += mdio.h · 251 unmodified lines
252252 header-y += media.h
253253 header-y += media-bus-format.h
254254 header-y += mei.h
255+header-y += membarrier.h
255256 header-y += memfd.h
256257 header-y += mempolicy.h
257258 header-y += meye.h
include/uapi/linux/membarrier.h+53−0
@@ -0,0 +1,53 @@
1+#ifndef _UAPI_LINUX_MEMBARRIER_H
2+#define _UAPI_LINUX_MEMBARRIER_H
3+
4+/*
5+ * linux/membarrier.h
6+ *
7+ * membarrier system call API
8+ *
9+ * Copyright (c) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10+ *
11+ * Permission is hereby granted, free of charge, to any person obtaining a copy
12+ * of this software and associated documentation files (the "Software"), to deal
13+ * in the Software without restriction, including without limitation the rights
14+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+ * copies of the Software, and to permit persons to whom the Software is
16+ * furnished to do so, subject to the following conditions:
17+ *
18+ * The above copyright notice and this permission notice shall be included in
19+ * all copies or substantial portions of the Software.
20+ *
21+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+ * SOFTWARE.
28+ */
29+
30+/**
31+ * enum membarrier_cmd - membarrier system call command
32+ * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
33+ * a bitmask of valid commands.
34+ * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
35+ * Upon return from system call, the caller thread
36+ * is ensured that all running threads have passed
37+ * through a state where all memory accesses to
38+ * user-space addresses match program order between
39+ * entry to and return from the system call
40+ * (non-running threads are de facto in such a
41+ * state). This covers threads from all processes
42+ * running on the system. This command returns 0.
43+ *
44+ * Command to be passed to the membarrier system call. The commands need to
45+ * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
46+ * the value 0.
47+ */
48+enum membarrier_cmd {
49+ MEMBARRIER_CMD_QUERY = 0,
50+ MEMBARRIER_CMD_SHARED = (1 << 0),
51+};
52+
53+#endif /* _UAPI_LINUX_MEMBARRIER_H */
init/Kconfig+12−0
@@ -1602,6 +1602,18 @@ config PCI_QUIRKS · 1601 unmodified lines
16021602 bugs/quirks. Disable this only if your target machine is
16031603 unaffected by PCI quirks.
16041604
1605+config MEMBARRIER
1606+ bool "Enable membarrier() system call" if EXPERT
1607+ default y
1608+ help
1609+ Enable the membarrier() system call that allows issuing memory
1610+ barriers across all running threads, which can be used to distribute
1611+ the cost of user-space memory barriers asymmetrically by transforming
1612+ pairs of memory barriers into pairs consisting of membarrier() and a
1613+ compiler barrier.
1614+
1615+ If unsure, say Y.
1616+
16051617 config EMBEDDED
16061618 bool "Embedded system"
16071619 option allnoconfig_y
kernel/Makefile+1−0
@@ -100,6 +100,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o · 99 unmodified lines
100100 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
101101 obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
102102 obj-$(CONFIG_TORTURE_TEST) += torture.o
103+obj-$(CONFIG_MEMBARRIER) += membarrier.o
103104
104105 obj-$(CONFIG_HAS_IOMEM) += memremap.o
105106
kernel/membarrier.c+66−0
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3+ *
4+ * membarrier system call
5+ *
6+ * This program is free software; you can redistribute it and/or modify
7+ * it under the terms of the GNU General Public License as published by
8+ * the Free Software Foundation; either version 2 of the License, or
9+ * (at your option) any later version.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ */
16+
17+#include <linux/syscalls.h>
18+#include <linux/membarrier.h>
19+
20+/*
21+ * Bitmask made from a "or" of all commands within enum membarrier_cmd,
22+ * except MEMBARRIER_CMD_QUERY.
23+ */
24+#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED)
25+
26+/**
27+ * sys_membarrier - issue memory barriers on a set of threads
28+ * @cmd: Takes command values defined in enum membarrier_cmd.
29+ * @flags: Currently needs to be 0. For future extensions.
30+ *
31+ * If this system call is not implemented, -ENOSYS is returned. If the
32+ * command specified does not exist, or if the command argument is invalid,
33+ * this system call returns -EINVAL. For a given command, with flags argument
34+ * set to 0, this system call is guaranteed to always return the same value
35+ * until reboot.
36+ *
37+ * All memory accesses performed in program order from each targeted thread
38+ * is guaranteed to be ordered with respect to sys_membarrier(). If we use
39+ * the semantic "barrier()" to represent a compiler barrier forcing memory
40+ * accesses to be performed in program order across the barrier, and
41+ * smp_mb() to represent explicit memory barriers forcing full memory
42+ * ordering across the barrier, we have the following ordering table for
43+ * each pair of barrier(), sys_membarrier() and smp_mb():
44+ *
45+ * The pair ordering is detailed as (O: ordered, X: not ordered):
46+ *
47+ * barrier() smp_mb() sys_membarrier()
48+ * barrier() X X O
49+ * smp_mb() X O O
50+ * sys_membarrier() O O O
51+ */
52+SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
53+{
54+ if (unlikely(flags))
55+ return -EINVAL;
56+ switch (cmd) {
57+ case MEMBARRIER_CMD_QUERY:
58+ return MEMBARRIER_CMD_BITMASK;
59+ case MEMBARRIER_CMD_SHARED:
60+ if (num_online_cpus() > 1)
61+ synchronize_sched();
62+ return 0;
63+ default:
64+ return -EINVAL;
65+ }
66+}
kernel/sys_ni.c+3−0
@@ -245,3 +245,6 @@ cond_syscall(sys_bpf); · 244 unmodified lines
245245
246246 /* execveat */
247247 cond_syscall(sys_execveat);
248+
249+/* membarrier */
250+cond_syscall(sys_membarrier);
mm/early_ioremap.c+1−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/mm.h>
1616 #include <linux/vmalloc.h>
1717 #include <asm/fixmap.h>
18+#include <asm/early_ioremap.h>
1819
1920 #ifdef CONFIG_MMU
2021 static int early_ioremap_debug __initdata;
scripts/extract-cert.c+1−1
@@ -86,7 +86,7 @@ static void write_cert(X509 *x509) · 85 unmodified lines
8686 ERR(!wb, "%s", cert_dst);
8787 }
8888 X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf));
89− ERR(!i2d_X509_bio(wb, x509), cert_dst);
89+ ERR(!i2d_X509_bio(wb, x509), "%s", cert_dst);
9090 if (kbuild_verbose)
9191 fprintf(stderr, "Extracted cert: %s\n", buf);
9292 }
tools/testing/selftests/Makefile+1−0
@@ -6,6 +6,7 @@ TARGETS += firmware · 5 unmodified lines
66 TARGETS += ftrace
77 TARGETS += futex
88 TARGETS += kcmp
9+TARGETS += membarrier
910 TARGETS += memfd
1011 TARGETS += memory-hotplug
1112 TARGETS += mount
tools/testing/selftests/membarrier/.gitignore+1−0
@@ -0,0 +1 @@
1+membarrier_test
tools/testing/selftests/membarrier/Makefile+11−0
@@ -0,0 +1,11 @@
1+CFLAGS += -g -I../../../../usr/include/
2+
3+all:
4+ $(CC) $(CFLAGS) membarrier_test.c -o membarrier_test
5+
6+TEST_PROGS := membarrier_test
7+
8+include ../lib.mk
9+
10+clean:
11+ $(RM) membarrier_test
tools/testing/selftests/membarrier/membarrier_test.c+121−0
@@ -0,0 +1,121 @@
1+#define _GNU_SOURCE
2+#define __EXPORTED_HEADERS__
3+
4+#include <linux/membarrier.h>
5+#include <asm-generic/unistd.h>
6+#include <sys/syscall.h>
7+#include <stdio.h>
8+#include <errno.h>
9+#include <string.h>
10+
11+#include "../kselftest.h"
12+
13+enum test_membarrier_status {
14+ TEST_MEMBARRIER_PASS = 0,
15+ TEST_MEMBARRIER_FAIL,
16+ TEST_MEMBARRIER_SKIP,
17+};
18+
19+static int sys_membarrier(int cmd, int flags)
20+{
21+ return syscall(__NR_membarrier, cmd, flags);
22+}
23+
24+static enum test_membarrier_status test_membarrier_cmd_fail(void)
25+{
26+ int cmd = -1, flags = 0;
27+
28+ if (sys_membarrier(cmd, flags) != -1) {
29+ printf("membarrier: Wrong command should fail but passed.\n");
30+ return TEST_MEMBARRIER_FAIL;
31+ }
32+ return TEST_MEMBARRIER_PASS;
33+}
34+
35+static enum test_membarrier_status test_membarrier_flags_fail(void)
36+{
37+ int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
38+
39+ if (sys_membarrier(cmd, flags) != -1) {
40+ printf("membarrier: Wrong flags should fail but passed.\n");
41+ return TEST_MEMBARRIER_FAIL;
42+ }
43+ return TEST_MEMBARRIER_PASS;
44+}
45+
46+static enum test_membarrier_status test_membarrier_success(void)
47+{
48+ int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
49+
50+ if (sys_membarrier(cmd, flags) != 0) {
51+ printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n",
52+ strerror(errno));
53+ return TEST_MEMBARRIER_FAIL;
54+ }
55+
56+ printf("membarrier: MEMBARRIER_CMD_SHARED success.\n");
57+ return TEST_MEMBARRIER_PASS;
58+}
59+
60+static enum test_membarrier_status test_membarrier(void)
61+{
62+ enum test_membarrier_status status;
63+
64+ status = test_membarrier_cmd_fail();
65+ if (status)
66+ return status;
67+ status = test_membarrier_flags_fail();
68+ if (status)
69+ return status;
70+ status = test_membarrier_success();
71+ if (status)
72+ return status;
73+ return TEST_MEMBARRIER_PASS;
74+}
75+
76+static enum test_membarrier_status test_membarrier_query(void)
77+{
78+ int flags = 0, ret;
79+
80+ printf("membarrier MEMBARRIER_CMD_QUERY ");
81+ ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
82+ if (ret < 0) {
83+ printf("failed. %s.\n", strerror(errno));
84+ switch (errno) {
85+ case ENOSYS:
86+ /*
87+ * It is valid to build a kernel with
88+ * CONFIG_MEMBARRIER=n. However, this skips the tests.
89+ */
90+ return TEST_MEMBARRIER_SKIP;
91+ case EINVAL:
92+ default:
93+ return TEST_MEMBARRIER_FAIL;
94+ }
95+ }
96+ if (!(ret & MEMBARRIER_CMD_SHARED)) {
97+ printf("command MEMBARRIER_CMD_SHARED is not supported.\n");
98+ return TEST_MEMBARRIER_FAIL;
99+ }
100+ printf("syscall available.\n");
101+ return TEST_MEMBARRIER_PASS;
102+}
103+
104+int main(int argc, char **argv)
105+{
106+ switch (test_membarrier_query()) {
107+ case TEST_MEMBARRIER_FAIL:
108+ return ksft_exit_fail();
109+ case TEST_MEMBARRIER_SKIP:
110+ return ksft_exit_skip();
111+ }
112+ switch (test_membarrier()) {
113+ case TEST_MEMBARRIER_FAIL:
114+ return ksft_exit_fail();
115+ case TEST_MEMBARRIER_SKIP:
116+ return ksft_exit_skip();
117+ }
118+
119+ printf("membarrier: tests done!\n");
120+ return ksft_exit_pass();
121+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t