Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+336 -54
+8
MAINTAINERS
··· 6789 6789 Q: http://patchwork.ozlabs.org/project/netdev/list/ 6790 6790 F: drivers/net/ethernet/mellanox/mlxsw/ 6791 6791 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 + 6792 6800 MEMORY MANAGEMENT 6793 6801 L: linux-mm@kvack.org 6794 6802 W: http://www.linux-mm.org
+1
arch/x86/entry/syscalls/syscall_32.tbl
··· 381 381 372 i386 recvmsg sys_recvmsg compat_sys_recvmsg 382 382 373 i386 shutdown sys_shutdown 383 383 374 i386 userfaultfd sys_userfaultfd 384 + 375 i386 membarrier sys_membarrier
+1
arch/x86/entry/syscalls/syscall_64.tbl
··· 330 330 321 common bpf sys_bpf 331 331 322 64 execveat stub_execveat 332 332 323 common userfaultfd sys_userfaultfd 333 + 324 common membarrier sys_membarrier 333 334 334 335 # 335 336 # x32-specific system call numbers start at 512 to avoid cache impact
+2 -1
drivers/iommu/omap-iommu-debug.c
··· 135 135 static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr, 136 136 struct seq_file *s) 137 137 { 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, 139 139 (cr->cam & MMU_CAM_P) ? 1 : 0); 140 + return 0; 140 141 } 141 142 142 143 static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)
+2 -1
fs/nsfs.c
··· 142 142 struct inode *inode = d_inode(dentry); 143 143 const struct proc_ns_operations *ns_ops = dentry->d_fsdata; 144 144 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; 146 147 } 147 148 148 149 static const struct super_operations nsfs_ops = {
+4 -2
fs/ocfs2/dlm/dlmrecovery.c
··· 1776 1776 struct dlm_migratable_lockres *mres) 1777 1777 { 1778 1778 struct dlm_migratable_lock *ml; 1779 - struct list_head *queue; 1779 + struct list_head *queue, *iter; 1780 1780 struct list_head *tmpq = NULL; 1781 1781 struct dlm_lock *newlock = NULL; 1782 1782 struct dlm_lockstatus *lksb = NULL; ··· 1821 1821 spin_lock(&res->spinlock); 1822 1822 for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) { 1823 1823 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); 1825 1827 if (lock->ml.cookie == ml->cookie) 1826 1828 break; 1827 1829 lock = NULL;
+31 -39
fs/seq_file.c
··· 372 372 * @esc: set of characters that need escaping 373 373 * 374 374 * 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. 377 377 */ 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) 379 379 { 380 380 char *end = m->buf + m->size; 381 - char *p; 381 + char *p; 382 382 char c; 383 383 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++) { 385 385 if (!strchr(esc, c)) { 386 386 *p++ = c; 387 387 continue; ··· 394 394 continue; 395 395 } 396 396 seq_set_overflow(m); 397 - return -1; 398 - } 397 + return; 398 + } 399 399 m->count = p - m->buf; 400 - return 0; 401 400 } 402 401 EXPORT_SYMBOL(seq_escape); 403 402 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) 405 404 { 406 405 int len; 407 406 ··· 408 409 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args); 409 410 if (m->count + len < m->size) { 410 411 m->count += len; 411 - return 0; 412 + return; 412 413 } 413 414 } 414 415 seq_set_overflow(m); 415 - return -1; 416 416 } 417 417 EXPORT_SYMBOL(seq_vprintf); 418 418 419 - int seq_printf(struct seq_file *m, const char *f, ...) 419 + void seq_printf(struct seq_file *m, const char *f, ...) 420 420 { 421 - int ret; 422 421 va_list args; 423 422 424 423 va_start(args, f); 425 - ret = seq_vprintf(m, f, args); 424 + seq_vprintf(m, f, args); 426 425 va_end(args); 427 - 428 - return ret; 429 426 } 430 427 EXPORT_SYMBOL(seq_printf); 431 428 ··· 659 664 } 660 665 EXPORT_SYMBOL(seq_open_private); 661 666 662 - int seq_putc(struct seq_file *m, char c) 667 + void seq_putc(struct seq_file *m, char c) 663 668 { 664 - if (m->count < m->size) { 665 - m->buf[m->count++] = c; 666 - return 0; 667 - } 668 - return -1; 669 + if (m->count >= m->size) 670 + return; 671 + 672 + m->buf[m->count++] = c; 669 673 } 670 674 EXPORT_SYMBOL(seq_putc); 671 675 672 - int seq_puts(struct seq_file *m, const char *s) 676 + void seq_puts(struct seq_file *m, const char *s) 673 677 { 674 678 int len = strlen(s); 675 - if (m->count + len < m->size) { 676 - memcpy(m->buf + m->count, s, len); 677 - m->count += len; 678 - return 0; 679 + 680 + if (m->count + len >= m->size) { 681 + seq_set_overflow(m); 682 + return; 679 683 } 680 - seq_set_overflow(m); 681 - return -1; 684 + memcpy(m->buf + m->count, s, len); 685 + m->count += len; 682 686 } 683 687 EXPORT_SYMBOL(seq_puts); 684 688 ··· 688 694 * This routine is very quick when you show lots of numbers. 689 695 * In usual cases, it will be better to use seq_printf(). It's easier to read. 690 696 */ 691 - int seq_put_decimal_ull(struct seq_file *m, char delimiter, 692 - unsigned long long num) 697 + void seq_put_decimal_ull(struct seq_file *m, char delimiter, 698 + unsigned long long num) 693 699 { 694 700 int len; 695 701 ··· 701 707 702 708 if (num < 10) { 703 709 m->buf[m->count++] = num + '0'; 704 - return 0; 710 + return; 705 711 } 706 712 707 713 len = num_to_str(m->buf + m->count, m->size - m->count, num); 708 714 if (!len) 709 715 goto overflow; 710 716 m->count += len; 711 - return 0; 717 + return; 718 + 712 719 overflow: 713 720 seq_set_overflow(m); 714 - return -1; 715 721 } 716 722 EXPORT_SYMBOL(seq_put_decimal_ull); 717 723 718 - int seq_put_decimal_ll(struct seq_file *m, char delimiter, 719 - long long num) 724 + void seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num) 720 725 { 721 726 if (num < 0) { 722 727 if (m->count + 3 >= m->size) { 723 728 seq_set_overflow(m); 724 - return -1; 729 + return; 725 730 } 726 731 if (delimiter) 727 732 m->buf[m->count++] = delimiter; 728 733 num = -num; 729 734 delimiter = '-'; 730 735 } 731 - return seq_put_decimal_ull(m, delimiter, num); 732 - 736 + seq_put_decimal_ull(m, delimiter, num); 733 737 } 734 738 EXPORT_SYMBOL(seq_put_decimal_ll); 735 739
+10 -9
include/linux/seq_file.h
··· 114 114 ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); 115 115 loff_t seq_lseek(struct file *, loff_t, int); 116 116 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); 120 117 int seq_write(struct seq_file *seq, const void *data, size_t len); 121 118 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); 124 129 125 130 void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type, 126 131 int rowsize, int groupsize, const void *buf, size_t len, ··· 143 138 void *__seq_open_private(struct file *, const struct seq_operations *, int); 144 139 int seq_open_private(struct file *, const struct seq_operations *, int); 145 140 int seq_release_private(struct inode *, struct file *); 146 - int seq_put_decimal_ull(struct seq_file *m, char delimiter, 147 - unsigned long long num); 148 - int seq_put_decimal_ll(struct seq_file *m, char delimiter, 149 - long long num); 150 141 151 142 static inline struct user_namespace *seq_user_ns(struct seq_file *seq) 152 143 {
+2
include/linux/syscalls.h
··· 885 885 const char __user *const __user *argv, 886 886 const char __user *const __user *envp, int flags); 887 887 888 + asmlinkage long sys_membarrier(int cmd, int flags); 889 + 888 890 #endif
+3 -1
include/uapi/asm-generic/unistd.h
··· 709 709 __SYSCALL(__NR_bpf, sys_bpf) 710 710 #define __NR_execveat 281 711 711 __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat) 712 + #define __NR_membarrier 282 713 + __SYSCALL(__NR_membarrier, sys_membarrier) 712 714 713 715 #undef __NR_syscalls 714 - #define __NR_syscalls 282 716 + #define __NR_syscalls 283 715 717 716 718 /* 717 719 * All syscalls below here should go away really,
+1
include/uapi/linux/Kbuild
··· 252 252 header-y += media.h 253 253 header-y += media-bus-format.h 254 254 header-y += mei.h 255 + header-y += membarrier.h 255 256 header-y += memfd.h 256 257 header-y += mempolicy.h 257 258 header-y += meye.h
+53
include/uapi/linux/membarrier.h
··· 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 */
+12
init/Kconfig
··· 1602 1602 bugs/quirks. Disable this only if your target machine is 1603 1603 unaffected by PCI quirks. 1604 1604 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 + 1605 1617 config EMBEDDED 1606 1618 bool "Embedded system" 1607 1619 option allnoconfig_y
+1
kernel/Makefile
··· 100 100 obj-$(CONFIG_JUMP_LABEL) += jump_label.o 101 101 obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o 102 102 obj-$(CONFIG_TORTURE_TEST) += torture.o 103 + obj-$(CONFIG_MEMBARRIER) += membarrier.o 103 104 104 105 obj-$(CONFIG_HAS_IOMEM) += memremap.o 105 106
+66
kernel/membarrier.c
··· 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 + }
+3
kernel/sys_ni.c
··· 245 245 246 246 /* execveat */ 247 247 cond_syscall(sys_execveat); 248 + 249 + /* membarrier */ 250 + cond_syscall(sys_membarrier);
+1
mm/early_ioremap.c
··· 15 15 #include <linux/mm.h> 16 16 #include <linux/vmalloc.h> 17 17 #include <asm/fixmap.h> 18 + #include <asm/early_ioremap.h> 18 19 19 20 #ifdef CONFIG_MMU 20 21 static int early_ioremap_debug __initdata;
+1 -1
scripts/extract-cert.c
··· 86 86 ERR(!wb, "%s", cert_dst); 87 87 } 88 88 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); 90 90 if (kbuild_verbose) 91 91 fprintf(stderr, "Extracted cert: %s\n", buf); 92 92 }
+1
tools/testing/selftests/Makefile
··· 6 6 TARGETS += ftrace 7 7 TARGETS += futex 8 8 TARGETS += kcmp 9 + TARGETS += membarrier 9 10 TARGETS += memfd 10 11 TARGETS += memory-hotplug 11 12 TARGETS += mount
+1
tools/testing/selftests/membarrier/.gitignore
··· 1 + membarrier_test
+11
tools/testing/selftests/membarrier/Makefile
··· 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
+121
tools/testing/selftests/membarrier/membarrier_test.c
··· 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 + }