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
6789Q: http://patchwork.ozlabs.org/project/netdev/list/6789Q: http://patchwork.ozlabs.org/project/netdev/list/
6790F: drivers/net/ethernet/mellanox/mlxsw/6790F: drivers/net/ethernet/mellanox/mlxsw/
6791 6791
6792MEMBARRIER SUPPORT
6793M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6794M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
6795L: linux-kernel@vger.kernel.org
6796S: Supported
6797F: kernel/membarrier.c
6798F: include/uapi/linux/membarrier.h
6799
6792MEMORY MANAGEMENT6800MEMORY MANAGEMENT
6793L: linux-mm@kvack.org6801L: linux-mm@kvack.org
6794W: http://www.linux-mm.org6802W: http://www.linux-mm.org
arch/x86/entry/syscalls/syscall_32.tbl+1−0
@@ -381,3 +381,4 @@ · 380 unmodified lines
381372 i386 recvmsg sys_recvmsg compat_sys_recvmsg381372 i386 recvmsg sys_recvmsg compat_sys_recvmsg
382373 i386 shutdown sys_shutdown382373 i386 shutdown sys_shutdown
383374 i386 userfaultfd sys_userfaultfd383374 i386 userfaultfd sys_userfaultfd
384375 i386 membarrier sys_membarrier
arch/x86/entry/syscalls/syscall_64.tbl+1−0
@@ -330,6 +330,7 @@ · 329 unmodified lines
330321 common bpf sys_bpf330321 common bpf sys_bpf
331322 64 execveat stub_execveat331322 64 execveat stub_execveat
332323 common userfaultfd sys_userfaultfd332323 common userfaultfd sys_userfaultfd
333324 common membarrier sys_membarrier
333 334
334#335#
335# x32-specific system call numbers start at 512 to avoid cache impact336# 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
135static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr,135static ssize_t iotlb_dump_cr(struct omap_iommu *obj, struct cr_regs *cr,
136 struct seq_file *s)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 (cr->cam & MMU_CAM_P) ? 1 : 0);139 (cr->cam & MMU_CAM_P) ? 1 : 0);
140 return 0;
140}141}
141 142
142static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s)143static 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
142 struct inode *inode = d_inode(dentry);142 struct inode *inode = d_inode(dentry);
143 const struct proc_ns_operations *ns_ops = dentry->d_fsdata;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
148static const struct super_operations nsfs_ops = {149static 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
1776 struct dlm_migratable_lockres *mres)1776 struct dlm_migratable_lockres *mres)
1777{1777{
1778 struct dlm_migratable_lock *ml;1778 struct dlm_migratable_lock *ml;
1779 struct list_head *queue;1779 struct list_head *queue, *iter;
1780 struct list_head *tmpq = NULL;1780 struct list_head *tmpq = NULL;
1781 struct dlm_lock *newlock = NULL;1781 struct dlm_lock *newlock = NULL;
1782 struct dlm_lockstatus *lksb = NULL;1782 struct dlm_lockstatus *lksb = NULL;
@@ -1821,7 +1821,9 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, · 38 unmodified lines
1821 spin_lock(&res->spinlock);1821 spin_lock(&res->spinlock);
1822 for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) {1822 for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) {
1823 tmpq = dlm_list_idx_to_ptr(res, j);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 if (lock->ml.cookie == ml->cookie)1827 if (lock->ml.cookie == ml->cookie)
1826 break;1828 break;
1827 lock = NULL;1829 lock = NULL;
fs/seq_file.c+31−39
@@ -372,16 +372,16 @@ EXPORT_SYMBOL(seq_release); · 371 unmodified lines
372 * @esc: set of characters that need escaping372 * @esc: set of characters that need escaping
373 *373 *
374 * Puts string into buffer, replacing each occurrence of character from374 * Puts string into buffer, replacing each occurrence of character from
375 * @esc with usual octal escape. Returns 0 in case of success, -1 - in375 * @esc with usual octal escape.
376 * case of overflow.376 * Use seq_has_overflowed() to check for errors.
377 */377 */
378int seq_escape(struct seq_file *m, const char *s, const char *esc)378void seq_escape(struct seq_file *m, const char *s, const char *esc)
379{379{
380 char *end = m->buf + m->size;380 char *end = m->buf + m->size;
381 char *p;381 char *p;
382 char c;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 if (!strchr(esc, c)) {385 if (!strchr(esc, c)) {
386 *p++ = c;386 *p++ = c;
387 continue;387 continue;
@@ -394,14 +394,13 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc) · 6 unmodified lines
394 continue;394 continue;
395 }395 }
396 seq_set_overflow(m);396 seq_set_overflow(m);
397 return -1;397 return;
398 }398 }
399 m->count = p - m->buf;399 m->count = p - m->buf;
400 return 0;
401}400}
402EXPORT_SYMBOL(seq_escape);401EXPORT_SYMBOL(seq_escape);
403 402
404int seq_vprintf(struct seq_file *m, const char *f, va_list args)403void seq_vprintf(struct seq_file *m, const char *f, va_list args)
405{404{
406 int len;405 int len;
407 406
@@ -409,24 +408,20 @@ int seq_vprintf(struct seq_file *m, const char *f, va_list args) · 1 unmodified line
409 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);408 len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
410 if (m->count + len < m->size) {409 if (m->count + len < m->size) {
411 m->count += len;410 m->count += len;
412 return 0;411 return;
413 }412 }
414 }413 }
415 seq_set_overflow(m);414 seq_set_overflow(m);
416 return -1;
417}415}
418EXPORT_SYMBOL(seq_vprintf);416EXPORT_SYMBOL(seq_vprintf);
419 417
420int seq_printf(struct seq_file *m, const char *f, ...)418void seq_printf(struct seq_file *m, const char *f, ...)
421{419{
422 int ret;
423 va_list args;420 va_list args;
424 421
425 va_start(args, f);422 va_start(args, f);
426 ret = seq_vprintf(m, f, args);423 seq_vprintf(m, f, args);
427 va_end(args);424 va_end(args);
428
429 return ret;
430}425}
431EXPORT_SYMBOL(seq_printf);426EXPORT_SYMBOL(seq_printf);
432 427
@@ -664,26 +659,25 @@ int seq_open_private(struct file *filp, const struct seq_operations *ops, · 231 unmodified lines
664}659}
665EXPORT_SYMBOL(seq_open_private);660EXPORT_SYMBOL(seq_open_private);
666 661
667int seq_putc(struct seq_file *m, char c)662void seq_putc(struct seq_file *m, char c)
668{663{
669 if (m->count < m->size) {664 if (m->count >= m->size)
670 m->buf[m->count++] = c;665 return;
671 return 0;666
672 }667 m->buf[m->count++] = c;
673 return -1;
674}668}
675EXPORT_SYMBOL(seq_putc);669EXPORT_SYMBOL(seq_putc);
676 670
677int seq_puts(struct seq_file *m, const char *s)671void seq_puts(struct seq_file *m, const char *s)
678{672{
679 int len = strlen(s);673 int len = strlen(s);
680 if (m->count + len < m->size) {674
681 memcpy(m->buf + m->count, s, len);675 if (m->count + len >= m->size) {
682 m->count += len;676 seq_set_overflow(m);
683 return 0;677 return;
684 }678 }
685 seq_set_overflow(m);679 memcpy(m->buf + m->count, s, len);
686 return -1;680 m->count += len;
687}681}
688EXPORT_SYMBOL(seq_puts);682EXPORT_SYMBOL(seq_puts);
689 683
@@ -694,8 +688,8 @@ EXPORT_SYMBOL(seq_puts); · 4 unmodified lines
694 * This routine is very quick when you show lots of numbers.688 * This routine is very quick when you show lots of numbers.
695 * In usual cases, it will be better to use seq_printf(). It's easier to read.689 * In usual cases, it will be better to use seq_printf(). It's easier to read.
696 */690 */
697int seq_put_decimal_ull(struct seq_file *m, char delimiter,691void seq_put_decimal_ull(struct seq_file *m, char delimiter,
698 unsigned long long num)692 unsigned long long num)
699{693{
700 int len;694 int len;
701 695
@@ -707,35 +701,33 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, · 5 unmodified lines
707 701
708 if (num < 10) {702 if (num < 10) {
709 m->buf[m->count++] = num + '0';703 m->buf[m->count++] = num + '0';
710 return 0;704 return;
711 }705 }
712 706
713 len = num_to_str(m->buf + m->count, m->size - m->count, num);707 len = num_to_str(m->buf + m->count, m->size - m->count, num);
714 if (!len)708 if (!len)
715 goto overflow;709 goto overflow;
716 m->count += len;710 m->count += len;
717 return 0;711 return;
712
718overflow:713overflow:
719 seq_set_overflow(m);714 seq_set_overflow(m);
720 return -1;
721}715}
722EXPORT_SYMBOL(seq_put_decimal_ull);716EXPORT_SYMBOL(seq_put_decimal_ull);
723 717
724int seq_put_decimal_ll(struct seq_file *m, char delimiter,718void seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num)
725 long long num)
726{719{
727 if (num < 0) {720 if (num < 0) {
728 if (m->count + 3 >= m->size) {721 if (m->count + 3 >= m->size) {
729 seq_set_overflow(m);722 seq_set_overflow(m);
730 return -1;723 return;
731 }724 }
732 if (delimiter)725 if (delimiter)
733 m->buf[m->count++] = delimiter;726 m->buf[m->count++] = delimiter;
734 num = -num;727 num = -num;
735 delimiter = '-';728 delimiter = '-';
736 }729 }
737 return seq_put_decimal_ull(m, delimiter, num);730 seq_put_decimal_ull(m, delimiter, num);
738
739}731}
740EXPORT_SYMBOL(seq_put_decimal_ll);732EXPORT_SYMBOL(seq_put_decimal_ll);
741 733
include/linux/seq_file.h+10−9
@@ -114,13 +114,18 @@ int seq_open(struct file *, const struct seq_operations *); · 113 unmodified lines
114ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);114ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
115loff_t seq_lseek(struct file *, loff_t, int);115loff_t seq_lseek(struct file *, loff_t, int);
116int seq_release(struct inode *, struct file *);116int seq_release(struct inode *, struct file *);
117int seq_escape(struct seq_file *, const char *, const char *);
118int seq_putc(struct seq_file *m, char c);
119int seq_puts(struct seq_file *m, const char *s);
120int seq_write(struct seq_file *seq, const void *data, size_t len);117int 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 *, ...);119__printf(2, 0)
123__printf(2, 0) int seq_vprintf(struct seq_file *, const char *, va_list args);120void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
121__printf(2, 3)
122void seq_printf(struct seq_file *m, const char *fmt, ...);
123void seq_putc(struct seq_file *m, char c);
124void seq_puts(struct seq_file *m, const char *s);
125void seq_put_decimal_ull(struct seq_file *m, char delimiter,
126 unsigned long long num);
127void seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num);
128void seq_escape(struct seq_file *m, const char *s, const char *esc);
124 129
125void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,130void seq_hex_dump(struct seq_file *m, const char *prefix_str, int prefix_type,
126 int rowsize, int groupsize, const void *buf, size_t len,131 int rowsize, int groupsize, const void *buf, size_t len,
@@ -138,10 +143,6 @@ int single_release(struct inode *, struct file *); · 11 unmodified lines
138void *__seq_open_private(struct file *, const struct seq_operations *, int);143void *__seq_open_private(struct file *, const struct seq_operations *, int);
139int seq_open_private(struct file *, const struct seq_operations *, int);144int seq_open_private(struct file *, const struct seq_operations *, int);
140int seq_release_private(struct inode *, struct file *);145int seq_release_private(struct inode *, struct file *);
141int seq_put_decimal_ull(struct seq_file *m, char delimiter,
142 unsigned long long num);
143int seq_put_decimal_ll(struct seq_file *m, char delimiter,
144 long long num);
145 146
146static inline struct user_namespace *seq_user_ns(struct seq_file *seq)147static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
147{148{
include/linux/syscalls.h+2−0
@@ -885,4 +885,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename, · 884 unmodified lines
885 const char __user *const __user *argv,885 const char __user *const __user *argv,
886 const char __user *const __user *envp, int flags);886 const char __user *const __user *envp, int flags);
887 887
888asmlinkage long sys_membarrier(int cmd, int flags);
889
888#endif890#endif
include/uapi/asm-generic/unistd.h+3−1
@@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create) · 708 unmodified lines
709__SYSCALL(__NR_bpf, sys_bpf)709__SYSCALL(__NR_bpf, sys_bpf)
710#define __NR_execveat 281710#define __NR_execveat 281
711__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)711__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
712#define __NR_membarrier 282
713__SYSCALL(__NR_membarrier, sys_membarrier)
712 714
713#undef __NR_syscalls715#undef __NR_syscalls
714#define __NR_syscalls 282716#define __NR_syscalls 283
715 717
716/*718/*
717 * All syscalls below here should go away really,719 * 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
252header-y += media.h252header-y += media.h
253header-y += media-bus-format.h253header-y += media-bus-format.h
254header-y += mei.h254header-y += mei.h
255header-y += membarrier.h
255header-y += memfd.h256header-y += memfd.h
256header-y += mempolicy.h257header-y += mempolicy.h
257header-y += meye.h258header-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 */
48enum 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
1602 bugs/quirks. Disable this only if your target machine is1602 bugs/quirks. Disable this only if your target machine is
1603 unaffected by PCI quirks.1603 unaffected by PCI quirks.
1604 1604
1605config 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
1605config EMBEDDED1617config EMBEDDED
1606 bool "Embedded system"1618 bool "Embedded system"
1607 option allnoconfig_y1619 option allnoconfig_y
kernel/Makefile+1−0
@@ -100,6 +100,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o · 99 unmodified lines
100obj-$(CONFIG_JUMP_LABEL) += jump_label.o100obj-$(CONFIG_JUMP_LABEL) += jump_label.o
101obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o101obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
102obj-$(CONFIG_TORTURE_TEST) += torture.o102obj-$(CONFIG_TORTURE_TEST) += torture.o
103obj-$(CONFIG_MEMBARRIER) += membarrier.o
103 104
104obj-$(CONFIG_HAS_IOMEM) += memremap.o105obj-$(CONFIG_HAS_IOMEM) += memremap.o
105 106
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 */
52SYSCALL_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
245 245
246/* execveat */246/* execveat */
247cond_syscall(sys_execveat);247cond_syscall(sys_execveat);
248
249/* membarrier */
250cond_syscall(sys_membarrier);
mm/early_ioremap.c+1−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/mm.h>15#include <linux/mm.h>
16#include <linux/vmalloc.h>16#include <linux/vmalloc.h>
17#include <asm/fixmap.h>17#include <asm/fixmap.h>
18#include <asm/early_ioremap.h>
18 19
19#ifdef CONFIG_MMU20#ifdef CONFIG_MMU
20static int early_ioremap_debug __initdata;21static int early_ioremap_debug __initdata;
scripts/extract-cert.c+1−1
@@ -86,7 +86,7 @@ static void write_cert(X509 *x509) · 85 unmodified lines
86 ERR(!wb, "%s", cert_dst);86 ERR(!wb, "%s", cert_dst);
87 }87 }
88 X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf));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 if (kbuild_verbose)90 if (kbuild_verbose)
91 fprintf(stderr, "Extracted cert: %s\n", buf);91 fprintf(stderr, "Extracted cert: %s\n", buf);
92}92}
tools/testing/selftests/Makefile+1−0
@@ -6,6 +6,7 @@ TARGETS += firmware · 5 unmodified lines
6TARGETS += ftrace6TARGETS += ftrace
7TARGETS += futex7TARGETS += futex
8TARGETS += kcmp8TARGETS += kcmp
9TARGETS += membarrier
9TARGETS += memfd10TARGETS += memfd
10TARGETS += memory-hotplug11TARGETS += memory-hotplug
11TARGETS += mount12TARGETS += mount
tools/testing/selftests/membarrier/.gitignore+1−0
@@ -0,0 +1 @@
1membarrier_test
tools/testing/selftests/membarrier/Makefile+11−0
@@ -0,0 +1,11 @@
1CFLAGS += -g -I../../../../usr/include/
2
3all:
4 $(CC) $(CFLAGS) membarrier_test.c -o membarrier_test
5
6TEST_PROGS := membarrier_test
7
8include ../lib.mk
9
10clean:
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
13enum test_membarrier_status {
14 TEST_MEMBARRIER_PASS = 0,
15 TEST_MEMBARRIER_FAIL,
16 TEST_MEMBARRIER_SKIP,
17};
18
19static int sys_membarrier(int cmd, int flags)
20{
21 return syscall(__NR_membarrier, cmd, flags);
22}
23
24static 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
35static 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
46static 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
60static 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
76static 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
104int 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