Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:Update
systemtap-docs
systemtap-get_user_pages-4.9-kernel.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File systemtap-get_user_pages-4.9-kernel.patch of Package systemtap-docs
From: David Smith <dsmith@redhat.com> Date: Fri Dec 9 11:41:35 2016 -0600 Subject: Fix BZ1386120 by updating systemtap to handle the 4.9 kernel Git-commit: 00960517fb4a4d8388854b470da30e0c886b0e89 References: bsc#1031409, bsc#1125906 Signed-off-by: Tony Jones <tonyj@suse.de> Fix BZ1386120 by updating systemtap to handle the 4.9 kernel. * runtime/linux/access_process_vm.h (__access_process_vm_): Use STAPCONF_GET_USER_PAGES_REMOTE_FLAGS to handle get_user_pages_remote() kernel function API change. * runtime/transport/procfs.c (_stp_proc_read): Use _stp_get_rchan_subbuf() macro to handle kernel relayfs rchan->buf changes. * runtime/transport/relay_v2.c (__stp_relay_wakeup_timer): Ditto. (_stp_data_write_reserve): Ditto. * runtime/transport/symbols.c (_stp_module_panic_notifier): Ditto. * buildrun.cxx (compile_pass): Add autoconf-style tests. * runtime/linux/autoconf-get_user_pages_remote-flags.c: New file. * runtime/linux/autoconf-relay_buf-per_cpu_ptr.c: New file. * runtime/transport/relay_compat.h: New file. diff --git a/buildrun.cxx b/buildrun.cxx index 7c68ba03e..f5019b925 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -393,6 +393,7 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL); output_autoconf(s, o, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL); output_autoconf(s, o, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL); + output_autoconf(s, o, "autoconf-relay_buf-per_cpu_ptr.c", "STAPCONF_RELAY_BUF_PER_CPU_PTR", NULL); output_autoconf(s, o, "autoconf-fs_supers-hlist.c", "STAPCONF_FS_SUPERS_HLIST", NULL); output_autoconf(s, o, "autoconf-compat_sigaction.c", "STAPCONF_COMPAT_SIGACTION", NULL); output_autoconf(s, o, "autoconf-netfilter.c", "STAPCONF_NETFILTER_V313", NULL); @@ -447,6 +448,8 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-mod_kallsyms.c", "STAPCONF_MOD_KALLSYMS", NULL); output_exportconf(s, o, "get_user_pages_remote", "STAPCONF_GET_USER_PAGES_REMOTE"); + output_autoconf(s, o, "autoconf-get_user_pages_remote-flags.c", + "STAPCONF_GET_USER_PAGES_REMOTE_FLAGS", NULL); o << module_cflags << " += -include $(STAPCONF_HEADER)" << endl; diff --git a/runtime/linux/access_process_vm.h b/runtime/linux/access_process_vm.h index 214d4e254..d9400d723 100644 --- a/runtime/linux/access_process_vm.h +++ b/runtime/linux/access_process_vm.h @@ -33,7 +33,14 @@ __access_process_vm_ (struct task_struct *tsk, unsigned long addr, void *buf, void *maddr; #ifdef STAPCONF_GET_USER_PAGES_REMOTE +#ifdef STAPCONF_GET_USER_PAGES_REMOTE_FLAGS + unsigned int flags = FOLL_FORCE; + if (write) + flags |= FOLL_WRITE; + ret = get_user_pages_remote (tsk, mm, addr, 1, flags, &page, &vma); +#else /* !STAPCONF_GET_USER_PAGES_REMOTE_FLAGS */ ret = get_user_pages_remote (tsk, mm, addr, 1, write, 1, &page, &vma); +#endif /* !STAPCONF_GET_USER_PAGES_REMOTE_FLAGS */ #else ret = get_user_pages (tsk, mm, addr, 1, write, 1, &page, &vma); #endif diff --git a/runtime/linux/autoconf-get_user_pages_remote-flags.c b/runtime/linux/autoconf-get_user_pages_remote-flags.c new file mode 100644 index 000000000..1313e8957 --- /dev/null +++ b/runtime/linux/autoconf-get_user_pages_remote-flags.c @@ -0,0 +1,42 @@ +#ifdef STAPCONF_GET_USER_PAGES_REMOTE +#include <linux/mm.h> + +// +// The following kernel commit changed the get_user_pages_remote() +// function signature: +// +// commit 9beae1ea89305a9667ceaab6d0bf46a045ad71e7 +// Author: Lorenzo Stoakes <lstoakes@gmail.com> +// Date: Thu Oct 13 01:20:17 2016 +0100 +// +// mm: replace get_user_pages_remote() write/force parameters with gup_flags +// +// This removes the 'write' and 'force' from get_user_pages_remote() and +// replaces them with 'gup_flags' to make the use of FOLL_FORCE explicit in +// callers as use of this flag can result in surprising behaviour (and +// hence bugs) within the mm subsystem. +// +// This changed the function signature from: +// +// long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, +// unsigned long start, unsigned long nr_pages, +// int write, int force, struct page **pages, +// struct vm_area_struct **vmas); +// +// to: +// +// long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, +// unsigned long start, unsigned long nr_pages, +// unsigned int gup_flags, struct page **pages, +// struct vm_area_struct **vmas); +// + +long gupr_wrapper(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, + unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas) +{ + return get_user_pages_remote(tsk, mm, start, nr_pages, gup_flags, + pages, vmas); +} +#endif diff --git a/runtime/linux/autoconf-relay_buf-per_cpu_ptr.c b/runtime/linux/autoconf-relay_buf-per_cpu_ptr.c new file mode 100644 index 000000000..d2af8d32d --- /dev/null +++ b/runtime/linux/autoconf-relay_buf-per_cpu_ptr.c @@ -0,0 +1,27 @@ +// +// The following kernel commit: +// +// commit 017c59c042d01fc84cae7a8ea475861e702c77ab +// Author: Akash Goel <akash.goel@intel.com> +// Date: Fri Sep 2 21:47:38 2016 +0200 +// +// relay: Use per CPU constructs for the relay channel buffer pointers +// +// relay essentially needs to maintain a per CPU array of channel buffer +// pointers but it manually creates that array. Instead its better to use +// the per CPU constructs, provided by the kernel, to allocate & access the +// array of pointer to channel buffers. +// +// changed the way the 'rchan->buf' field works. It just to be a +// regular array, and is now a per_cpu_ptr-style array. +// +// If we can call per_cpu_ptr() on rchan->buf, we'll assume that we've +// got the new style relay channel buffer pointers. + +#include <linux/relay.h> +#include <linux/percpu.h> + +struct rchan_buf *relay_buf_test(struct rchan *chan, unsigned int cpu) +{ + return *per_cpu_ptr(chan->buf, cpu); +} diff --git a/runtime/transport/procfs.c b/runtime/transport/procfs.c index 05d824ec8..857f713e1 100644 --- a/runtime/transport/procfs.c +++ b/runtime/transport/procfs.c @@ -10,6 +10,7 @@ */ #include "../procfs.c" // for _stp_mkdir_proc_module() +#include "relay_compat.h" #define STP_DEFAULT_BUFFERS 256 @@ -19,6 +20,7 @@ static ssize_t _stp_proc_read(struct file *file, char __user *buf, size_t count, { int num; struct _stp_buf_info out; + struct rchan_buf *sub_buf; int cpu = *(int *)(PDE(file->f_dentry->d_inode)->data); @@ -26,8 +28,9 @@ static ssize_t _stp_proc_read(struct file *file, char __user *buf, size_t count, return -EINVAL; out.cpu = cpu; - out.produced = atomic_read(&_stp_relay_data.rchan->buf[cpu]->subbufs_produced); - out.consumed = atomic_read(&_stp_relay_data.rchan->buf[cpu]->subbufs_consumed); + sub_buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, cpu); + out.produced = atomic_read(&sub_buf->subbufs_produced); + out.consumed = atomic_read(&sub_buf->subbufs_consumed); out.flushing = _stp_relay_data.flushing; num = sizeof(out); diff --git a/runtime/transport/relay_compat.h b/runtime/transport/relay_compat.h new file mode 100644 index 000000000..02b822861 --- /dev/null +++ b/runtime/transport/relay_compat.h @@ -0,0 +1,25 @@ +/* -*- linux-c -*- */ +#ifndef _TRANSPORT_RELAY_COMPAT_H_ +#define _TRANSPORT_RELAY_COMPAT_H_ + +#if defined (CONFIG_RELAYFS_FS) || defined (CONFIG_RELAYFS_FS_MODULE) +# include <linux/relayfs_fs.h> +#elif defined (CONFIG_RELAY) +# include <linux/relay.h> +#endif + +#ifdef STAPCONF_RELAY_BUF_PER_CPU_PTR + +#include <linux/percpu.h> + +#define _stp_get_rchan_subbuf(rchan_buf, cpu) \ + (*per_cpu_ptr((rchan_buf), (cpu))) + +#else + +#define _stp_get_rchan_subbuf(rchan_buf, cpu) \ + ((rchan_buf)[(cpu)]) + +#endif + +#endif /* _TRANSPORT_RELAY_COMPAT_H_ */ diff --git a/runtime/transport/relay_v2.c b/runtime/transport/relay_v2.c index 18fca8bd3..ccf4dc80d 100644 --- a/runtime/transport/relay_v2.c +++ b/runtime/transport/relay_v2.c @@ -32,6 +32,7 @@ #include <linux/relay.h> #include <linux/timer.h> #include "../uidgid_compatibility.h" +#include "relay_compat.h" #ifndef STP_RELAY_TIMER_INTERVAL /* Wakeup timer interval in jiffies (default 10 ms) */ @@ -126,12 +127,18 @@ static void __stp_relay_wakeup_timer(unsigned long val) #endif if (atomic_read(&_stp_relay_data.wakeup)) { + struct rchan_buf *buf; + atomic_set(&_stp_relay_data.wakeup, 0); #ifdef STP_BULKMODE - for_each_possible_cpu(i) - __stp_relay_wakeup_readers(_stp_relay_data.rchan->buf[i]); + for_each_possible_cpu(i) { + buf = _stp_get_rchan_subbuf(_stp->relay_data.rchan->buf, + i); + __stp_relay_wakeup_readers(buf); + } #else - __stp_relay_wakeup_readers(_stp_relay_data.rchan->buf[0]); + buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, 0); + __stp_relay_wakeup_readers(buf); #endif } @@ -397,7 +404,8 @@ _stp_data_write_reserve(size_t size_request, void **entry) if (entry == NULL) return -EINVAL; - buf = _stp_relay_data.rchan->buf[smp_processor_id()]; + buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, + smp_processor_id()); if (unlikely(buf->offset + size_request > buf->chan->subbuf_size)) { size_request = __stp_relay_switch_subbuf(buf, size_request); if (!size_request) diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 98b023938..692a6f3f7 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -12,6 +12,7 @@ #ifndef _STP_SYMBOLS_C_ #define _STP_SYMBOLS_C_ #include "../sym.h" +#include "relay_compat.h" #ifndef KERN_CONT #define KERN_CONT "" @@ -327,7 +328,7 @@ static int _stp_module_panic_notifier (struct notifier_block *nb, unsigned long int printed; int first_iteration; - sub_buf = _stp_relay_data.rchan->buf[i]; + sub_buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, i); /* Set our pointer to the beginning of the channel buffer */ subbuf_start = (char *)sub_buf->start;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor