* [GIT PULL] Please pull powerpc/linux.git powerpc-4.16-3 tag
From: Michael Ellerman @ 2018-02-17 9:45 UTC (permalink / raw)
To: Linus Torvalds
Cc: clabbe, clg, cyrilbur, linux-kernel, linuxppc-dev, nfont, npiggin
[-- Attachment #1: Type: text/plain, Size: 2051 bytes --]
Hi Linus,
Please pull some more powerpc fixes for 4.16. Sorry to send a pull
request on the weekend, and a 2nd one this week, but one of these
commits fixes a boot crash which would be good to get in before rc2.
cheers
The following changes since commit 694a20dae6efc3803740971fa9f7c86b8c8d4685:
Merge tag 'powerpc-4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux (2018-02-14 10:06:41 -0800)
are available in the git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git tags/powerpc-4.16-3
for you to fetch changes up to 2c10636a0b9c689450e85f9945583920f50337c9:
powerpc/pseries: Check for zero filled ibm,dynamic-memory property (2018-02-16 21:34:14 +1100)
----------------------------------------------------------------
powerpc fixes for 4.16 #3
The main attraction is a fix for a bug in the new drmem code, which was causing
an oops on boot on some versions of Qemu.
There's also a fix for XIVE (Power9 interrupt controller) on KVM, as well as a
few other minor fixes.
Thanks to:
Corentin Labbe, Cyril Bur, Cédric Le Goater, Daniel Black, Nathan Fontenot,
Nicholas Piggin.
----------------------------------------------------------------
Corentin Labbe (1):
powerpc/pseries: Add empty update_numa_cpu_lookup_table() for NUMA=n
Cyril Bur (1):
powerpc: Expose TSCR via sysfs only on powernv
Cédric Le Goater (1):
powerpc/xive: Use hw CPU ids when configuring the CPU queues
Nathan Fontenot (1):
powerpc/pseries: Check for zero filled ibm,dynamic-memory property
Nicholas Piggin (1):
powerpc/powernv: IMC fix out of bounds memory access at shutdown
arch/powerpc/include/asm/topology.h | 3 +++
arch/powerpc/kernel/sysfs.c | 6 ++++--
arch/powerpc/mm/drmem.c | 8 ++++++++
arch/powerpc/platforms/powernv/opal-imc.c | 6 ++++--
arch/powerpc/sysdev/xive/spapr.c | 16 ++++++++++------
5 files changed, 29 insertions(+), 10 deletions(-)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Ravi Bangoria @ 2018-02-17 6:17 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe, Ravi Bangoria
In-Reply-To: <20180216175002.GC16919@kernel.org>
Oops.. Really sorry about that.
I've tested acme/perf/core on ubuntu ppc32 with and without libaudit-dev
and it's working fine.
Thank you very much for fixing it,
Ravi
On 02/16/2018 11:20 PM, Arnaldo Carvalho de Melo wrote:
> Em Fri, Feb 16, 2018 at 02:29:01PM -0300, Arnaldo Carvalho de Melo escreveu:
>> Humm, we need to create two tables, one for 32-bit and another for 64,
>> even with ppc not having (AFAIK) clashes in syscall numbers for 32/64...
>>
>> Trying to do it now.
> Now seems to work, take a look at my perf/core branch, should be one of the first few csets.
>
> perfbuilder@cc1a85517216:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_32.c
> [192] = "mmap2",
> perfbuilder@cc1a85517216:/git/perf$ powerpc-linux-gnu-gcc --version
> powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> perfbuilder@cc1a85517216:/git/perf$
>
> perfbuilder@9d7fc9dcfb73:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_32.c
> [192] = "mmap2",
> perfbuilder@9d7fc9dcfb73:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_64.c
> perfbuilder@9d7fc9dcfb73:/git/perf$ powerpc64-linux-gnu-gcc --version
> powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
> perfbuilder@9d7fc9dcfb73:/git/perf$
>
^ permalink raw reply
* [PATCH RESEND] powerpc/5200: dts: digsy_mtc.dts: fix rv3029 compatible
From: Alexandre Belloni @ 2018-02-16 23:43 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, linux-rtc, linux-kernel, Alexandre Belloni
The proper compatible for rv3029 is microcrystal,rv3029.
Acked-by: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
Hi,
I'm resending that one because I prefer not taking DT patches through the RTC
tree.
arch/powerpc/boot/dts/digsy_mtc.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts
index c280e75c86bf..c3922fc03e0b 100644
--- a/arch/powerpc/boot/dts/digsy_mtc.dts
+++ b/arch/powerpc/boot/dts/digsy_mtc.dts
@@ -78,7 +78,7 @@
};
rtc@56 {
- compatible = "mc,rv3029c2";
+ compatible = "microcrystal,rv3029";
reg = <0x56>;
};
--
2.16.1
^ permalink raw reply related
* [PATCH 35/41] perf trace powerpc: Use generated syscall table
From: Arnaldo Carvalho de Melo @ 2018-02-16 19:17 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, linux-perf-users, Ravi Bangoria, Alexander Shishkin,
Hendrik Brueckner, Jiri Olsa, Michael Ellerman, Namhyung Kim,
Thomas Richter, linuxppc-dev, Arnaldo Carvalho de Melo
In-Reply-To: <20180216191746.11095-1-acme@kernel.org>
From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
This should speed up accessing new system calls introduced with the
kernel rather than waiting for libaudit updates to include them.
It also enables users to specify wildcards, for example, perf trace -e
'open*', just like was already possible on x86 and s390.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Thomas Richter <tmricht@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/20180129083417.31240-4-ravi.bangoria@linux.vnet.ibm.com
[ Do it for ppc32 as well ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/Makefile.config | 2 ++
tools/perf/util/syscalltbl.c | 8 ++++++++
2 files changed, 10 insertions(+)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 0dfdaa9fa81e..577a5d2988fe 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -27,6 +27,8 @@ NO_SYSCALL_TABLE := 1
# Additional ARCH settings for ppc
ifeq ($(SRCARCH),powerpc)
NO_PERF_REGS := 0
+ NO_SYSCALL_TABLE := 0
+ CFLAGS += -I$(OUTPUT)arch/powerpc/include/generated
LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
endif
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c
index 303bdb84ab5a..895122d638dd 100644
--- a/tools/perf/util/syscalltbl.c
+++ b/tools/perf/util/syscalltbl.c
@@ -30,6 +30,14 @@ static const char **syscalltbl_native = syscalltbl_x86_64;
#include <asm/syscalls_64.c>
const int syscalltbl_native_max_id = SYSCALLTBL_S390_64_MAX_ID;
static const char **syscalltbl_native = syscalltbl_s390_64;
+#elif defined(__powerpc64__)
+#include <asm/syscalls_64.c>
+const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
+static const char **syscalltbl_native = syscalltbl_powerpc_64;
+#elif defined(__powerpc__)
+#include <asm/syscalls_32.c>
+const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID;
+static const char **syscalltbl_native = syscalltbl_powerpc_32;
#endif
struct syscall {
--
2.14.3
^ permalink raw reply related
* [PATCH 34/41] perf powerpc: Generate system call table from asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 19:17 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, linux-perf-users, Ravi Bangoria, Alexander Shishkin,
Hendrik Brueckner, Jiri Olsa, Michael Ellerman, Namhyung Kim,
Thomas Richter, linuxppc-dev, Arnaldo Carvalho de Melo
In-Reply-To: <20180216191746.11095-1-acme@kernel.org>
From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
This should speed up accessing new system calls introduced with the
kernel rather than waiting for libaudit updates to include them.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Thomas Richter <tmricht@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/20180129083417.31240-3-ravi.bangoria@linux.vnet.ibm.com
[ Made it generate syscall_32.c as well to fix the build on 32-bit ppc ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/arch/powerpc/Makefile | 25 +++++++++++++++
.../perf/arch/powerpc/entry/syscalls/mksyscalltbl | 37 ++++++++++++++++++++++
2 files changed, 62 insertions(+)
create mode 100755 tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index 42dab7c8f508..a111239df182 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -6,3 +6,28 @@ endif
HAVE_KVM_STAT_SUPPORT := 1
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
PERF_HAVE_JITDUMP := 1
+
+#
+# Syscall table generation for perf
+#
+
+out := $(OUTPUT)arch/powerpc/include/generated/asm
+header32 := $(out)/syscalls_32.c
+header64 := $(out)/syscalls_64.c
+sysdef := $(srctree)/tools/arch/powerpc/include/uapi/asm/unistd.h
+sysprf := $(srctree)/tools/perf/arch/powerpc/entry/syscalls/
+systbl := $(sysprf)/mksyscalltbl
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
+
+$(header64): $(sysdef) $(systbl)
+ $(Q)$(SHELL) '$(systbl)' '64' '$(CC)' $(sysdef) > $@
+
+$(header32): $(sysdef) $(systbl)
+ $(Q)$(SHELL) '$(systbl)' '32' '$(CC)' $(sysdef) > $@
+
+clean::
+ $(call QUIET_CLEAN, powerpc) $(RM) $(header32) $(header64)
+
+archheaders: $(header32) $(header64)
diff --git a/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
new file mode 100755
index 000000000000..ef52e1dd694b
--- /dev/null
+++ b/tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
@@ -0,0 +1,37 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate system call table for perf. Derived from
+# s390 script.
+#
+# Copyright IBM Corp. 2017
+# Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+# Changed by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+
+wordsize=$1
+gcc=$2
+input=$3
+
+if ! test -r $input; then
+ echo "Could not read input file" >&2
+ exit 1
+fi
+
+create_table()
+{
+ local wordsize=$1
+ local max_nr
+
+ echo "static const char *syscalltbl_powerpc_${wordsize}[] = {"
+ while read sc nr; do
+ printf '\t[%d] = "%s",\n' $nr $sc
+ max_nr=$nr
+ done
+ echo '};'
+ echo "#define SYSCALLTBL_POWERPC_${wordsize}_MAX_ID $max_nr"
+}
+
+$gcc -m${wordsize} -E -dM -x c $input \
+ |sed -ne 's/^#define __NR_//p' \
+ |sort -t' ' -k2 -nu \
+ |create_table ${wordsize}
--
2.14.3
^ permalink raw reply related
* [PATCH 33/41] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 19:17 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, linux-perf-users, Ravi Bangoria, Alexander Shishkin,
Hendrik Brueckner, Jiri Olsa, Michael Ellerman, Namhyung Kim,
Thomas Richter, linuxppc-dev, Arnaldo Carvalho de Melo
In-Reply-To: <20180216191746.11095-1-acme@kernel.org>
From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Will be used for generating the syscall id/string translation table.
Committer notes:
Update it already to catch with these csets applied since Ravi first
submitted this patch:
3350eb2ea127 powerpc: sys_pkey_mprotect() system call
9499ec1b5e82 powerpc: sys_pkey_alloc() and sys_pkey_free() system calls
So now 'perf trace' on ppc now knows about the pkey_ syscals.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Thomas Richter <tmricht@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/20180129083417.31240-2-ravi.bangoria@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/arch/powerpc/include/uapi/asm/unistd.h | 402 +++++++++++++++++++++++++++
| 1 +
2 files changed, 403 insertions(+)
create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
diff --git a/tools/arch/powerpc/include/uapi/asm/unistd.h b/tools/arch/powerpc/include/uapi/asm/unistd.h
new file mode 100644
index 000000000000..389c36fd8299
--- /dev/null
+++ b/tools/arch/powerpc/include/uapi/asm/unistd.h
@@ -0,0 +1,402 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * This file contains the system call numbers.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_POWERPC_UNISTD_H_
+#define _UAPI_ASM_POWERPC_UNISTD_H_
+
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_query_module 166
+#define __NR_poll 167
+#define __NR_nfsservctl 168
+#define __NR_setresgid 169
+#define __NR_getresgid 170
+#define __NR_prctl 171
+#define __NR_rt_sigreturn 172
+#define __NR_rt_sigaction 173
+#define __NR_rt_sigprocmask 174
+#define __NR_rt_sigpending 175
+#define __NR_rt_sigtimedwait 176
+#define __NR_rt_sigqueueinfo 177
+#define __NR_rt_sigsuspend 178
+#define __NR_pread64 179
+#define __NR_pwrite64 180
+#define __NR_chown 181
+#define __NR_getcwd 182
+#define __NR_capget 183
+#define __NR_capset 184
+#define __NR_sigaltstack 185
+#define __NR_sendfile 186
+#define __NR_getpmsg 187 /* some people actually want streams */
+#define __NR_putpmsg 188 /* some people actually want streams */
+#define __NR_vfork 189
+#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
+#define __NR_readahead 191
+#ifndef __powerpc64__ /* these are 32-bit only */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#endif
+#define __NR_pciconfig_read 198
+#define __NR_pciconfig_write 199
+#define __NR_pciconfig_iobase 200
+#define __NR_multiplexer 201
+#define __NR_getdents64 202
+#define __NR_pivot_root 203
+#ifndef __powerpc64__
+#define __NR_fcntl64 204
+#endif
+#define __NR_madvise 205
+#define __NR_mincore 206
+#define __NR_gettid 207
+#define __NR_tkill 208
+#define __NR_setxattr 209
+#define __NR_lsetxattr 210
+#define __NR_fsetxattr 211
+#define __NR_getxattr 212
+#define __NR_lgetxattr 213
+#define __NR_fgetxattr 214
+#define __NR_listxattr 215
+#define __NR_llistxattr 216
+#define __NR_flistxattr 217
+#define __NR_removexattr 218
+#define __NR_lremovexattr 219
+#define __NR_fremovexattr 220
+#define __NR_futex 221
+#define __NR_sched_setaffinity 222
+#define __NR_sched_getaffinity 223
+/* 224 currently unused */
+#define __NR_tuxcall 225
+#ifndef __powerpc64__
+#define __NR_sendfile64 226
+#endif
+#define __NR_io_setup 227
+#define __NR_io_destroy 228
+#define __NR_io_getevents 229
+#define __NR_io_submit 230
+#define __NR_io_cancel 231
+#define __NR_set_tid_address 232
+#define __NR_fadvise64 233
+#define __NR_exit_group 234
+#define __NR_lookup_dcookie 235
+#define __NR_epoll_create 236
+#define __NR_epoll_ctl 237
+#define __NR_epoll_wait 238
+#define __NR_remap_file_pages 239
+#define __NR_timer_create 240
+#define __NR_timer_settime 241
+#define __NR_timer_gettime 242
+#define __NR_timer_getoverrun 243
+#define __NR_timer_delete 244
+#define __NR_clock_settime 245
+#define __NR_clock_gettime 246
+#define __NR_clock_getres 247
+#define __NR_clock_nanosleep 248
+#define __NR_swapcontext 249
+#define __NR_tgkill 250
+#define __NR_utimes 251
+#define __NR_statfs64 252
+#define __NR_fstatfs64 253
+#ifndef __powerpc64__
+#define __NR_fadvise64_64 254
+#endif
+#define __NR_rtas 255
+#define __NR_sys_debug_setcontext 256
+/* Number 257 is reserved for vserver */
+#define __NR_migrate_pages 258
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
+#define __NR_mq_open 262
+#define __NR_mq_unlink 263
+#define __NR_mq_timedsend 264
+#define __NR_mq_timedreceive 265
+#define __NR_mq_notify 266
+#define __NR_mq_getsetattr 267
+#define __NR_kexec_load 268
+#define __NR_add_key 269
+#define __NR_request_key 270
+#define __NR_keyctl 271
+#define __NR_waitid 272
+#define __NR_ioprio_set 273
+#define __NR_ioprio_get 274
+#define __NR_inotify_init 275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch 277
+#define __NR_spu_run 278
+#define __NR_spu_create 279
+#define __NR_pselect6 280
+#define __NR_ppoll 281
+#define __NR_unshare 282
+#define __NR_splice 283
+#define __NR_tee 284
+#define __NR_vmsplice 285
+#define __NR_openat 286
+#define __NR_mkdirat 287
+#define __NR_mknodat 288
+#define __NR_fchownat 289
+#define __NR_futimesat 290
+#ifdef __powerpc64__
+#define __NR_newfstatat 291
+#else
+#define __NR_fstatat64 291
+#endif
+#define __NR_unlinkat 292
+#define __NR_renameat 293
+#define __NR_linkat 294
+#define __NR_symlinkat 295
+#define __NR_readlinkat 296
+#define __NR_fchmodat 297
+#define __NR_faccessat 298
+#define __NR_get_robust_list 299
+#define __NR_set_robust_list 300
+#define __NR_move_pages 301
+#define __NR_getcpu 302
+#define __NR_epoll_pwait 303
+#define __NR_utimensat 304
+#define __NR_signalfd 305
+#define __NR_timerfd_create 306
+#define __NR_eventfd 307
+#define __NR_sync_file_range2 308
+#define __NR_fallocate 309
+#define __NR_subpage_prot 310
+#define __NR_timerfd_settime 311
+#define __NR_timerfd_gettime 312
+#define __NR_signalfd4 313
+#define __NR_eventfd2 314
+#define __NR_epoll_create1 315
+#define __NR_dup3 316
+#define __NR_pipe2 317
+#define __NR_inotify_init1 318
+#define __NR_perf_event_open 319
+#define __NR_preadv 320
+#define __NR_pwritev 321
+#define __NR_rt_tgsigqueueinfo 322
+#define __NR_fanotify_init 323
+#define __NR_fanotify_mark 324
+#define __NR_prlimit64 325
+#define __NR_socket 326
+#define __NR_bind 327
+#define __NR_connect 328
+#define __NR_listen 329
+#define __NR_accept 330
+#define __NR_getsockname 331
+#define __NR_getpeername 332
+#define __NR_socketpair 333
+#define __NR_send 334
+#define __NR_sendto 335
+#define __NR_recv 336
+#define __NR_recvfrom 337
+#define __NR_shutdown 338
+#define __NR_setsockopt 339
+#define __NR_getsockopt 340
+#define __NR_sendmsg 341
+#define __NR_recvmsg 342
+#define __NR_recvmmsg 343
+#define __NR_accept4 344
+#define __NR_name_to_handle_at 345
+#define __NR_open_by_handle_at 346
+#define __NR_clock_adjtime 347
+#define __NR_syncfs 348
+#define __NR_sendmmsg 349
+#define __NR_setns 350
+#define __NR_process_vm_readv 351
+#define __NR_process_vm_writev 352
+#define __NR_finit_module 353
+#define __NR_kcmp 354
+#define __NR_sched_setattr 355
+#define __NR_sched_getattr 356
+#define __NR_renameat2 357
+#define __NR_seccomp 358
+#define __NR_getrandom 359
+#define __NR_memfd_create 360
+#define __NR_bpf 361
+#define __NR_execveat 362
+#define __NR_switch_endian 363
+#define __NR_userfaultfd 364
+#define __NR_membarrier 365
+#define __NR_mlock2 378
+#define __NR_copy_file_range 379
+#define __NR_preadv2 380
+#define __NR_pwritev2 381
+#define __NR_kexec_file_load 382
+#define __NR_statx 383
+#define __NR_pkey_alloc 384
+#define __NR_pkey_free 385
+#define __NR_pkey_mprotect 386
+
+#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
--git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index 790ec25919a0..bf206ffe5c45 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -42,6 +42,7 @@ arch/parisc/include/uapi/asm/errno.h
arch/powerpc/include/uapi/asm/errno.h
arch/sparc/include/uapi/asm/errno.h
arch/x86/include/uapi/asm/errno.h
+arch/powerpc/include/uapi/asm/unistd.h
include/asm-generic/bitops/arch_hweight.h
include/asm-generic/bitops/const_hweight.h
include/asm-generic/bitops/__fls.h
--
2.14.3
^ permalink raw reply related
* [GIT PULL 00/41] perf/core improvements and fixes
From: Arnaldo Carvalho de Melo @ 2018-02-16 19:17 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, linux-perf-users, Arnaldo Carvalho de Melo,
Adrian Hunter, Alexander Shishkin, Andi Kleen, coresight,
David Ahern, Heiko Carstens, Hendrik Brueckner, Jaecheol Shin,
Jin Yao, Jiri Olsa, Kan Liang, linux-arm-kernel, linuxppc-dev,
Martin Schwidefsky, Masami Hiramatsu, Mathieu Poirier,
Michael Ellerman, Milian Wolff, Namhyung Kim, Naveen N . Rao,
Peter Zijlstra, Ravi Bangoria, Robert Walker, Sangwon Hong,
Stephane Eranian, Taeung Song, Thomas Richter, Wang Nan,
yuzhoujian, Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling, this is on top of tip/perf/urgent.
- Arnaldo
Test results at the end of this message, as usual.
The following changes since commit 297f9233b53a08fd457815e19f1d6f2c3389857b:
kprobes: Propagate error from disarm_kprobe_ftrace() (2018-02-16 09:12:58 +0100)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-4.17-20180216
for you to fetch changes up to 21316ac6803d4a1aadd74b896db8d60a92cd1140:
perf tests shell lib: Use a wildcard to remove the vfs_getname probe (2018-02-16 15:31:12 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
- Fix wrong jump arrow in systems with branch records with cycles,
i.e. Intel's >= Skylake (Jin Yao)
- Fix 'perf record --per-thread' problem introduced when
implementing 'perf stat --per-thread (Jin Yao)
- Use arch__compare_symbol_names() to fix 'perf test vmlinux',
that was using strcmp(symbol names) while the dso routines
doing symbol lookups used the arch overridable one, making
this test fail in architectures that overrided that function
with something other than strcmp() (Jiri Olsa)
- Add 'perf script --show-round-event' to display
PERF_RECORD_FINISHED_ROUND entries (Jiri Olsa)
- Fix dwarf unwind for stripped binaries in 'perf test' (Jiri Olsa)
- Use ordered_events for 'perf report --tasks', otherwise we may get
artifacts when PERF_RECORD_FORK gets processed before PERF_RECORD_COMM
(when they got recorded in different CPUs) (Jiri Olsa)
- Add support to display group output for non group events, i.e.
now when one uses 'perf report --group' on a perf.data file
recorded without explicitly grouping events with {} (e.g.
"perf record -e '{cycles,instructions}'" get the same output
that would produce, i.e. see all those non-grouped events in
multiple columns, at the same time (Jiri Olsa)
- Skip non-address kallsyms entries, e.g. '(null)' for !root (Jiri Olsa)
- Kernel maps fixes wrt perf.data(report) versus live system (top)
(Jiri Olsa)
- Fix memory corruption when using 'perf record -j call -g -a <application>'
followed by 'perf report --branch-history' (Jiri Olsa)
- ARM CoreSight fixes (Mathieu Poirier)
- Add inject capability for CoreSight Traces (Robert Waker)
- Update documentation for use of 'perf' + ARM CoreSight (Robert Walker)
- Man pages fixes (Sangwon Hong, Jaecheol Shin)
- Fix some 'perf test' cases on s/390 and x86_64 (some backtraces
changed with a glibc update) (Thomas Richter)
- Add detailed CPUID info in the 'perf.data' headers for s/390 to
then use it in 'perf annotate' (Thomas Richter)
- Add '--interval-count N' to 'perf stat', to use with -I, i.e.
'perf stat -I 1000 --interval-count 2' will show stats every
1000ms, two times (yuzhoujian)
- Add 'perf stat --timeout Nms', that will run for that many
milliseconds and then stop, printing the counters (yuzhoujian)
- Fix description for 'perf report --mem-modex (Andi Kleen)
- Use a wildcard to remove the vfs_getname probe in the
'perf test' shell based test cases (Arnaldo Carvalho de Melo)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
----------------------------------------------------------------
Andi Kleen (1):
perf report: Fix description for --mem-mode
Arnaldo Carvalho de Melo (1):
perf tests shell lib: Use a wildcard to remove the vfs_getname probe
Jaecheol Shin (1):
perf annotate: Add missing arguments in Man page
Jin Yao (2):
perf tools: Use target->per_thread and target->system_wide flags
perf report: Fix wrong jump arrow
Jiri Olsa (18):
perf record: Put new line after target override warning
perf script: Add --show-round-event to display PERF_RECORD_FINISHED_ROUND
tools lib api fs: Add filename__read_xll function
tools lib api fs: Add sysfs__read_xll function
perf tests: Fix dwarf unwind for stripped binaries
perf tools: Fix comment for sort__* compare functions
perf report: Ask for ordered events for --tasks option
perf report: Add support to display group output for non group events
tools lib symbol: Skip non-address kallsyms line
perf symbols: Check if we read regular file in dso__load()
perf machine: Free root_dir in machine__init() error path
perf machine: Move kernel mmap name into struct machine
perf machine: Generalize machine__set_kernel_mmap()
perf machine: Don't search for active kernel start in __machine__create_kernel_maps
perf machine: Remove machine__load_kallsyms()
perf tools: Do not create kernel maps in sample__resolve()
perf tests: Use arch__compare_symbol_names to compare symbols
perf report: Fix memory corruption in --branch-history mode --branch-history
Mathieu Poirier (3):
perf cs-etm: Freeing allocated memory
perf auxtrace arm: Fixing uninitialised variable
perf cs-etm: Properly deal with cpu maps
Ravi Bangoria (3):
tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
perf powerpc: Generate system call table from asm/unistd.h
perf trace powerpc: Use generated syscall table
Robert Walker (3):
perf cs-etm: Inject capabilitity for CoreSight traces
perf inject: Emit instruction records on ETM trace discontinuity
coresight: Update documentation for perf usage
Sangwon Hong (2):
perf kmem: Document a missing option & an argument
perf mem: Document a missing option
Thomas Richter (5):
perf record: Provide detailed information on s390 CPU
perf annotate: Scan cpuid for s390 and save machine type
perf cpuid: Introduce a platform specific cpuid compare function
perf test: Fix test case 23 for s390 z/VM or KVM guests
perf test: Fix test case inet_pton to accept inlines.
yuzhoujian (2):
perf stat: Add support to print counts for fixed times
perf stat: Add support to print counts after a period of time
Documentation/trace/coresight.txt | 51 +++
tools/arch/powerpc/include/uapi/asm/unistd.h | 402 +++++++++++++++++
tools/lib/api/fs/fs.c | 44 +-
tools/lib/api/fs/fs.h | 2 +
tools/lib/symbol/kallsyms.c | 4 +
tools/perf/Documentation/perf-annotate.txt | 6 +-
tools/perf/Documentation/perf-kmem.txt | 6 +-
tools/perf/Documentation/perf-mem.txt | 4 +
tools/perf/Documentation/perf-report.txt | 5 +-
tools/perf/Documentation/perf-script.txt | 3 +
tools/perf/Documentation/perf-stat.txt | 10 +
tools/perf/Makefile.config | 2 +
tools/perf/arch/arm/util/auxtrace.c | 2 +-
tools/perf/arch/arm/util/cs-etm.c | 51 ++-
tools/perf/arch/powerpc/Makefile | 25 ++
.../perf/arch/powerpc/entry/syscalls/mksyscalltbl | 37 ++
tools/perf/arch/s390/annotate/instructions.c | 27 +-
tools/perf/arch/s390/util/header.c | 148 ++++++-
tools/perf/builtin-record.c | 2 +-
tools/perf/builtin-report.c | 7 +-
tools/perf/builtin-script.c | 17 +
tools/perf/builtin-stat.c | 53 ++-
tools/perf/check-headers.sh | 1 +
tools/perf/tests/code-reading.c | 33 +-
tools/perf/tests/dwarf-unwind.c | 46 +-
tools/perf/tests/shell/lib/probe_vfs_getname.sh | 2 +-
.../perf/tests/shell/trace+probe_libc_inet_pton.sh | 6 +-
tools/perf/tests/vmlinux-kallsyms.c | 4 +-
tools/perf/ui/browsers/annotate.c | 9 +-
tools/perf/util/build-id.c | 10 +-
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 74 +++-
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 2 +
tools/perf/util/cs-etm.c | 478 ++++++++++++++++++---
tools/perf/util/event.c | 16 +-
tools/perf/util/evlist.c | 21 +-
tools/perf/util/header.h | 1 +
tools/perf/util/hist.c | 4 +-
tools/perf/util/hist.h | 1 -
tools/perf/util/machine.c | 145 +++----
tools/perf/util/machine.h | 6 +-
tools/perf/util/pmu.c | 47 +-
tools/perf/util/sort.c | 7 +-
tools/perf/util/stat.h | 2 +
tools/perf/util/symbol.c | 13 +-
tools/perf/util/syscalltbl.c | 8 +
tools/perf/util/thread_map.c | 4 +-
tools/perf/util/thread_map.h | 2 +-
47 files changed, 1577 insertions(+), 273 deletions(-)
create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
create mode 100755 tools/perf/arch/powerpc/entry/syscalls/mksyscalltbl
Test results:
The first ones are container (docker) based builds of tools/perf with and
without libelf support. Where clang is available, it is also used to build
perf with/without libelf.
The objtool and samples/bpf/ builds are disabled now that I'm switching from
using the sources in a local volume to fetching them from a http server to
build it inside the container, to make it easier to build in a container cluster.
Those will come back later.
Several are cross builds, the ones with -x-ARCH and the android one, and those
may not have all the features built, due to lack of multi-arch devel packages,
available and being used so far on just a few, like
debian:experimental-x-{arm64,mipsel}.
The 'perf test' one will perform a variety of tests exercising
tools/perf/util/, tools/lib/{bpf,traceevent,etc}, as well as run perf commands
with a variety of command line event specifications to then intercept the
sys_perf_event syscall to check that the perf_event_attr fields are set up as
expected, among a variety of other unit tests.
Then there is the 'make -C tools/perf build-test' ones, that build tools/perf/
with a variety of feature sets, exercising the build with an incomplete set of
features as well as with a complete one. It is planned to have it run on each
of the containers mentioned above, using some container orchestration
infrastructure. Get in contact if interested in helping having this in place.
On a Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
# dm
1 39.82 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0
2 57.59 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822
3 44.30 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0
4 42.14 alpine:edge : Ok gcc (Alpine 6.4.0) 6.4.0
5 35.50 amazonlinux:1 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
6 42.97 amazonlinux:2 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
7 26.46 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease)
8 27.28 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease)
9 24.29 centos:5 : Ok gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55)
10 32.15 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
11 39.36 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
12 34.69 debian:7 : Ok gcc (Debian 4.7.2-5) 4.7.2
13 37.92 debian:8 : Ok gcc (Debian 4.9.2-10) 4.9.2
14 62.13 debian:9 : Ok gcc (Debian 6.3.0-18) 6.3.0 20170516
15 65.51 debian:experimental : Ok gcc (Debian 7.2.0-18) 7.2.0
16 38.73 debian:experimental-x-arm64 : Ok aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
17 68.18 debian:experimental-x-mips : Ok mips-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
18 36.21 debian:experimental-x-mips64 : Ok mips64-linux-gnuabi64-gcc (Debian 7.2.0-11) 7.2.0
19 37.57 debian:experimental-x-mipsel : Ok mipsel-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
20 38.22 fedora:20 : Ok gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
21 42.49 fedora:21 : Ok gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
22 39.15 fedora:22 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)
23 41.46 fedora:23 : Ok gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6)
24 41.12 fedora:24 : Ok gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
25 34.92 fedora:24-x-ARC-uClibc : Ok arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710
26 78.28 fedora:25 : Ok gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1)
27 84.02 fedora:26 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
28 95.42 fedora:27 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
29 78.89 fedora:rawhide : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-4)
30 57.48 gentoo-stage3-amd64:latest : Ok gcc (Gentoo 6.4.0-r1 p1.3) 6.4.0
31 41.18 mageia:5 : Ok gcc (GCC) 4.9.2
32 42.27 mageia:6 : Ok gcc (Mageia 5.4.0-5.mga6) 5.4.0
33 39.66 opensuse:42.1 : Ok gcc (SUSE Linux) 4.8.5
34 40.09 opensuse:42.2 : Ok gcc (SUSE Linux) 4.8.5
35 41.01 opensuse:42.3 : Ok gcc (SUSE Linux) 4.8.5
36 82.32 opensuse:tumbleweed : Ok gcc (SUSE Linux) 7.3.0
37 31.70 oraclelinux:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
38 38.39 oraclelinux:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
39 30.49 ubuntu:12.04.5 : Ok gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
40 36.44 ubuntu:14.04.4 : Ok gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
41 32.13 ubuntu:14.04.4-x-linaro-arm64 : Ok aarch64-linux-gnu-gcc (Linaro GCC 5.5-2017.10) 5.5.0
42 58.58 ubuntu:16.04 : Ok gcc (Ubuntu 5.4.0-6ubuntu1~16.04.6) 5.4.0 20160609
43 31.52 ubuntu:16.04-x-arm : Ok arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
44 31.06 ubuntu:16.04-x-arm64 : Ok aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
45 31.61 ubuntu:16.04-x-powerpc : Ok powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
46 31.93 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
47 33.02 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
48 30.94 ubuntu:16.04-x-s390 : Ok s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
49 63.24 ubuntu:16.10 : Ok gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
50 63.34 ubuntu:17.04 : Ok gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406
51 63.56 ubuntu:17.10 : Ok gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0
52 63.45 ubuntu:18.04 : Ok gcc (Ubuntu 7.2.0-18ubuntu2) 7.2.0
# uname -a
Linux jouet 4.15.0-rc9+ #7 SMP Mon Jan 22 18:16:36 -03 2018 x86_64 x86_64 x86_64 GNU/Linux
# perf test
1: vmlinux symtab matches kallsyms : Ok
2: Detect openat syscall event : Ok
3: Detect openat syscall event on all cpus : Ok
4: Read samples using the mmap interface : Ok
5: Test data source output : Ok
6: Parse event definition strings : Ok
7: Simple expression parser : Ok
8: PERF_RECORD_* events & perf_sample fields : Ok
9: Parse perf pmu format : Ok
10: DSO data read : Ok
11: DSO data cache : Ok
12: DSO data reopen : Ok
13: Roundtrip evsel->name : Ok
14: Parse sched tracepoints fields : Ok
15: syscalls:sys_enter_openat event fields : Ok
16: Setup struct perf_event_attr : Ok
17: Match and link multiple hists : Ok
18: 'import perf' in python : Ok
19: Breakpoint overflow signal handler : Ok
20: Breakpoint overflow sampling : Ok
21: Number of exit events of a simple workload : Ok
22: Software clock events period values : Ok
23: Object code reading : Ok
24: Sample parsing : Ok
25: Use a dummy software event to keep tracking : Ok
26: Parse with no sample_id_all bit set : Ok
27: Filter hist entries : Ok
28: Lookup mmap thread : Ok
29: Share thread mg : Ok
30: Sort output of hist entries : Ok
31: Cumulate child hist entries : Ok
32: Track with sched_switch : Ok
33: Filter fds with revents mask in a fdarray : Ok
34: Add fd to a fdarray, making it autogrow : Ok
35: kmod_path__parse : Ok
36: Thread map : Ok
37: LLVM search and compile :
37.1: Basic BPF llvm compile : Ok
37.2: kbuild searching : Ok
37.3: Compile source for BPF prologue generation : Ok
37.4: Compile source for BPF relocation : Ok
38: Session topology : Ok
39: BPF filter :
39.1: Basic BPF filtering : Ok
39.2: BPF pinning : Ok
39.3: BPF prologue generation : Ok
39.4: BPF relocation checker : Ok
40: Synthesize thread map : Ok
41: Remove thread map : Ok
42: Synthesize cpu map : Ok
43: Synthesize stat config : Ok
44: Synthesize stat : Ok
45: Synthesize stat round : Ok
46: Synthesize attr update : Ok
47: Event times : Ok
48: Read backward ring buffer : Ok
49: Print cpu map : Ok
50: Probe SDT events : Ok
51: is_printable_array : Ok
52: Print bitmap : Ok
53: perf hooks : Ok
54: builtin clang support : Skip (not compiled in)
55: unit_number__scnprintf : Ok
56: x86 rdpmc : Ok
57: Convert perf time to TSC : Ok
58: DWARF unwind : Ok
59: x86 instruction decoder - new instructions : Ok
60: Use vfs_getname probe to get syscall args filenames : Ok
61: probe libc's inet_pton & backtrace it with ping : Ok
62: Check open filename arg using perf trace + vfs_getname: Ok
63: Add vfs_getname probe to get syscall args filenames : Ok
#
$ make -C tools/perf build-test
make: Entering directory '/home/acme/git/perf/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
make_no_libunwind_O: make NO_LIBUNWIND=1
make_no_backtrace_O: make NO_BACKTRACE=1
make_with_babeltrace_O: make LIBBABELTRACE=1
make_no_libdw_dwarf_unwind_O: make NO_LIBDW_DWARF_UNWIND=1
make_install_prefix_slash_O: make install prefix=/tmp/krava/
make_static_O: make LDFLAGS=-static
make_minimal_O: make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1
make_with_clangllvm_O: make LIBCLANGLLVM=1
make_install_O: make install
make_doc_O: make doc
make_pure_O: make
make_no_libaudit_O: make NO_LIBAUDIT=1
make_no_slang_O: make NO_SLANG=1
make_no_gtk2_O: make NO_GTK2=1
make_install_bin_O: make install-bin
make_no_libperl_O: make NO_LIBPERL=1
make_no_demangle_O: make NO_DEMANGLE=1
make_tags_O: make tags
make_no_auxtrace_O: make NO_AUXTRACE=1
make_util_pmu_bison_o_O: make util/pmu-bison.o
make_install_prefix_O: make install prefix=/tmp/krava
make_debug_O: make DEBUG=1
make_no_scripts_O: make NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_newt_O: make NO_NEWT=1
make_no_ui_O: make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
^[[5~ make_no_libnuma_O: make NO_LIBNUMA=1
make_no_libelf_O: make NO_LIBELF=1
make_help_O: make help
make_no_libbpf_O: make NO_LIBBPF=1
make_no_libpython_O: make NO_LIBPYTHON=1
make_no_libbionic_O: make NO_LIBBIONIC=1
make_clean_all_O: make clean all
make_perf_o_O: make perf.o
make_util_map_o_O: make util/map.o
OK
make: Leaving directory '/home/acme/git/perf/tools/perf'
$
^ permalink raw reply
* [PATCH 00/23] kconfig: move compiler capability tests to Kconfig
From: Masahiro Yamada @ 2018-02-16 18:38 UTC (permalink / raw)
To: linux-kbuild, Linus Torvalds
Cc: Greg Kroah-Hartman, Arnd Bergmann, Kees Cook, Randy Dunlap,
Ulf Magnusson, Sam Ravnborg, Michal Marek, Masahiro Yamada,
Peter Oberparleiter, kernel-hardening, Jonathan Corbet,
sparclinux, linux-sh, x86, Thomas Gleixner, Rich Felker,
Jeff Dike, H. Peter Anvin, user-mode-linux-devel, Yoshinori Sato,
Benjamin Herrenschmidt, linuxppc-dev, Paul Mackerras,
user-mode-linux-user, Ingo Molnar, David S. Miller,
Michael Ellerman, linux-doc, linux-kernel, Richard Weinberger,
Emese Revfy
I brushed up the implementation in this version.
In the previous RFC, CC_HAS_ was described by using 'option shell=',
like this:
config CC_HAS_STACKPROTECTOR
bool
option shell="$CC -Werror -fstack-protector -c -x c /dev/null"
After I thought a bit more, the following syntax is more grammatical,
and flexible.
config CC_HAS_STACKPROTECTOR
bool
default $(shell $CC -Werror -fstack-protector -c -x c /dev/null)
This version supports cc-option, so it can be written as:
config CC_HAS_STACKPROTECTOR
bool
default $(cc-option -fstack-protector)
To support this in a clean way, I introduced a new concept 'function'
like we see in Makefiles.
$(shell ...) is a built-in function. $(cc-option ...) is implemented
as macro (user-defined function).
I also try cleaning of stack-protector, gcc-plugins since the Makefile
is so dirty.
Current limitations:
Dependency on outside scripts.
For example, scripts/gcc-x86_64-has-stack-protecter.sh is run from
Kconfig. When the shell script is updated, should Kconfig be re-run
automatically?
Inter-option dependency:
$(call cc-option,...) in Makefile accumulates added options to
KBUILD_CFLAGS, but it is difficult to do it in Kconfig.
If a compiler option check is dependent on another option,
this is a difficult case. Let's see how significant it is.
Functions are evaluated statically:
Functions are only expanded when parsing the Kconfig. So, it can
not refelect user configuration. If this is required, $(shell )
must be dynamically re-calculated depending on other symbols.
But, this is difficult, and may cause performance issue.
Masahiro Yamada (22):
kbuild: remove kbuild cache
kbuild: remove CONFIG_CROSS_COMPILE support
kconfig: add xstrdup() helper
kconfig: set SYMBOL_AUTO to the symbol marked with defconfig_list
kconfig: move and rename sym_expand_string_value()
kconfig: reference environments directly and remove 'option env='
syntax
kconfig: add function support and implement 'shell' function
kconfig: add 'macro' keyword to support user-defined function
kconfig: add 'cc-option' macro
stack-protector: test compiler capability in Kconfig and drop AUTO
mode
kconfig: add 'shell-stdout' function
kconfig: replace $UNAME_RELEASE with function call
kconfig: expand environments/functions in (main)menu, comment, prompt
kconfig: show compiler version text in the top comment
kconfig: add CC_IS_GCC and GCC_VERSION
kconfig: add CC_IS_CLANG and CLANG_VERSION
gcov: remove CONFIG_GCOV_FORMAT_AUTODETECT
kcov: imply GCC_PLUGINS and GCC_PLUGIN_SANCOV instead of select'ing
them
gcc-plugins: always build plugins with C++
gcc-plugins: move GCC version check for PowerPC to Kconfig
gcc-plugins: test GCC plugin support in Kconfig
gcc-plugins: enable GCC_PLUGINS for COMPILE_TEST
Sami Tolvanen (1):
kbuild: add clang-version.sh
Documentation/kbuild/kconfig-language.txt | 8 -
Kconfig | 4 +-
Makefile | 103 ++----------
arch/Kconfig | 43 +++--
arch/powerpc/Kconfig | 2 +-
arch/sh/Kconfig | 4 +-
arch/sparc/Kconfig | 4 +-
arch/tile/Kconfig | 2 +-
arch/um/Kconfig.common | 4 -
arch/x86/Kconfig | 12 +-
arch/x86/um/Kconfig | 4 +-
init/Kconfig | 44 +++---
kernel/gcov/Kconfig | 18 +--
kernel/gcov/Makefile | 2 -
lib/Kconfig.debug | 7 +-
scripts/Kbuild.include | 101 ++----------
scripts/Makefile.gcc-plugins | 95 ++++-------
scripts/clang-version.sh | 31 ++++
scripts/gcc-plugin.sh | 37 +----
scripts/gcc-plugins/Makefile | 15 +-
scripts/gcc-x86_32-has-stack-protector.sh | 7 +-
scripts/gcc-x86_64-has-stack-protector.sh | 5 -
scripts/kconfig/confdata.c | 33 +---
scripts/kconfig/function.c | 251 ++++++++++++++++++++++++++++++
scripts/kconfig/kconf_id.c | 2 +-
scripts/kconfig/kxgettext.c | 2 +-
scripts/kconfig/lkc.h | 6 +-
scripts/kconfig/lkc_proto.h | 7 +-
scripts/kconfig/menu.c | 6 +-
scripts/kconfig/symbol.c | 139 +++--------------
scripts/kconfig/util.c | 186 ++++++++++++++++++++--
scripts/kconfig/zconf.l | 40 ++++-
scripts/kconfig/zconf.y | 48 +++---
33 files changed, 687 insertions(+), 585 deletions(-)
create mode 100755 scripts/clang-version.sh
create mode 100644 scripts/kconfig/function.c
--
2.7.4
^ permalink raw reply
* [PATCH 21/23] gcc-plugins: move GCC version check for PowerPC to Kconfig
From: Masahiro Yamada @ 2018-02-16 18:38 UTC (permalink / raw)
To: linux-kbuild, Linus Torvalds
Cc: Greg Kroah-Hartman, Arnd Bergmann, Kees Cook, Randy Dunlap,
Ulf Magnusson, Sam Ravnborg, Michal Marek, Masahiro Yamada,
Michael Ellerman, Benjamin Herrenschmidt, linux-kernel,
Paul Mackerras, kernel-hardening, linuxppc-dev, Emese Revfy
In-Reply-To: <1518806331-7101-1-git-send-email-yamada.masahiro@socionext.com>
For PowerPC, GCC 5.2 is the requirement for GCC plugins. Move the
version check to Kconfig, and remove the ugly checker.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
arch/powerpc/Kconfig | 2 +-
scripts/Makefile.gcc-plugins | 8 --------
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 73ce5dd..b8474c2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -195,7 +195,7 @@ config PPC
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
- select HAVE_GCC_PLUGINS
+ select HAVE_GCC_PLUGINS if GCC_VERSION >= 50200
select HAVE_GENERIC_GUP
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
select HAVE_IDE
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index b0f9108..25da4c0 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -56,14 +56,6 @@ gcc-plugins-check: FORCE
ifdef CONFIG_GCC_PLUGINS
ifeq ($(PLUGINCC),)
ifneq ($(GCC_PLUGINS_CFLAGS),)
- # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing
- # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 have
- # issues with 64-bit targets.
- ifeq ($(ARCH),powerpc)
- ifeq ($(call cc-ifversion, -le, 0501, y), y)
- @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1
- endif
- endif
$(Q)$(srctree)/scripts/gcc-plugin.sh --show-error $(HOSTCXX) $(CC) || true
@echo "Cannot use CONFIG_GCC_PLUGINS: your gcc installation does not support plugins, perhaps the necessary headers are missing?" >&2 && exit 1
endif
--
2.7.4
^ permalink raw reply related
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 17:50 UTC (permalink / raw)
To: Ravi Bangoria
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe
In-Reply-To: <20180216172901.GB16919@kernel.org>
Em Fri, Feb 16, 2018 at 02:29:01PM -0300, Arnaldo Carvalho de Melo escreveu:
> Humm, we need to create two tables, one for 32-bit and another for 64,
> even with ppc not having (AFAIK) clashes in syscall numbers for 32/64...
>
> Trying to do it now.
Now seems to work, take a look at my perf/core branch, should be one of the first few csets.
perfbuilder@cc1a85517216:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_32.c
[192] = "mmap2",
perfbuilder@cc1a85517216:/git/perf$ powerpc-linux-gnu-gcc --version
powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
perfbuilder@cc1a85517216:/git/perf$
perfbuilder@9d7fc9dcfb73:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_32.c
[192] = "mmap2",
perfbuilder@9d7fc9dcfb73:/git/perf$ grep 192 /tmp/build/perf/arch/powerpc/include/generated/asm/syscalls_64.c
perfbuilder@9d7fc9dcfb73:/git/perf$ powerpc64-linux-gnu-gcc --version
powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
perfbuilder@9d7fc9dcfb73:/git/perf$
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 17:29 UTC (permalink / raw)
To: Ravi Bangoria
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe
In-Reply-To: <20180216170812.GA16919@kernel.org>
Em Fri, Feb 16, 2018 at 02:08:12PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, Feb 16, 2018 at 02:03:36PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Fri, Feb 16, 2018 at 01:56:16PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Fri, Feb 16, 2018 at 01:52:45PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Jan 29, 2018 at 02:04:15PM +0530, Ravi Bangoria escreveu:
> > > > > Will be used for generating the syscall id/string translation table.
> > > > >
> > > > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> > > > > ---
> > > > > tools/arch/powerpc/include/uapi/asm/unistd.h | 399 +++++++++++++++++++++++++++
> > > > > tools/perf/check-headers.sh | 1 +
> > > > > 2 files changed, 400 insertions(+)
> > > > > create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
> > > >
> > > > Not building on a cross-compiling environment (ubuntu 16.04), I'm checking...
> > >
> > > BTW, details about that environment:
> > >
> > > 46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> >
> > So, you did it just for ppc64? Because...
> >
> > 46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> > 47 69.81 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
> > 48 68.35 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> >
> > Its just on ppc32 that his is falling apart.
>
> So, $(SRCARCH) maps to both powerpc and powerpc64m which will set
> NO_SYSCALL_TABLE to zero, thus linking against
> tools/perf/util/syscalltbl.o, which will include the generated
> syscalls_64.c only for ppc64, b00m.
Ok, so after looking at:
commit eef289f79c03ba5ca197e2ac1e33906175f01c39
Author: Paul Mackerras <paulus@samba.org>
Date: Mon Oct 10 22:56:11 2005 +1000
powerpc: Merge asm/unistd.h
Signed-off-by: Paul Mackerras <paulus@samba.org>
----
Humm, we need to create two tables, one for 32-bit and another for 64,
even with ppc not having (AFAIK) clashes in syscall numbers for 32/64...
Trying to do it now.
- Arnaldo
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 17:08 UTC (permalink / raw)
To: Ravi Bangoria
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe
In-Reply-To: <20180216170336.GG24436@kernel.org>
Em Fri, Feb 16, 2018 at 02:03:36PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, Feb 16, 2018 at 01:56:16PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Fri, Feb 16, 2018 at 01:52:45PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Jan 29, 2018 at 02:04:15PM +0530, Ravi Bangoria escreveu:
> > > > Will be used for generating the syscall id/string translation table.
> > > >
> > > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> > > > ---
> > > > tools/arch/powerpc/include/uapi/asm/unistd.h | 399 +++++++++++++++++++++++++++
> > > > tools/perf/check-headers.sh | 1 +
> > > > 2 files changed, 400 insertions(+)
> > > > create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
> > >
> > > Not building on a cross-compiling environment (ubuntu 16.04), I'm checking...
> >
> > BTW, details about that environment:
> >
> > 46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
>
> So, you did it just for ppc64? Because...
>
> 46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> 47 69.81 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
> 48 68.35 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
>
> Its just on ppc32 that his is falling apart.
So, $(SRCARCH) maps to both powerpc and powerpc64m which will set
NO_SYSCALL_TABLE to zero, thus linking against
tools/perf/util/syscalltbl.o, which will include the generated
syscalls_64.c only for ppc64, b00m.
+++ b/tools/perf/Makefile.config
@@ -27,6 +27,8 @@ NO_SYSCALL_TABLE := 1
# Additional ARCH settings for ppc
ifeq ($(SRCARCH),powerpc)
NO_PERF_REGS := 0
+ NO_SYSCALL_TABLE := 0
+ CFLAGS += -I$(OUTPUT)arch/powerpc/include/generated
LIBUNWIND_LIBS := -lunwind -lunwind-ppc64
endif
+++ b/tools/perf/util/syscalltbl.c
static const char **syscalltbl_native = syscalltbl_s390_64;
+#elif defined(__powerpc64__)
+#include <asm/syscalls_64.c>
+const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_64_MAX_ID;
+static const char **syscalltbl_native = syscalltbl_powerpc_64;
#endif
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 17:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ravi Bangoria, alexander.shishkin, jolsa, namhyung, linux-kernel,
brueckner, tmricht, linuxppc-dev, mpe
In-Reply-To: <20180216165616.GF24436@kernel.org>
Em Fri, Feb 16, 2018 at 01:56:16PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Fri, Feb 16, 2018 at 01:52:45PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 29, 2018 at 02:04:15PM +0530, Ravi Bangoria escreveu:
> > > Will be used for generating the syscall id/string translation table.
> > >
> > > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> > > ---
> > > tools/arch/powerpc/include/uapi/asm/unistd.h | 399 +++++++++++++++++++++++++++
> > > tools/perf/check-headers.sh | 1 +
> > > 2 files changed, 400 insertions(+)
> > > create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
> >
> > Not building on a cross-compiling environment (ubuntu 16.04), I'm checking...
>
> BTW, details about that environment:
>
> 46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
So, you did it just for ppc64? Because...
46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
47 69.81 ubuntu:16.04-x-powerpc64 : Ok powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609
48 68.35 ubuntu:16.04-x-powerpc64el : Ok powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Its just on ppc32 that his is falling apart.
>
> > CC /tmp/build/perf/util/syscalltbl.o
> > util/syscalltbl.c: In function 'syscalltbl__init_native':
> > util/syscalltbl.c:64:19: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
> > for (i = 0; i <= syscalltbl_native_max_id; ++i)
> > ^
> > util/syscalltbl.c:64:19: note: each undeclared identifier is reported only once for each function it appears in
> > util/syscalltbl.c:65:7: error: 'syscalltbl_native' undeclared (first use in this function)
> > if (syscalltbl_native[i])
> > ^
> > util/syscalltbl.c: In function 'syscalltbl__name':
> > util/syscalltbl.c:105:15: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
> > return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> > ^
> > util/syscalltbl.c:105:42: error: 'syscalltbl_native' undeclared (first use in this function)
> > return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> > ^
> > util/syscalltbl.c:106:1: error: control reaches end of non-void function [-Werror=return-type]
> > }
> > ^
> > cc1: all warnings being treated as errors
> > mv: cannot stat '/tmp/build/perf/util/.syscalltbl.o.tmp': No such file or directory
> > /git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/syscalltbl.o' failed
> > make[4]: *** [/tmp/build/perf/util/syscalltbl.o] Error 1
> > make[4]: *** Waiting for unfinished jobs....
> > CC /tmp/build/perf/tests/sample-parsing.o
> > CC /tmp/build/perf/tests/parse-no-sample-id-all.o
> > CC /tmp/build/perf/tests/kmod-path.o
> > CC /tmp/build/perf/tests/thread-map.o
> > CC /tmp/build/perf/tests/llvm.o
> > CC /tmp/build/perf/tests/bpf.o
> > CC /tmp/build/perf/tests/topology.o
> > CC /tmp/build/perf/tests/mem.o
> > CC /tmp/build/perf/tests/cpumap.o
> > CC /tmp/build/perf/tests/stat.o
> > /git/linux/tools/build/Makefile.build:139: recipe for target 'util' failed
> > make[3]: *** [util] Error 2
> > Makefile.perf:629: recipe for target '/tmp/build/perf/libperf-in.o' failed
> > make[2]: *** [/tmp/build/perf/libperf-in.o] Error 2
> > make[2]: *** Waiting for unfinished jobs....
> > CC /tmp/build/perf/tests/event_update.o
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 16:56 UTC (permalink / raw)
To: Ravi Bangoria
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe
In-Reply-To: <20180216165245.GD24436@kernel.org>
Em Fri, Feb 16, 2018 at 01:52:45PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 29, 2018 at 02:04:15PM +0530, Ravi Bangoria escreveu:
> > Will be used for generating the syscall id/string translation table.
> >
> > Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> > ---
> > tools/arch/powerpc/include/uapi/asm/unistd.h | 399 +++++++++++++++++++++++++++
> > tools/perf/check-headers.sh | 1 +
> > 2 files changed, 400 insertions(+)
> > create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
>
> Not building on a cross-compiling environment (ubuntu 16.04), I'm checking...
BTW, details about that environment:
46 29.83 ubuntu:16.04-x-powerpc : FAIL powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
> CC /tmp/build/perf/util/syscalltbl.o
> util/syscalltbl.c: In function 'syscalltbl__init_native':
> util/syscalltbl.c:64:19: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
> for (i = 0; i <= syscalltbl_native_max_id; ++i)
> ^
> util/syscalltbl.c:64:19: note: each undeclared identifier is reported only once for each function it appears in
> util/syscalltbl.c:65:7: error: 'syscalltbl_native' undeclared (first use in this function)
> if (syscalltbl_native[i])
> ^
> util/syscalltbl.c: In function 'syscalltbl__name':
> util/syscalltbl.c:105:15: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
> return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> ^
> util/syscalltbl.c:105:42: error: 'syscalltbl_native' undeclared (first use in this function)
> return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
> ^
> util/syscalltbl.c:106:1: error: control reaches end of non-void function [-Werror=return-type]
> }
> ^
> cc1: all warnings being treated as errors
> mv: cannot stat '/tmp/build/perf/util/.syscalltbl.o.tmp': No such file or directory
> /git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/syscalltbl.o' failed
> make[4]: *** [/tmp/build/perf/util/syscalltbl.o] Error 1
> make[4]: *** Waiting for unfinished jobs....
> CC /tmp/build/perf/tests/sample-parsing.o
> CC /tmp/build/perf/tests/parse-no-sample-id-all.o
> CC /tmp/build/perf/tests/kmod-path.o
> CC /tmp/build/perf/tests/thread-map.o
> CC /tmp/build/perf/tests/llvm.o
> CC /tmp/build/perf/tests/bpf.o
> CC /tmp/build/perf/tests/topology.o
> CC /tmp/build/perf/tests/mem.o
> CC /tmp/build/perf/tests/cpumap.o
> CC /tmp/build/perf/tests/stat.o
> /git/linux/tools/build/Makefile.build:139: recipe for target 'util' failed
> make[3]: *** [util] Error 2
> Makefile.perf:629: recipe for target '/tmp/build/perf/libperf-in.o' failed
> make[2]: *** [/tmp/build/perf/libperf-in.o] Error 2
> make[2]: *** Waiting for unfinished jobs....
> CC /tmp/build/perf/tests/event_update.o
^ permalink raw reply
* Re: [PATCH 1/3] tools include powerpc: Grab a copy of arch/powerpc/include/uapi/asm/unistd.h
From: Arnaldo Carvalho de Melo @ 2018-02-16 16:52 UTC (permalink / raw)
To: Ravi Bangoria
Cc: alexander.shishkin, jolsa, namhyung, linux-kernel, brueckner,
tmricht, linuxppc-dev, mpe
In-Reply-To: <20180129083417.31240-2-ravi.bangoria@linux.vnet.ibm.com>
Em Mon, Jan 29, 2018 at 02:04:15PM +0530, Ravi Bangoria escreveu:
> Will be used for generating the syscall id/string translation table.
>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
> ---
> tools/arch/powerpc/include/uapi/asm/unistd.h | 399 +++++++++++++++++++++++++++
> tools/perf/check-headers.sh | 1 +
> 2 files changed, 400 insertions(+)
> create mode 100644 tools/arch/powerpc/include/uapi/asm/unistd.h
Not building on a cross-compiling environment (ubuntu 16.04), I'm checking...
CC /tmp/build/perf/util/syscalltbl.o
util/syscalltbl.c: In function 'syscalltbl__init_native':
util/syscalltbl.c:64:19: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
for (i = 0; i <= syscalltbl_native_max_id; ++i)
^
util/syscalltbl.c:64:19: note: each undeclared identifier is reported only once for each function it appears in
util/syscalltbl.c:65:7: error: 'syscalltbl_native' undeclared (first use in this function)
if (syscalltbl_native[i])
^
util/syscalltbl.c: In function 'syscalltbl__name':
util/syscalltbl.c:105:15: error: 'syscalltbl_native_max_id' undeclared (first use in this function)
return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
^
util/syscalltbl.c:105:42: error: 'syscalltbl_native' undeclared (first use in this function)
return id <= syscalltbl_native_max_id ? syscalltbl_native[id]: NULL;
^
util/syscalltbl.c:106:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
cc1: all warnings being treated as errors
mv: cannot stat '/tmp/build/perf/util/.syscalltbl.o.tmp': No such file or directory
/git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/syscalltbl.o' failed
make[4]: *** [/tmp/build/perf/util/syscalltbl.o] Error 1
make[4]: *** Waiting for unfinished jobs....
CC /tmp/build/perf/tests/sample-parsing.o
CC /tmp/build/perf/tests/parse-no-sample-id-all.o
CC /tmp/build/perf/tests/kmod-path.o
CC /tmp/build/perf/tests/thread-map.o
CC /tmp/build/perf/tests/llvm.o
CC /tmp/build/perf/tests/bpf.o
CC /tmp/build/perf/tests/topology.o
CC /tmp/build/perf/tests/mem.o
CC /tmp/build/perf/tests/cpumap.o
CC /tmp/build/perf/tests/stat.o
/git/linux/tools/build/Makefile.build:139: recipe for target 'util' failed
make[3]: *** [util] Error 2
Makefile.perf:629: recipe for target '/tmp/build/perf/libperf-in.o' failed
make[2]: *** [/tmp/build/perf/libperf-in.o] Error 2
make[2]: *** Waiting for unfinished jobs....
CC /tmp/build/perf/tests/event_update.o
^ permalink raw reply
* Re: [RFC][PATCH bpf v2 1/2] bpf: allow 64-bit offsets for bpf function calls
From: Naveen N. Rao @ 2018-02-16 15:50 UTC (permalink / raw)
To: ast, Daniel Borkmann, Sandipan Das, Michael Ellerman
Cc: linuxppc-dev, netdev, Michael Holzheu
In-Reply-To: <ad895533-2f15-bfe4-671c-6d1a8c672bbd@iogearbox.net>
Daniel Borkmann wrote:
> On 02/15/2018 05:25 PM, Daniel Borkmann wrote:
>> On 02/13/2018 05:05 AM, Sandipan Das wrote:
>>> The imm field of a bpf_insn is a signed 32-bit integer. For
>>> JIT-ed bpf-to-bpf function calls, it stores the offset from
>>> __bpf_call_base to the start of the callee function.
>>>
>>> For some architectures, such as powerpc64, it was found that
>>> this offset may be as large as 64 bits because of which this
>>> cannot be accomodated in the imm field without truncation.
>>>
>>> To resolve this, we additionally make aux->func within each
>>> bpf_prog associated with the functions to point to the list
>>> of all function addresses determined by the verifier.
>>>
>>> We keep the value assigned to the off field of the bpf_insn
>>> as a way to index into aux->func and also set aux->func_cnt
>>> so that this can be used for performing basic upper bound
>>> checks for the off field.
>>>
>>> Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
>>> ---
>>> v2: Make aux->func point to the list of functions determined
>>> by the verifier rather than allocating a separate callee
>>> list for each function.
>>=20
>> Approach looks good to me; do you know whether s390x JIT would
>> have similar requirement? I think one limitation that would still
>> need to be addressed later with such approach would be regarding the
>> xlated prog dump in bpftool, see 'BPF calls via JIT' in 7105e828c087
>> ("bpf: allow for correlation of maps and helpers in dump"). Any
>> ideas for this (potentially if we could use off + imm for calls,
>> we'd get to 48 bits, but that seems still not be enough as you say)?
All good points. I'm not really sure how s390x works, so I can't comment=20
on that, but I'm copying Michael Holzheu for his consideration.
With the existing scheme, 48 bits won't be enough, so we rejected that=20
approach. I can also see how this will be a problem with bpftool, but I=20
haven't looked into it in detail. I wonder if we can annotate the output=20
to indicate the function being referred to?
>=20
> One other random thought, although I'm not sure how feasible this
> is for ppc64 JIT to realize ... but idea would be to have something
> like the below:
>=20
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 29ca920..daa7258 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -512,6 +512,11 @@ int bpf_get_kallsym(unsigned int symnum, unsigned lo=
ng *value, char *type,
> return ret;
> }
>=20
> +void * __weak bpf_jit_image_alloc(unsigned long size)
> +{
> + return module_alloc(size);
> +}
> +
> struct bpf_binary_header *
> bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
> unsigned int alignment,
> @@ -525,7 +530,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image=
_ptr,
> * random section of illegal instructions.
> */
> size =3D round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE);
> - hdr =3D module_alloc(size);
> + hdr =3D bpf_jit_image_alloc(size);
> if (hdr =3D=3D NULL)
> return NULL;
>=20
> And ppc64 JIT could override bpf_jit_image_alloc() in a similar way
> like some archs would override the module_alloc() helper through a
> custom implementation, usually via __vmalloc_node_range(), so we
> could perhaps fit the range for BPF JITed images in a way that they
> could use the 32bit imm in the end? There are not that many progs
> loaded typically, so the range could be a bit narrower in such case
> anyway. (Not sure if this would work out though, but I thought to
> bring it up.)
That'd be a good option to consider. I don't think we want to allocate=20
anything from the linear memory range since users could load=20
unprivileged BPF programs and consume a lot of memory that way. I doubt=20
if we can map vmalloc'ed memory into the 0xc0 address range, but I'm not=20
entirely sure.
Michael,
Is the above possible? The question is if we can have BPF programs be=20
allocated within 4GB of __bpf_call_base (which is a kernel symbol), so=20
that calls to those programs can be encoded in a 32-bit immediate field=20
in a BPF instruction. As an extension, we may be able to extend it to=20
48-bits by combining with another BPF instruction field (offset). In=20
either case, the vmalloc'ed address range won't work.
The alternative is to pass the full 64-bit address of the BPF program in=20
an auxiliary field (as proposed in this patch set) but we need to fix it=20
up for 'bpftool' as well.
Thanks,
Naveen
=
^ permalink raw reply
* [PATCH V3] cxl: Fix timebase synchronization status on P9
From: Christophe Lombard @ 2018-02-16 15:27 UTC (permalink / raw)
To: linuxppc-dev, fbarrat, vaibhav, andrew.donnellan
The PSL Timebase register is updated by the PSL to maintain the
timebase.
On P9, the Timebase value is only provided by the CAPP as received
the last time a timebase request was performed.
The timebase requests are initiated through the adapter configuration or
application registers.
The specific sysfs entry "/sys/class/cxl/cardxx/psl_timebase_synced" is
now dynamically updated according the content of the PSL Timebase
register.
Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
This patch applies on top of this patch:
http://patchwork.ozlabs.org/patch/873663/
Changelog[v3]
- Rebased to latest upstream.
- Dynamic update is now applied to P8.
Changelog[v2]
- Missing Signed-off-by.
- Spaces required around the ':'.
---
drivers/misc/cxl/pci.c | 17 -----------------
drivers/misc/cxl/sysfs.c | 10 ++++++++++
2 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 66eed6a..3247eaf 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -606,9 +606,6 @@ static u64 timebase_read_xsl(struct cxl *adapter)
static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
{
- u64 psl_tb;
- int delta;
- unsigned int retry = 0;
struct device_node *np;
adapter->psl_timebase_synced = false;
@@ -636,20 +633,6 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb);
- /* Wait until CORE TB and PSL TB difference <= 16usecs */
- do {
- msleep(1);
- if (retry++ > 5) {
- dev_info(&dev->dev, "PSL timebase can't synchronize\n");
- return;
- }
- psl_tb = adapter->native->sl_ops->timebase_read(adapter);
- delta = mftb() - psl_tb;
- if (delta < 0)
- delta = -delta;
- } while (tb_to_ns(delta) > 16000);
-
- adapter->psl_timebase_synced = true;
return;
}
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index a8b6d6a..3f758d9 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -62,6 +62,16 @@ static ssize_t psl_timebase_synced_show(struct device *device,
char *buf)
{
struct cxl *adapter = to_cxl_adapter(device);
+ u64 psl_tb;
+ int delta;
+
+ psl_tb = adapter->native->sl_ops->timebase_read(adapter);
+ delta = mftb() - psl_tb;
+ if (delta < 0)
+ delta = -delta;
+
+ /* CORE TB and PSL TB difference <= 16usecs ? */
+ adapter->psl_timebase_synced = (tb_to_ns(delta) < 16000) ? true : false;
return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
}
--
2.7.4
^ permalink raw reply related
* [PATCH v8 22/24] mm: Speculative page fault handler return VMA
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
When the speculative page fault handler is returning VM_RETRY, there is a
chance that VMA fetched without grabbing the mmap_sem can be reused by the
legacy page fault handler. By reusing it, we avoid calling find_vma()
again. To achieve, that we must ensure that the VMA structure will not be
freed in our back. This is done by getting the reference on it (get_vma())
and by assuming that the caller will call the new service
can_reuse_spf_vma() once it has grabbed the mmap_sem.
can_reuse_spf_vma() is first checking that the VMA is still in the RB tree
, and then that the VMA's boundaries matched the passed address and release
the reference on the VMA so that it can be freed if needed.
In the case the VMA is freed, can_reuse_spf_vma() will have returned false
as the VMA is no more in the RB tree.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
include/linux/mm.h | 5 +-
mm/memory.c | 136 +++++++++++++++++++++++++++++++++--------------------
2 files changed, 88 insertions(+), 53 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c383a4e2ceb3..0cd31a37bb3d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1355,7 +1355,10 @@ extern int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
unsigned int flags);
#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
extern int handle_speculative_fault(struct mm_struct *mm,
- unsigned long address, unsigned int flags);
+ unsigned long address, unsigned int flags,
+ struct vm_area_struct **vma);
+extern bool can_reuse_spf_vma(struct vm_area_struct *vma,
+ unsigned long address);
#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
unsigned long address, unsigned int fault_flags,
diff --git a/mm/memory.c b/mm/memory.c
index 2ef686405154..1f5ce5ff79af 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4307,13 +4307,22 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
/* This is required by vm_normal_page() */
#error "Speculative page fault handler requires __HAVE_ARCH_PTE_SPECIAL"
#endif
-
/*
* vm_normal_page() adds some processing which should be done while
* hodling the mmap_sem.
*/
+
+/*
+ * Tries to handle the page fault in a speculative way, without grabbing the
+ * mmap_sem.
+ * When VM_FAULT_RETRY is returned, the vma pointer is valid and this vma must
+ * be checked later when the mmap_sem has been grabbed by calling
+ * can_reuse_spf_vma().
+ * This is needed as the returned vma is kept in memory until the call to
+ * can_reuse_spf_vma() is made.
+ */
int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
- unsigned int flags)
+ unsigned int flags, struct vm_area_struct **vma)
{
struct vm_fault vmf = {
.address = address,
@@ -4322,7 +4331,6 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
p4d_t *p4d, p4dval;
pud_t pudval;
int seq, ret = VM_FAULT_RETRY;
- struct vm_area_struct *vma;
#ifdef CONFIG_NUMA
struct mempolicy *pol;
#endif
@@ -4331,14 +4339,16 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
flags &= ~(FAULT_FLAG_ALLOW_RETRY|FAULT_FLAG_KILLABLE);
flags |= FAULT_FLAG_SPECULATIVE;
- vma = get_vma(mm, address);
- if (!vma)
+ *vma = get_vma(mm, address);
+ if (!*vma)
return ret;
+ vmf.vma = *vma;
- seq = raw_read_seqcount(&vma->vm_sequence); /* rmb <-> seqlock,vma_rb_erase() */
+ /* rmb <-> seqlock,vma_rb_erase() */
+ seq = raw_read_seqcount(&vmf.vma->vm_sequence);
if (seq & 1) {
- trace_spf_vma_changed(_RET_IP_, vma, address);
- goto out_put;
+ trace_spf_vma_changed(_RET_IP_, vmf.vma, address);
+ return ret;
}
/*
@@ -4346,9 +4356,9 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
* with the VMA.
* This include huge page from hugetlbfs.
*/
- if (vma->vm_ops) {
- trace_spf_vma_notsup(_RET_IP_, vma, address);
- goto out_put;
+ if (vmf.vma->vm_ops) {
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
+ return ret;
}
/*
@@ -4356,18 +4366,18 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
* because vm_next and vm_prev must be safe. This can't be guaranteed
* in the speculative path.
*/
- if (unlikely(!vma->anon_vma)) {
- trace_spf_vma_notsup(_RET_IP_, vma, address);
- goto out_put;
+ if (unlikely(!vmf.vma->anon_vma)) {
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
+ return ret;
}
- vmf.vma_flags = READ_ONCE(vma->vm_flags);
- vmf.vma_page_prot = READ_ONCE(vma->vm_page_prot);
+ vmf.vma_flags = READ_ONCE(vmf.vma->vm_flags);
+ vmf.vma_page_prot = READ_ONCE(vmf.vma->vm_page_prot);
/* Can't call userland page fault handler in the speculative path */
if (unlikely(vmf.vma_flags & VM_UFFD_MISSING)) {
- trace_spf_vma_notsup(_RET_IP_, vma, address);
- goto out_put;
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
+ return ret;
}
if (vmf.vma_flags & VM_GROWSDOWN || vmf.vma_flags & VM_GROWSUP) {
@@ -4376,48 +4386,39 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
* boundaries but we want to trace it as not supported instead
* of changed.
*/
- trace_spf_vma_notsup(_RET_IP_, vma, address);
- goto out_put;
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
+ return ret;
}
- if (address < READ_ONCE(vma->vm_start)
- || READ_ONCE(vma->vm_end) <= address) {
- trace_spf_vma_changed(_RET_IP_, vma, address);
- goto out_put;
+ if (address < READ_ONCE(vmf.vma->vm_start)
+ || READ_ONCE(vmf.vma->vm_end) <= address) {
+ trace_spf_vma_changed(_RET_IP_, vmf.vma, address);
+ return ret;
}
- if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
+ if (!arch_vma_access_permitted(vmf.vma, flags & FAULT_FLAG_WRITE,
flags & FAULT_FLAG_INSTRUCTION,
- flags & FAULT_FLAG_REMOTE)) {
- trace_spf_vma_access(_RET_IP_, vma, address);
- ret = VM_FAULT_SIGSEGV;
- goto out_put;
- }
+ flags & FAULT_FLAG_REMOTE))
+ goto out_segv;
/* This is one is required to check that the VMA has write access set */
if (flags & FAULT_FLAG_WRITE) {
- if (unlikely(!(vmf.vma_flags & VM_WRITE))) {
- trace_spf_vma_access(_RET_IP_, vma, address);
- ret = VM_FAULT_SIGSEGV;
- goto out_put;
- }
- } else if (unlikely(!(vmf.vma_flags & (VM_READ|VM_EXEC|VM_WRITE)))) {
- trace_spf_vma_access(_RET_IP_, vma, address);
- ret = VM_FAULT_SIGSEGV;
- goto out_put;
- }
+ if (unlikely(!(vmf.vma_flags & VM_WRITE)))
+ goto out_segv;
+ } else if (unlikely(!(vmf.vma_flags & (VM_READ|VM_EXEC|VM_WRITE))))
+ goto out_segv;
#ifdef CONFIG_NUMA
/*
* MPOL_INTERLEAVE implies additional check in mpol_misplaced() which
* are not compatible with the speculative page fault processing.
*/
- pol = __get_vma_policy(vma, address);
+ pol = __get_vma_policy(vmf.vma, address);
if (!pol)
pol = get_task_policy(current);
if (pol && pol->mode == MPOL_INTERLEAVE) {
- trace_spf_vma_notsup(_RET_IP_, vma, address);
- goto out_put;
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
+ return ret;
}
#endif
@@ -4479,9 +4480,8 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
vmf.pte = NULL;
}
- vmf.vma = vma;
- vmf.pgoff = linear_page_index(vma, address);
- vmf.gfp_mask = __get_fault_gfp_mask(vma);
+ vmf.pgoff = linear_page_index(vmf.vma, address);
+ vmf.gfp_mask = __get_fault_gfp_mask(vmf.vma);
vmf.sequence = seq;
vmf.flags = flags;
@@ -4491,16 +4491,22 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
* We need to re-validate the VMA after checking the bounds, otherwise
* we might have a false positive on the bounds.
*/
- if (read_seqcount_retry(&vma->vm_sequence, seq)) {
- trace_spf_vma_changed(_RET_IP_, vma, address);
- goto out_put;
+ if (read_seqcount_retry(&vmf.vma->vm_sequence, seq)) {
+ trace_spf_vma_changed(_RET_IP_, vmf.vma, address);
+ return ret;
}
mem_cgroup_oom_enable();
ret = handle_pte_fault(&vmf);
mem_cgroup_oom_disable();
- put_vma(vma);
+ /*
+ * If there is no need to retry, don't return the vma to the caller.
+ */
+ if (!(ret & VM_FAULT_RETRY)) {
+ put_vma(vmf.vma);
+ *vma = NULL;
+ }
/*
* The task may have entered a memcg OOM situation but
@@ -4513,9 +4519,35 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
return ret;
out_walk:
- trace_spf_vma_notsup(_RET_IP_, vma, address);
+ trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
local_irq_enable();
-out_put:
+ return ret;
+
+out_segv:
+ trace_spf_vma_access(_RET_IP_, vmf.vma, address);
+ /*
+ * We don't return VM_FAULT_RETRY so the caller is not expected to
+ * retrieve the fetched VMA.
+ */
+ put_vma(vmf.vma);
+ *vma = NULL;
+ return VM_FAULT_SIGSEGV;
+}
+
+/*
+ * This is used to know if the vma fetch in the speculative page fault handler
+ * is still valid when trying the regular fault path while holding the
+ * mmap_sem.
+ * The call to put_vma(vma) must be made after checking the vma's fields, as
+ * the vma may be freed by put_vma(). In such a case it is expected that false
+ * is returned.
+ */
+bool can_reuse_spf_vma(struct vm_area_struct *vma, unsigned long address)
+{
+ bool ret;
+
+ ret = !RB_EMPTY_NODE(&vma->vm_rb) &&
+ vma->vm_start <= address && address < vma->vm_end;
put_vma(vma);
return ret;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v8 24/24] powerpc/mm: Add speculative page fault
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
This patch enable the speculative page fault on the PowerPC
architecture.
This will try a speculative page fault without holding the mmap_sem,
if it returns with VM_FAULT_RETRY, the mmap_sem is acquired and the
traditional page fault processing is done.
The speculative path is only tried for multithreaded process as there is no
risk of contention on the mmap_sem otherwise.
Build on if CONFIG_SPECULATIVE_PAGE_FAULT is defined (currently for
BOOK3S_64 && SMP).
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
arch/powerpc/mm/fault.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 866446cf2d9a..104f3cc86b51 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -392,6 +392,9 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
struct vm_area_struct * vma;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ struct vm_area_struct *spf_vma = NULL;
+#endif
struct mm_struct *mm = current->mm;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
int is_exec = TRAP(regs) == 0x400;
@@ -459,6 +462,20 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
if (is_exec)
flags |= FAULT_FLAG_INSTRUCTION;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ if (is_user && (atomic_read(&mm->mm_users) > 1)) {
+ /* let's try a speculative page fault without grabbing the
+ * mmap_sem.
+ */
+ fault = handle_speculative_fault(mm, address, flags, &spf_vma);
+ if (!(fault & VM_FAULT_RETRY)) {
+ perf_sw_event(PERF_COUNT_SW_SPF, 1,
+ regs, address);
+ goto done;
+ }
+ }
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
+
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
* kernel and should generate an OOPS. Unfortunately, in the case of an
@@ -489,7 +506,16 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
might_sleep();
}
- vma = find_vma(mm, address);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ if (spf_vma) {
+ if (can_reuse_spf_vma(spf_vma, address))
+ vma = spf_vma;
+ else
+ vma = find_vma(mm, address);
+ spf_vma = NULL;
+ } else
+#endif
+ vma = find_vma(mm, address);
if (unlikely(!vma))
return bad_area(regs, address);
if (likely(vma->vm_start <= address))
@@ -568,6 +594,9 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
up_read(¤t->mm->mmap_sem);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+done:
+#endif
if (unlikely(fault & VM_FAULT_ERROR))
return mm_fault_error(regs, address, fault);
--
2.7.4
^ permalink raw reply related
* [PATCH v8 23/24] x86/mm: Add speculative pagefault handling
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
From: Peter Zijlstra <peterz@infradead.org>
Try a speculative fault before acquiring mmap_sem, if it returns with
VM_FAULT_RETRY continue with the mmap_sem acquisition and do the
traditional fault.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
[Clearing of FAULT_FLAG_ALLOW_RETRY is now done in
handle_speculative_fault()]
[Retry with usual fault path in the case VM_ERROR is returned by
handle_speculative_fault(). This allows signal to be delivered]
[Don't build SPF call if !CONFIG_SPECULATIVE_PAGE_FAULT]
[Try speculative fault path only for multi threaded processes]
[Try to the VMA fetch during the speculative path in case of retry]
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
arch/x86/mm/fault.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 800de815519c..d9f9236ccb9a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1239,6 +1239,9 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
unsigned long address)
{
struct vm_area_struct *vma;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ struct vm_area_struct *spf_vma = NULL;
+#endif
struct task_struct *tsk;
struct mm_struct *mm;
int fault, major = 0;
@@ -1336,6 +1339,27 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
if (error_code & X86_PF_INSTR)
flags |= FAULT_FLAG_INSTRUCTION;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ if ((error_code & X86_PF_USER) && (atomic_read(&mm->mm_users) > 1)) {
+ fault = handle_speculative_fault(mm, address, flags,
+ &spf_vma);
+
+ if (!(fault & VM_FAULT_RETRY)) {
+ if (!(fault & VM_FAULT_ERROR)) {
+ perf_sw_event(PERF_COUNT_SW_SPF, 1,
+ regs, address);
+ goto done;
+ }
+ /*
+ * In case of error we need the pkey value, but
+ * can't get it from the spf_vma as it is only returned
+ * when VM_FAULT_RETRY is returned. So we have to
+ * retry the page fault with the mmap_sem grabbed.
+ */
+ }
+ }
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
+
/*
* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in
@@ -1369,7 +1393,16 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
might_sleep();
}
- vma = find_vma(mm, address);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ if (spf_vma) {
+ if (can_reuse_spf_vma(spf_vma, address))
+ vma = spf_vma;
+ else
+ vma = find_vma(mm, address);
+ spf_vma = NULL;
+ } else
+#endif
+ vma = find_vma(mm, address);
if (unlikely(!vma)) {
bad_area(regs, error_code, address);
return;
@@ -1455,6 +1488,9 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code,
return;
}
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+done:
+#endif
/*
* Major/minor page fault accounting. If any of the events
* returned VM_FAULT_MAJOR, we account it as a major fault.
--
2.7.4
^ permalink raw reply related
* [PATCH v8 19/24] mm: Adding speculative page fault failure trace events
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
This patch a set of new trace events to collect the speculative page fault
event failures.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
include/trace/events/pagefault.h | 87 ++++++++++++++++++++++++++++++++++++++++
mm/memory.c | 62 ++++++++++++++++++++++------
2 files changed, 136 insertions(+), 13 deletions(-)
create mode 100644 include/trace/events/pagefault.h
diff --git a/include/trace/events/pagefault.h b/include/trace/events/pagefault.h
new file mode 100644
index 000000000000..1d793f8c739b
--- /dev/null
+++ b/include/trace/events/pagefault.h
@@ -0,0 +1,87 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM pagefault
+
+#if !defined(_TRACE_PAGEFAULT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PAGEFAULT_H
+
+#include <linux/tracepoint.h>
+#include <linux/mm.h>
+
+DECLARE_EVENT_CLASS(spf,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address),
+
+ TP_STRUCT__entry(
+ __field(unsigned long, caller)
+ __field(unsigned long, vm_start)
+ __field(unsigned long, vm_end)
+ __field(unsigned long, address)
+ ),
+
+ TP_fast_assign(
+ __entry->caller = caller;
+ __entry->vm_start = vma->vm_start;
+ __entry->vm_end = vma->vm_end;
+ __entry->address = address;
+ ),
+
+ TP_printk("ip:%lx vma:%lx-%lx address:%lx",
+ __entry->caller, __entry->vm_start, __entry->vm_end,
+ __entry->address)
+);
+
+DEFINE_EVENT(spf, spf_pte_lock,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+DEFINE_EVENT(spf, spf_vma_changed,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+DEFINE_EVENT(spf, spf_vma_noanon,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+DEFINE_EVENT(spf, spf_vma_notsup,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+DEFINE_EVENT(spf, spf_vma_access,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+DEFINE_EVENT(spf, spf_pmd_changed,
+
+ TP_PROTO(unsigned long caller,
+ struct vm_area_struct *vma, unsigned long address),
+
+ TP_ARGS(caller, vma, address)
+);
+
+#endif /* _TRACE_PAGEFAULT_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/mm/memory.c b/mm/memory.c
index efc32173264e..2ef686405154 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -80,6 +80,9 @@
#include "internal.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/pagefault.h>
+
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
#warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid.
#endif
@@ -2310,23 +2313,30 @@ static bool pte_spinlock(struct vm_fault *vmf)
}
local_irq_disable();
- if (vma_has_changed(vmf))
+ if (vma_has_changed(vmf)) {
+ trace_spf_vma_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
+ }
/*
* We check if the pmd value is still the same to ensure that there
* is a huge collapse operation in progress in our back.
*/
pmdval = READ_ONCE(*vmf->pmd);
- if (!pmd_same(pmdval, vmf->orig_pmd))
+ if (!pmd_same(pmdval, vmf->orig_pmd)) {
+ trace_spf_pmd_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
+ }
vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
- if (unlikely(!spin_trylock(vmf->ptl)))
+ if (unlikely(!spin_trylock(vmf->ptl))) {
+ trace_spf_pte_lock(_RET_IP_, vmf->vma, vmf->address);
goto out;
+ }
if (vma_has_changed(vmf)) {
spin_unlock(vmf->ptl);
+ trace_spf_vma_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
}
@@ -2357,16 +2367,20 @@ static bool pte_map_lock(struct vm_fault *vmf)
* block on the PTL and thus we're safe.
*/
local_irq_disable();
- if (vma_has_changed(vmf))
+ if (vma_has_changed(vmf)) {
+ trace_spf_vma_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
+ }
/*
* We check if the pmd value is still the same to ensure that there
* is a huge collapse operation in progress in our back.
*/
pmdval = READ_ONCE(*vmf->pmd);
- if (!pmd_same(pmdval, vmf->orig_pmd))
+ if (!pmd_same(pmdval, vmf->orig_pmd)) {
+ trace_spf_pmd_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
+ }
/*
* Same as pte_offset_map_lock() except that we call
@@ -2379,11 +2393,13 @@ static bool pte_map_lock(struct vm_fault *vmf)
pte = pte_offset_map(vmf->pmd, vmf->address);
if (unlikely(!spin_trylock(ptl))) {
pte_unmap(pte);
+ trace_spf_pte_lock(_RET_IP_, vmf->vma, vmf->address);
goto out;
}
if (vma_has_changed(vmf)) {
pte_unmap_unlock(pte, ptl);
+ trace_spf_vma_changed(_RET_IP_, vmf->vma, vmf->address);
goto out;
}
@@ -4320,47 +4336,60 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
return ret;
seq = raw_read_seqcount(&vma->vm_sequence); /* rmb <-> seqlock,vma_rb_erase() */
- if (seq & 1)
+ if (seq & 1) {
+ trace_spf_vma_changed(_RET_IP_, vma, address);
goto out_put;
+ }
/*
* Can't call vm_ops service has we don't know what they would do
* with the VMA.
* This include huge page from hugetlbfs.
*/
- if (vma->vm_ops)
+ if (vma->vm_ops) {
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
goto out_put;
+ }
/*
* __anon_vma_prepare() requires the mmap_sem to be held
* because vm_next and vm_prev must be safe. This can't be guaranteed
* in the speculative path.
*/
- if (unlikely(!vma->anon_vma))
+ if (unlikely(!vma->anon_vma)) {
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
goto out_put;
+ }
vmf.vma_flags = READ_ONCE(vma->vm_flags);
vmf.vma_page_prot = READ_ONCE(vma->vm_page_prot);
/* Can't call userland page fault handler in the speculative path */
- if (unlikely(vmf.vma_flags & VM_UFFD_MISSING))
+ if (unlikely(vmf.vma_flags & VM_UFFD_MISSING)) {
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
goto out_put;
+ }
- if (vmf.vma_flags & VM_GROWSDOWN || vmf.vma_flags & VM_GROWSUP)
+ if (vmf.vma_flags & VM_GROWSDOWN || vmf.vma_flags & VM_GROWSUP) {
/*
* This could be detected by the check address against VMA's
* boundaries but we want to trace it as not supported instead
* of changed.
*/
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
goto out_put;
+ }
if (address < READ_ONCE(vma->vm_start)
- || READ_ONCE(vma->vm_end) <= address)
+ || READ_ONCE(vma->vm_end) <= address) {
+ trace_spf_vma_changed(_RET_IP_, vma, address);
goto out_put;
+ }
if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
flags & FAULT_FLAG_INSTRUCTION,
flags & FAULT_FLAG_REMOTE)) {
+ trace_spf_vma_access(_RET_IP_, vma, address);
ret = VM_FAULT_SIGSEGV;
goto out_put;
}
@@ -4368,10 +4397,12 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
/* This is one is required to check that the VMA has write access set */
if (flags & FAULT_FLAG_WRITE) {
if (unlikely(!(vmf.vma_flags & VM_WRITE))) {
+ trace_spf_vma_access(_RET_IP_, vma, address);
ret = VM_FAULT_SIGSEGV;
goto out_put;
}
} else if (unlikely(!(vmf.vma_flags & (VM_READ|VM_EXEC|VM_WRITE)))) {
+ trace_spf_vma_access(_RET_IP_, vma, address);
ret = VM_FAULT_SIGSEGV;
goto out_put;
}
@@ -4384,8 +4415,10 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
pol = __get_vma_policy(vma, address);
if (!pol)
pol = get_task_policy(current);
- if (pol && pol->mode == MPOL_INTERLEAVE)
+ if (pol && pol->mode == MPOL_INTERLEAVE) {
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
goto out_put;
+ }
#endif
/*
@@ -4458,8 +4491,10 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
* We need to re-validate the VMA after checking the bounds, otherwise
* we might have a false positive on the bounds.
*/
- if (read_seqcount_retry(&vma->vm_sequence, seq))
+ if (read_seqcount_retry(&vma->vm_sequence, seq)) {
+ trace_spf_vma_changed(_RET_IP_, vma, address);
goto out_put;
+ }
mem_cgroup_oom_enable();
ret = handle_pte_fault(&vmf);
@@ -4478,6 +4513,7 @@ int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
return ret;
out_walk:
+ trace_spf_vma_notsup(_RET_IP_, vma, address);
local_irq_enable();
out_put:
put_vma(vma);
--
2.7.4
^ permalink raw reply related
* [PATCH v8 21/24] perf tools: Add support for the SPF perf event
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
Add support for the new speculative faults event.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
tools/include/uapi/linux/perf_event.h | 1 +
tools/perf/util/evsel.c | 1 +
tools/perf/util/parse-events.c | 4 ++++
tools/perf/util/parse-events.l | 1 +
tools/perf/util/python.c | 1 +
5 files changed, 8 insertions(+)
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index e0739a1aa4b2..164383273147 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -112,6 +112,7 @@ enum perf_sw_ids {
PERF_COUNT_SW_EMULATION_FAULTS = 8,
PERF_COUNT_SW_DUMMY = 9,
PERF_COUNT_SW_BPF_OUTPUT = 10,
+ PERF_COUNT_SW_SPF = 11,
PERF_COUNT_SW_MAX, /* non-ABI */
};
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 66fa45198a11..7fddb37f44ca 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -438,6 +438,7 @@ const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = {
"alignment-faults",
"emulation-faults",
"dummy",
+ "speculative-faults",
};
static const char *__perf_evsel__sw_name(u64 config)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 34589c427e52..2a8189c6d5fc 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -140,6 +140,10 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
.symbol = "bpf-output",
.alias = "",
},
+ [PERF_COUNT_SW_SPF] = {
+ .symbol = "speculative-faults",
+ .alias = "spf",
+ },
};
#define __PERF_EVENT_FIELD(config, name) \
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 655ecff636a8..5d6782426b30 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -308,6 +308,7 @@ emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EM
dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
duration_time { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); }
+speculative-faults|spf { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_SPF); }
/*
* We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately.
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index b1e999bd21ef..100507d632fa 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1142,6 +1142,7 @@ static struct {
PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
PERF_CONST(COUNT_SW_EMULATION_FAULTS),
PERF_CONST(COUNT_SW_DUMMY),
+ PERF_CONST(COUNT_SW_SPF),
PERF_CONST(SAMPLE_IP),
PERF_CONST(SAMPLE_TID),
--
2.7.4
^ permalink raw reply related
* [PATCH v8 20/24] perf: Add a speculative page fault sw event
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
Add a new software event to count succeeded speculative page faults.
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
include/uapi/linux/perf_event.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index e0739a1aa4b2..164383273147 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -112,6 +112,7 @@ enum perf_sw_ids {
PERF_COUNT_SW_EMULATION_FAULTS = 8,
PERF_COUNT_SW_DUMMY = 9,
PERF_COUNT_SW_BPF_OUTPUT = 10,
+ PERF_COUNT_SW_SPF = 11,
PERF_COUNT_SW_MAX, /* non-ABI */
};
--
2.7.4
^ permalink raw reply related
* [PATCH v8 17/24] mm: Protect mm_rb tree with a rwlock
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
This change is inspired by the Peter's proposal patch [1] which was
protecting the VMA using SRCU. Unfortunately, SRCU is not scaling well in
that particular case, and it is introducing major performance degradation
due to excessive scheduling operations.
To allow access to the mm_rb tree without grabbing the mmap_sem, this patch
is protecting it access using a rwlock. As the mm_rb tree is a O(log n)
search it is safe to protect it using such a lock. The VMA cache is not
protected by the new rwlock and it should not be used without holding the
mmap_sem.
To allow the picked VMA structure to be used once the rwlock is released, a
use count is added to the VMA structure. When the VMA is allocated it is
set to 1. Each time the VMA is picked with the rwlock held its use count
is incremented. Each time the VMA is released it is decremented. When the
use count hits zero, this means that the VMA is no more used and should be
freed.
This patch is preparing for 2 kind of VMA access :
- as usual, under the control of the mmap_sem,
- without holding the mmap_sem for the speculative page fault handler.
Access done under the control the mmap_sem doesn't require to grab the
rwlock to protect read access to the mm_rb tree, but access in write must
be done under the protection of the rwlock too. This affects inserting and
removing of elements in the RB tree.
The patch is introducing 2 new functions:
- vma_get() to find a VMA based on an address by holding the new rwlock.
- vma_put() to release the VMA when its no more used.
These services are designed to be used when access are made to the RB tree
without holding the mmap_sem.
When a VMA is removed from the RB tree, its vma->vm_rb field is cleared and
we rely on the WMB done when releasing the rwlock to serialize the write
with the RMB done in a later patch to check for the VMA's validity.
When free_vma is called, the file associated with the VMA is closed
immediately, but the policy and the file structure remained in used until
the VMA's use count reach 0, which may happens later when exiting an
in progress speculative page fault.
[1] https://patchwork.kernel.org/patch/5108281/
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
include/linux/mm_types.h | 4 ++
kernel/fork.c | 3 ++
mm/init-mm.c | 3 ++
mm/internal.h | 6 +++
mm/mmap.c | 122 ++++++++++++++++++++++++++++++++++-------------
5 files changed, 106 insertions(+), 32 deletions(-)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 34fde7111e88..28c763ea1036 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -335,6 +335,7 @@ struct vm_area_struct {
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
seqcount_t vm_sequence;
+ atomic_t vm_ref_count; /* see vma_get(), vma_put() */
#endif
} __randomize_layout;
@@ -353,6 +354,9 @@ struct kioctx_table;
struct mm_struct {
struct vm_area_struct *mmap; /* list of VMAs */
struct rb_root mm_rb;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ rwlock_t mm_rb_lock;
+#endif
u32 vmacache_seqnum; /* per-thread vmacache */
#ifdef CONFIG_MMU
unsigned long (*get_unmapped_area) (struct file *filp,
diff --git a/kernel/fork.c b/kernel/fork.c
index 505195d26744..6c4dc1aa6f17 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -887,6 +887,9 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
mm->mmap = NULL;
mm->mm_rb = RB_ROOT;
mm->vmacache_seqnum = 0;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ rwlock_init(&mm->mm_rb_lock);
+#endif
atomic_set(&mm->mm_users, 1);
atomic_set(&mm->mm_count, 1);
init_rwsem(&mm->mmap_sem);
diff --git a/mm/init-mm.c b/mm/init-mm.c
index f94d5d15ebc0..e71ac37a98c4 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -17,6 +17,9 @@
struct mm_struct init_mm = {
.mm_rb = RB_ROOT,
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ .mm_rb_lock = __RW_LOCK_UNLOCKED(init_mm.mm_rb_lock),
+#endif
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
diff --git a/mm/internal.h b/mm/internal.h
index 62d8c34e63d5..fb2667b20f0a 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -40,6 +40,12 @@ void page_writeback_init(void);
int do_swap_page(struct vm_fault *vmf);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+extern struct vm_area_struct *get_vma(struct mm_struct *mm,
+ unsigned long addr);
+extern void put_vma(struct vm_area_struct *vma);
+#endif
+
void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
unsigned long floor, unsigned long ceiling);
diff --git a/mm/mmap.c b/mm/mmap.c
index 13c799710a8a..220ba8cb65fc 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -160,6 +160,27 @@ void unlink_file_vma(struct vm_area_struct *vma)
}
}
+static void __free_vma(struct vm_area_struct *vma)
+{
+ if (vma->vm_file)
+ fput(vma->vm_file);
+ mpol_put(vma_policy(vma));
+ kmem_cache_free(vm_area_cachep, vma);
+}
+
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+void put_vma(struct vm_area_struct *vma)
+{
+ if (atomic_dec_and_test(&vma->vm_ref_count))
+ __free_vma(vma);
+}
+#else
+static inline void put_vma(struct vm_area_struct *vma)
+{
+ return __free_vma(vma);
+}
+#endif
+
/*
* Close a vm structure and free it, returning the next.
*/
@@ -170,10 +191,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
might_sleep();
if (vma->vm_ops && vma->vm_ops->close)
vma->vm_ops->close(vma);
- if (vma->vm_file)
- fput(vma->vm_file);
- mpol_put(vma_policy(vma));
- kmem_cache_free(vm_area_cachep, vma);
+ put_vma(vma);
return next;
}
@@ -393,6 +411,14 @@ static void validate_mm(struct mm_struct *mm)
#define validate_mm(mm) do { } while (0)
#endif
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+#define mm_rb_write_lock(mm) write_lock(&(mm)->mm_rb_lock)
+#define mm_rb_write_unlock(mm) write_unlock(&(mm)->mm_rb_lock)
+#else
+#define mm_rb_write_lock(mm) do { } while (0)
+#define mm_rb_write_unlock(mm) do { } while (0)
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
+
RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb,
unsigned long, rb_subtree_gap, vma_compute_subtree_gap)
@@ -411,26 +437,37 @@ static void vma_gap_update(struct vm_area_struct *vma)
}
static inline void vma_rb_insert(struct vm_area_struct *vma,
- struct rb_root *root)
+ struct mm_struct *mm)
{
+ struct rb_root *root = &mm->mm_rb;
+
/* All rb_subtree_gap values must be consistent prior to insertion */
validate_mm_rb(root, NULL);
rb_insert_augmented(&vma->vm_rb, root, &vma_gap_callbacks);
}
-static void __vma_rb_erase(struct vm_area_struct *vma, struct rb_root *root)
+static void __vma_rb_erase(struct vm_area_struct *vma, struct mm_struct *mm)
{
+ struct rb_root *root = &mm->mm_rb;
/*
* Note rb_erase_augmented is a fairly large inline function,
* so make sure we instantiate it only once with our desired
* augmented rbtree callbacks.
*/
+ mm_rb_write_lock(mm);
rb_erase_augmented(&vma->vm_rb, root, &vma_gap_callbacks);
+ mm_rb_write_unlock(mm); /* wmb */
+
+ /*
+ * Ensure the removal is complete before clearing the node.
+ * Matched by vma_has_changed()/handle_speculative_fault().
+ */
+ RB_CLEAR_NODE(&vma->vm_rb);
}
static __always_inline void vma_rb_erase_ignore(struct vm_area_struct *vma,
- struct rb_root *root,
+ struct mm_struct *mm,
struct vm_area_struct *ignore)
{
/*
@@ -438,21 +475,21 @@ static __always_inline void vma_rb_erase_ignore(struct vm_area_struct *vma,
* with the possible exception of the "next" vma being erased if
* next->vm_start was reduced.
*/
- validate_mm_rb(root, ignore);
+ validate_mm_rb(&mm->mm_rb, ignore);
- __vma_rb_erase(vma, root);
+ __vma_rb_erase(vma, mm);
}
static __always_inline void vma_rb_erase(struct vm_area_struct *vma,
- struct rb_root *root)
+ struct mm_struct *mm)
{
/*
* All rb_subtree_gap values must be consistent prior to erase,
* with the possible exception of the vma being erased.
*/
- validate_mm_rb(root, vma);
+ validate_mm_rb(&mm->mm_rb, vma);
- __vma_rb_erase(vma, root);
+ __vma_rb_erase(vma, mm);
}
/*
@@ -558,10 +595,6 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
else
mm->highest_vm_end = vm_end_gap(vma);
-#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
- seqcount_init(&vma->vm_sequence);
-#endif
-
/*
* vma->vm_prev wasn't known when we followed the rbtree to find the
* correct insertion point for that vma. As a result, we could not
@@ -571,10 +604,15 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
* immediately update the gap to the correct value. Finally we
* rebalance the rbtree after all augmented values have been set.
*/
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ atomic_set(&vma->vm_ref_count, 1);
+#endif
+ mm_rb_write_lock(mm);
rb_link_node(&vma->vm_rb, rb_parent, rb_link);
vma->rb_subtree_gap = 0;
vma_gap_update(vma);
- vma_rb_insert(vma, &mm->mm_rb);
+ vma_rb_insert(vma, mm);
+ mm_rb_write_unlock(mm);
}
static void __vma_link_file(struct vm_area_struct *vma)
@@ -650,7 +688,7 @@ static __always_inline void __vma_unlink_common(struct mm_struct *mm,
{
struct vm_area_struct *next;
- vma_rb_erase_ignore(vma, &mm->mm_rb, ignore);
+ vma_rb_erase_ignore(vma, mm, ignore);
next = vma->vm_next;
if (has_prev)
prev->vm_next = next;
@@ -923,16 +961,13 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
}
if (remove_next) {
- if (file) {
+ if (file)
uprobe_munmap(next, next->vm_start, next->vm_end);
- fput(file);
- }
if (next->anon_vma)
anon_vma_merge(vma, next);
mm->map_count--;
- mpol_put(vma_policy(next));
vm_raw_write_end(next);
- kmem_cache_free(vm_area_cachep, next);
+ put_vma(next);
/*
* In mprotect's case 6 (see comments on vma_merge),
* we must remove another next too. It would clutter
@@ -2182,15 +2217,11 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
EXPORT_SYMBOL(get_unmapped_area);
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
-struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+static struct vm_area_struct *__find_vma(struct mm_struct *mm,
+ unsigned long addr)
{
struct rb_node *rb_node;
- struct vm_area_struct *vma;
-
- /* Check the cache first. */
- vma = vmacache_find(mm, addr);
- if (likely(vma))
- return vma;
+ struct vm_area_struct *vma = NULL;
rb_node = mm->mm_rb.rb_node;
@@ -2208,13 +2239,40 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
rb_node = rb_node->rb_right;
}
+ return vma;
+}
+
+struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ /* Check the cache first. */
+ vma = vmacache_find(mm, addr);
+ if (likely(vma))
+ return vma;
+
+ vma = __find_vma(mm, addr);
if (vma)
vmacache_update(addr, vma);
return vma;
}
-
EXPORT_SYMBOL(find_vma);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+struct vm_area_struct *get_vma(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma = NULL;
+
+ read_lock(&mm->mm_rb_lock);
+ vma = __find_vma(mm, addr);
+ if (vma)
+ atomic_inc(&vma->vm_ref_count);
+ read_unlock(&mm->mm_rb_lock);
+
+ return vma;
+}
+#endif
+
/*
* Same as find_vma, but also return a pointer to the previous VMA in *pprev.
*/
@@ -2582,7 +2640,7 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
- vma_rb_erase(vma, &mm->mm_rb);
+ vma_rb_erase(vma, mm);
mm->map_count--;
tail_vma = vma;
vma = vma->vm_next;
--
2.7.4
^ permalink raw reply related
* [PATCH v8 18/24] mm: Provide speculative fault infrastructure
From: Laurent Dufour @ 2018-02-16 15:25 UTC (permalink / raw)
To: paulmck, peterz, akpm, kirill, ak, mhocko, dave, jack,
Matthew Wilcox, benh, mpe, paulus, Thomas Gleixner, Ingo Molnar,
hpa, Will Deacon, Sergey Senozhatsky, Andrea Arcangeli,
Alexei Starovoitov, kemi.wang, sergey.senozhatsky.work,
Daniel Jordan
Cc: linux-kernel, linux-mm, haren, khandual, npiggin, bsingharora,
Tim Chen, linuxppc-dev, x86
In-Reply-To: <1518794738-4186-1-git-send-email-ldufour@linux.vnet.ibm.com>
From: Peter Zijlstra <peterz@infradead.org>
Provide infrastructure to do a speculative fault (not holding
mmap_sem).
The not holding of mmap_sem means we can race against VMA
change/removal and page-table destruction. We use the SRCU VMA freeing
to keep the VMA around. We use the VMA seqcount to detect change
(including umapping / page-table deletion) and we use gup_fast() style
page-table walking to deal with page-table races.
Once we've obtained the page and are ready to update the PTE, we
validate if the state we started the fault with is still valid, if
not, we'll fail the fault with VM_FAULT_RETRY, otherwise we update the
PTE and we're done.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
[Manage the newly introduced pte_spinlock() for speculative page
fault to fail if the VMA is touched in our back]
[Rename vma_is_dead() to vma_has_changed() and declare it here]
[Fetch p4d and pud]
[Set vmd.sequence in __handle_mm_fault()]
[Abort speculative path when handle_userfault() has to be called]
[Add additional VMA's flags checks in handle_speculative_fault()]
[Clear FAULT_FLAG_ALLOW_RETRY in handle_speculative_fault()]
[Don't set vmf->pte and vmf->ptl if pte_map_lock() failed]
[Remove warning comment about waiting for !seq&1 since we don't want
to wait]
[Remove warning about no huge page support, mention it explictly]
[Don't call do_fault() in the speculative path as __do_fault() calls
vma->vm_ops->fault() which may want to release mmap_sem]
[Only vm_fault pointer argument for vma_has_changed()]
[Fix check against huge page, calling pmd_trans_huge()]
[Use READ_ONCE() when reading VMA's fields in the speculative path]
[Explicitly check for __HAVE_ARCH_PTE_SPECIAL as we can't support for
processing done in vm_normal_page()]
[Check that vma->anon_vma is already set when starting the speculative
path]
[Check for memory policy as we can't support MPOL_INTERLEAVE case due to
the processing done in mpol_misplaced()]
[Don't support VMA growing up or down]
[Move check on vm_sequence just before calling handle_pte_fault()]
[Don't build SPF services if !CONFIG_SPECULATIVE_PAGE_FAULT]
[Add mem cgroup oom check]
[Use READ_ONCE to access p*d entries]
[Replace deprecated ACCESS_ONCE() by READ_ONCE() in vma_has_changed()]
[Don't fetch pte again in handle_pte_fault() when running the speculative
path]
[Check PMD against concurrent collapsing operation]
[Try spin lock the pte during the speculative path to avoid deadlock with
other CPU's invalidating the TLB and requiring this CPU to catch the
inter processor's interrupt]
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
include/linux/hugetlb_inline.h | 2 +-
include/linux/mm.h | 8 +
include/linux/pagemap.h | 4 +-
mm/internal.h | 16 +-
mm/memory.c | 334 ++++++++++++++++++++++++++++++++++++++++-
5 files changed, 356 insertions(+), 8 deletions(-)
diff --git a/include/linux/hugetlb_inline.h b/include/linux/hugetlb_inline.h
index 0660a03d37d9..9e25283d6fc9 100644
--- a/include/linux/hugetlb_inline.h
+++ b/include/linux/hugetlb_inline.h
@@ -8,7 +8,7 @@
static inline bool is_vm_hugetlb_page(struct vm_area_struct *vma)
{
- return !!(vma->vm_flags & VM_HUGETLB);
+ return !!(READ_ONCE(vma->vm_flags) & VM_HUGETLB);
}
#else
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d5f17fcd2c32..c383a4e2ceb3 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -331,6 +331,10 @@ struct vm_fault {
gfp_t gfp_mask; /* gfp mask to be used for allocations */
pgoff_t pgoff; /* Logical page offset based on vma */
unsigned long address; /* Faulting virtual address */
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ unsigned int sequence;
+ pmd_t orig_pmd; /* value of PMD at the time of fault */
+#endif
pmd_t *pmd; /* Pointer to pmd entry matching
* the 'address' */
pud_t *pud; /* Pointer to pud entry matching
@@ -1349,6 +1353,10 @@ int invalidate_inode_page(struct page *page);
#ifdef CONFIG_MMU
extern int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
unsigned int flags);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+extern int handle_speculative_fault(struct mm_struct *mm,
+ unsigned long address, unsigned int flags);
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
unsigned long address, unsigned int fault_flags,
bool *unlocked);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 34ce3ebf97d5..70e4d2688e7b 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -456,8 +456,8 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
pgoff_t pgoff;
if (unlikely(is_vm_hugetlb_page(vma)))
return linear_hugepage_index(vma, address);
- pgoff = (address - vma->vm_start) >> PAGE_SHIFT;
- pgoff += vma->vm_pgoff;
+ pgoff = (address - READ_ONCE(vma->vm_start)) >> PAGE_SHIFT;
+ pgoff += READ_ONCE(vma->vm_pgoff);
return pgoff;
}
diff --git a/mm/internal.h b/mm/internal.h
index fb2667b20f0a..10b188c87fa4 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -44,7 +44,21 @@ int do_swap_page(struct vm_fault *vmf);
extern struct vm_area_struct *get_vma(struct mm_struct *mm,
unsigned long addr);
extern void put_vma(struct vm_area_struct *vma);
-#endif
+
+static inline bool vma_has_changed(struct vm_fault *vmf)
+{
+ int ret = RB_EMPTY_NODE(&vmf->vma->vm_rb);
+ unsigned int seq = READ_ONCE(vmf->vma->vm_sequence.sequence);
+
+ /*
+ * Matches both the wmb in write_seqlock_{begin,end}() and
+ * the wmb in vma_rb_erase().
+ */
+ smp_rmb();
+
+ return ret || seq != vmf->sequence;
+}
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
unsigned long floor, unsigned long ceiling);
diff --git a/mm/memory.c b/mm/memory.c
index 67de327c7262..efc32173264e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -769,7 +769,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
if (page)
dump_page(page, "bad pte");
pr_alert("addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
- (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
+ (void *)addr, READ_ONCE(vma->vm_flags), vma->anon_vma,
+ mapping, index);
pr_alert("file:%pD fault:%pf mmap:%pf readpage:%pf\n",
vma->vm_file,
vma->vm_ops ? vma->vm_ops->fault : NULL,
@@ -2295,19 +2296,119 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
}
EXPORT_SYMBOL_GPL(apply_to_page_range);
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
static bool pte_spinlock(struct vm_fault *vmf)
{
+ bool ret = false;
+ pmd_t pmdval;
+
+ /* Check if vma is still valid */
+ if (!(vmf->flags & FAULT_FLAG_SPECULATIVE)) {
+ vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
+ spin_lock(vmf->ptl);
+ return true;
+ }
+
+ local_irq_disable();
+ if (vma_has_changed(vmf))
+ goto out;
+
+ /*
+ * We check if the pmd value is still the same to ensure that there
+ * is a huge collapse operation in progress in our back.
+ */
+ pmdval = READ_ONCE(*vmf->pmd);
+ if (!pmd_same(pmdval, vmf->orig_pmd))
+ goto out;
+
+ vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
+ if (unlikely(!spin_trylock(vmf->ptl)))
+ goto out;
+
+ if (vma_has_changed(vmf)) {
+ spin_unlock(vmf->ptl);
+ goto out;
+ }
+
+ ret = true;
+out:
+ local_irq_enable();
+ return ret;
+}
+
+static bool pte_map_lock(struct vm_fault *vmf)
+{
+ bool ret = false;
+ pte_t *pte;
+ pmd_t pmdval;
+ spinlock_t *ptl;
+
+ if (!(vmf->flags & FAULT_FLAG_SPECULATIVE)) {
+ vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+ return true;
+ }
+
+ /*
+ * The first vma_has_changed() guarantees the page-tables are still
+ * valid, having IRQs disabled ensures they stay around, hence the
+ * second vma_has_changed() to make sure they are still valid once
+ * we've got the lock. After that a concurrent zap_pte_range() will
+ * block on the PTL and thus we're safe.
+ */
+ local_irq_disable();
+ if (vma_has_changed(vmf))
+ goto out;
+
+ /*
+ * We check if the pmd value is still the same to ensure that there
+ * is a huge collapse operation in progress in our back.
+ */
+ pmdval = READ_ONCE(*vmf->pmd);
+ if (!pmd_same(pmdval, vmf->orig_pmd))
+ goto out;
+
+ /*
+ * Same as pte_offset_map_lock() except that we call
+ * spin_trylock() in place of spin_lock() to avoid race with
+ * unmap path which may have the lock and wait for this CPU
+ * to invalidate TLB but this CPU has irq disabled.
+ * Since we are in a speculative patch, accept it could fail
+ */
+ ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
+ pte = pte_offset_map(vmf->pmd, vmf->address);
+ if (unlikely(!spin_trylock(ptl))) {
+ pte_unmap(pte);
+ goto out;
+ }
+
+ if (vma_has_changed(vmf)) {
+ pte_unmap_unlock(pte, ptl);
+ goto out;
+ }
+
+ vmf->pte = pte;
+ vmf->ptl = ptl;
+ ret = true;
+out:
+ local_irq_enable();
+ return ret;
+}
+#else
+static inline bool pte_spinlock(struct vm_fault *vmf)
+{
vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
spin_lock(vmf->ptl);
return true;
}
-static bool pte_map_lock(struct vm_fault *vmf)
+static inline bool pte_map_lock(struct vm_fault *vmf)
{
vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd,
vmf->address, &vmf->ptl);
return true;
}
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
/*
* handle_pte_fault chooses page fault handler according to an entry which was
@@ -3207,6 +3308,14 @@ static int do_anonymous_page(struct vm_fault *vmf)
ret = check_stable_address_space(vma->vm_mm);
if (ret)
goto unlock;
+ /*
+ * Don't call the userfaultfd during the speculative path.
+ * We already checked for the VMA to not be managed through
+ * userfaultfd, but it may be set in our back once we have lock
+ * the pte. In such a case we can ignore it this time.
+ */
+ if (vmf->flags & FAULT_FLAG_SPECULATIVE)
+ goto setpte;
/* Deliver the page fault to userland, check inside PT lock */
if (userfaultfd_missing(vma)) {
pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -3249,7 +3358,7 @@ static int do_anonymous_page(struct vm_fault *vmf)
goto release;
/* Deliver the page fault to userland, check inside PT lock */
- if (userfaultfd_missing(vma)) {
+ if (!(vmf->flags & FAULT_FLAG_SPECULATIVE) && userfaultfd_missing(vma)) {
pte_unmap_unlock(vmf->pte, vmf->ptl);
mem_cgroup_cancel_charge(page, memcg, false);
put_page(page);
@@ -3992,13 +4101,22 @@ static int handle_pte_fault(struct vm_fault *vmf)
if (unlikely(pmd_none(*vmf->pmd))) {
/*
+ * In the case of the speculative page fault handler we abort
+ * the speculative path immediately as the pmd is probably
+ * in the way to be converted in a huge one. We will try
+ * again holding the mmap_sem (which implies that the collapse
+ * operation is done).
+ */
+ if (vmf->flags & FAULT_FLAG_SPECULATIVE)
+ return VM_FAULT_RETRY;
+ /*
* Leave __pte_alloc() until later: because vm_ops->fault may
* want to allocate huge page, and if we expose page table
* for an instant, it will be difficult to retract from
* concurrent faults and from rmap lookups.
*/
vmf->pte = NULL;
- } else {
+ } else if (!(vmf->flags & FAULT_FLAG_SPECULATIVE)) {
/* See comment in pte_alloc_one_map() */
if (pmd_devmap_trans_unstable(vmf->pmd))
return 0;
@@ -4007,6 +4125,9 @@ static int handle_pte_fault(struct vm_fault *vmf)
* pmd from under us anymore at this point because we hold the
* mmap_sem read mode and khugepaged takes it in write mode.
* So now it's safe to run pte_offset_map().
+ * This is not applicable to the speculative page fault handler
+ * but in that case, the pte is fetched earlier in
+ * handle_speculative_fault().
*/
vmf->pte = pte_offset_map(vmf->pmd, vmf->address);
vmf->orig_pte = *vmf->pte;
@@ -4029,6 +4150,8 @@ static int handle_pte_fault(struct vm_fault *vmf)
if (!vmf->pte) {
if (vma_is_anonymous(vmf->vma))
return do_anonymous_page(vmf);
+ else if (vmf->flags & FAULT_FLAG_SPECULATIVE)
+ return VM_FAULT_RETRY;
else
return do_fault(vmf);
}
@@ -4126,6 +4249,9 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
vmf.pmd = pmd_alloc(mm, vmf.pud, address);
if (!vmf.pmd)
return VM_FAULT_OOM;
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+ vmf.sequence = raw_read_seqcount(&vma->vm_sequence);
+#endif
if (pmd_none(*vmf.pmd) && transparent_hugepage_enabled(vma)) {
ret = create_huge_pmd(&vmf);
if (!(ret & VM_FAULT_FALLBACK))
@@ -4159,6 +4285,206 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
return handle_pte_fault(&vmf);
}
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+
+#ifndef __HAVE_ARCH_PTE_SPECIAL
+/* This is required by vm_normal_page() */
+#error "Speculative page fault handler requires __HAVE_ARCH_PTE_SPECIAL"
+#endif
+
+/*
+ * vm_normal_page() adds some processing which should be done while
+ * hodling the mmap_sem.
+ */
+int handle_speculative_fault(struct mm_struct *mm, unsigned long address,
+ unsigned int flags)
+{
+ struct vm_fault vmf = {
+ .address = address,
+ };
+ pgd_t *pgd, pgdval;
+ p4d_t *p4d, p4dval;
+ pud_t pudval;
+ int seq, ret = VM_FAULT_RETRY;
+ struct vm_area_struct *vma;
+#ifdef CONFIG_NUMA
+ struct mempolicy *pol;
+#endif
+
+ /* Clear flags that may lead to release the mmap_sem to retry */
+ flags &= ~(FAULT_FLAG_ALLOW_RETRY|FAULT_FLAG_KILLABLE);
+ flags |= FAULT_FLAG_SPECULATIVE;
+
+ vma = get_vma(mm, address);
+ if (!vma)
+ return ret;
+
+ seq = raw_read_seqcount(&vma->vm_sequence); /* rmb <-> seqlock,vma_rb_erase() */
+ if (seq & 1)
+ goto out_put;
+
+ /*
+ * Can't call vm_ops service has we don't know what they would do
+ * with the VMA.
+ * This include huge page from hugetlbfs.
+ */
+ if (vma->vm_ops)
+ goto out_put;
+
+ /*
+ * __anon_vma_prepare() requires the mmap_sem to be held
+ * because vm_next and vm_prev must be safe. This can't be guaranteed
+ * in the speculative path.
+ */
+ if (unlikely(!vma->anon_vma))
+ goto out_put;
+
+ vmf.vma_flags = READ_ONCE(vma->vm_flags);
+ vmf.vma_page_prot = READ_ONCE(vma->vm_page_prot);
+
+ /* Can't call userland page fault handler in the speculative path */
+ if (unlikely(vmf.vma_flags & VM_UFFD_MISSING))
+ goto out_put;
+
+ if (vmf.vma_flags & VM_GROWSDOWN || vmf.vma_flags & VM_GROWSUP)
+ /*
+ * This could be detected by the check address against VMA's
+ * boundaries but we want to trace it as not supported instead
+ * of changed.
+ */
+ goto out_put;
+
+ if (address < READ_ONCE(vma->vm_start)
+ || READ_ONCE(vma->vm_end) <= address)
+ goto out_put;
+
+ if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
+ flags & FAULT_FLAG_INSTRUCTION,
+ flags & FAULT_FLAG_REMOTE)) {
+ ret = VM_FAULT_SIGSEGV;
+ goto out_put;
+ }
+
+ /* This is one is required to check that the VMA has write access set */
+ if (flags & FAULT_FLAG_WRITE) {
+ if (unlikely(!(vmf.vma_flags & VM_WRITE))) {
+ ret = VM_FAULT_SIGSEGV;
+ goto out_put;
+ }
+ } else if (unlikely(!(vmf.vma_flags & (VM_READ|VM_EXEC|VM_WRITE)))) {
+ ret = VM_FAULT_SIGSEGV;
+ goto out_put;
+ }
+
+#ifdef CONFIG_NUMA
+ /*
+ * MPOL_INTERLEAVE implies additional check in mpol_misplaced() which
+ * are not compatible with the speculative page fault processing.
+ */
+ pol = __get_vma_policy(vma, address);
+ if (!pol)
+ pol = get_task_policy(current);
+ if (pol && pol->mode == MPOL_INTERLEAVE)
+ goto out_put;
+#endif
+
+ /*
+ * Do a speculative lookup of the PTE entry.
+ */
+ local_irq_disable();
+ pgd = pgd_offset(mm, address);
+ pgdval = READ_ONCE(*pgd);
+ if (pgd_none(pgdval) || unlikely(pgd_bad(pgdval)))
+ goto out_walk;
+
+ p4d = p4d_offset(pgd, address);
+ p4dval = READ_ONCE(*p4d);
+ if (p4d_none(p4dval) || unlikely(p4d_bad(p4dval)))
+ goto out_walk;
+
+ vmf.pud = pud_offset(p4d, address);
+ pudval = READ_ONCE(*vmf.pud);
+ if (pud_none(pudval) || unlikely(pud_bad(pudval)))
+ goto out_walk;
+
+ /* Huge pages at PUD level are not supported. */
+ if (unlikely(pud_trans_huge(pudval)))
+ goto out_walk;
+
+ vmf.pmd = pmd_offset(vmf.pud, address);
+ vmf.orig_pmd = READ_ONCE(*vmf.pmd);
+ /*
+ * pmd_none could mean that a hugepage collapse is in progress
+ * in our back as collapse_huge_page() mark it before
+ * invalidating the pte (which is done once the IPI is catched
+ * by all CPU and we have interrupt disabled).
+ * For this reason we cannot handle THP in a speculative way since we
+ * can't safely indentify an in progress collapse operation done in our
+ * back on that PMD.
+ * Regarding the order of the following checks, see comment in
+ * pmd_devmap_trans_unstable()
+ */
+ if (unlikely(pmd_devmap(vmf.orig_pmd) ||
+ pmd_none(vmf.orig_pmd) || pmd_trans_huge(vmf.orig_pmd) ||
+ is_swap_pmd(vmf.orig_pmd)))
+ goto out_walk;
+
+ /*
+ * The above does not allocate/instantiate page-tables because doing so
+ * would lead to the possibility of instantiating page-tables after
+ * free_pgtables() -- and consequently leaking them.
+ *
+ * The result is that we take at least one !speculative fault per PMD
+ * in order to instantiate it.
+ */
+
+ vmf.pte = pte_offset_map(vmf.pmd, address);
+ vmf.orig_pte = READ_ONCE(*vmf.pte);
+ barrier(); /* See comment in handle_pte_fault() */
+ if (pte_none(vmf.orig_pte)) {
+ pte_unmap(vmf.pte);
+ vmf.pte = NULL;
+ }
+
+ vmf.vma = vma;
+ vmf.pgoff = linear_page_index(vma, address);
+ vmf.gfp_mask = __get_fault_gfp_mask(vma);
+ vmf.sequence = seq;
+ vmf.flags = flags;
+
+ local_irq_enable();
+
+ /*
+ * We need to re-validate the VMA after checking the bounds, otherwise
+ * we might have a false positive on the bounds.
+ */
+ if (read_seqcount_retry(&vma->vm_sequence, seq))
+ goto out_put;
+
+ mem_cgroup_oom_enable();
+ ret = handle_pte_fault(&vmf);
+ mem_cgroup_oom_disable();
+
+ put_vma(vma);
+
+ /*
+ * The task may have entered a memcg OOM situation but
+ * if the allocation error was handled gracefully (no
+ * VM_FAULT_OOM), there is no need to kill anything.
+ * Just clean up the OOM state peacefully.
+ */
+ if (task_in_memcg_oom(current) && !(ret & VM_FAULT_OOM))
+ mem_cgroup_oom_synchronize(false);
+ return ret;
+
+out_walk:
+ local_irq_enable();
+out_put:
+ put_vma(vma);
+ return ret;
+}
+#endif /* CONFIG_SPECULATIVE_PAGE_FAULT */
+
/*
* By the time we get here, we already hold the mm semaphore
*
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox