diff --git a/.bcc.metadata b/.bcc.metadata
new file mode 100644
index 0000000..0e97130
--- /dev/null
+++ b/.bcc.metadata
@@ -0,0 +1 @@
+70e35f9ad5989dfeab4c0e87b98602e78493a730 SOURCES/bcc-0.10.0.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4f367d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/bcc-0.10.0.tar.gz
diff --git a/SOURCES/Fix-tools-for-RHEL-7.patch b/SOURCES/Fix-tools-for-RHEL-7.patch
new file mode 100644
index 0000000..f6c8362
--- /dev/null
+++ b/SOURCES/Fix-tools-for-RHEL-7.patch
@@ -0,0 +1,594 @@
+From 5848b9fe9ad49151492cb2652a06921fa4b49031 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Thu, 16 Aug 2018 14:58:56 +0200
+Subject: [PATCH] Fix tools for RHEL 7
+
+There some differences on RHEL 7 that make some tools fail. This patch
+fixes the following:
+ - missing /sys/kernel/debug/kprobes/blacklist file
+ - missing __vfs_read() function
+ - aio_read/write methods replaced by read/write_iter in file_operations
+ - changes in mnt_namespace structure
+ - change in finish_task_switch() argument list
+ - changes in sock_common struct
+ - missing TCP_NEW_SYN_RECV TCP state
+ - mm_page_alloc tracepoint returns page struct instead of PFN
+ - iocb argument removed from tcp_sendmsg()
+---
+ src/python/bcc/__init__.py |  7 +++++--
+ tools/btrfsdist.py         | 13 +++++++------
+ tools/btrfsslower.py       | 13 +++++++------
+ tools/cpudist.py           |  4 +++-
+ tools/ext4dist.py          | 11 ++++++-----
+ tools/ext4slower.py        | 13 +++++++------
+ tools/fileslower.py        | 13 +++++++++----
+ tools/memleak.py           | 12 ++++++++++--
+ tools/mountsnoop.py        |  9 ++++-----
+ tools/nfsslower.py         |  1 +
+ tools/offcputime.py        |  4 +++-
+ tools/offwaketime.py       |  4 +++-
+ tools/oomkill.py           |  8 ++++----
+ tools/runqlat.py           |  2 +-
+ tools/runqslower.py        |  2 +-
+ tools/solisten.py          |  2 +-
+ tools/tcpsubnet.py         |  4 ++--
+ tools/tcptracer.py         |  9 ++++-----
+ tools/xfsdist.py           |  8 ++++----
+ tools/xfsslower.py         | 11 ++++++-----
+ 20 files changed, 88 insertions(+), 62 deletions(-)
+
+diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py
+index bff5f282..19933cf7 100644
+--- a/src/python/bcc/__init__.py
++++ b/src/python/bcc/__init__.py
+@@ -525,8 +525,11 @@ DEBUG_BTF = 0x20
+ 
+     @staticmethod
+     def get_kprobe_functions(event_re):
+-        with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
+-            blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
++        try:
++            with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
++                blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
++        except:
++            blacklist = set()
+         fns = []
+ 
+         in_init_section = 0
+diff --git a/tools/btrfsdist.py b/tools/btrfsdist.py
+index 4659ab46..3326b67a 100755
+--- a/tools/btrfsdist.py
++++ b/tools/btrfsdist.py
+@@ -60,6 +60,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ 
+ #define OP_NAME_LEN 8
+@@ -81,7 +82,7 @@ int trace_entry(struct pt_regs *ctx)
+     return 0;
+ }
+ 
+-// The current btrfs (Linux 4.5) uses generic_file_read_iter() instead of it's
++// btrfs uses generic_file_aio_read() instead of it's
+ // own read function. So we need to trace that and then filter on btrfs, which
+ // I do by checking file->f_op.
+ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+@@ -193,13 +194,13 @@ bpf_text = bpf_text.replace('FACTOR', str(factor))
+ # load BPF program
+ b = BPF(text=bpf_text)
+ 
+-# Common file functions. See earlier comment about generic_file_read_iter().
+-b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="btrfs_file_write_iter", fn_name="trace_entry")
++# Common file functions. See earlier comment about generic_file_aio_read().
++b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="btrfs_file_aio_write", fn_name="trace_entry")
+ b.attach_kprobe(event="generic_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="btrfs_sync_file", fn_name="trace_entry")
+-b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="btrfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="btrfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="generic_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="btrfs_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/btrfsslower.py b/tools/btrfsslower.py
+index bacbc06a..b650cea0 100755
+--- a/tools/btrfsslower.py
++++ b/tools/btrfsslower.py
+@@ -62,6 +62,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -96,7 +97,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// The current btrfs (Linux 4.5) uses generic_file_read_iter() instead of it's
++// btrfs uses generic_file_aio_read() instead of it's
+ // own read function. So we need to trace that and then filter on btrfs, which
+ // I do by checking file->f_op.
+ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+@@ -123,7 +124,7 @@ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+     return 0;
+ }
+ 
+-// btrfs_file_write_iter():
++// btrfs_file_aio_write():
+ int trace_write_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -313,12 +314,12 @@ int trace_fsync_return(struct pt_regs *ctx)
+ b = BPF(text=bpf_text)
+ 
+ # Common file functions. See earlier comment about generic_*().
+-b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="btrfs_file_write_iter", fn_name="trace_write_entry")
++b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="btrfs_file_aio_write", fn_name="trace_write_entry")
+ b.attach_kprobe(event="generic_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="btrfs_sync_file", fn_name="trace_fsync_entry")
+-b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="btrfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="btrfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="generic_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="btrfs_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/cpudist.py b/tools/cpudist.py
+index 4d7c9eb4..ddb675e2 100755
+--- a/tools/cpudist.py
++++ b/tools/cpudist.py
+@@ -94,7 +94,9 @@ static inline void update_hist(u32 tgid, u32 pid, u64 ts)
+     STORE
+ }
+ 
+-int sched_switch(struct pt_regs *ctx, struct task_struct *prev)
++struct rq;
++
++int sched_switch(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u64 ts = bpf_ktime_get_ns();
+     u64 pid_tgid = bpf_get_current_pid_tgid();
+diff --git a/tools/ext4dist.py b/tools/ext4dist.py
+index 384a4c14..559e4a5f 100755
+--- a/tools/ext4dist.py
++++ b/tools/ext4dist.py
+@@ -60,6 +60,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ 
+ #define OP_NAME_LEN 8
+@@ -136,18 +137,18 @@ int trace_fsync_return(struct pt_regs *ctx)
+ """
+ 
+ # Starting from Linux 4.10 ext4_file_operations.read_iter has been changed from
+-# using generic_file_read_iter() to its own ext4_file_read_iter().
++# using generic_file_aio_read() to its own ext4_file_read_iter().
+ #
+ # To detect the proper function to trace check if ext4_file_read_iter() is
+ # defined in /proc/kallsyms, if it's defined attach to that function, otherwise
+-# use generic_file_read_iter() and inside the trace hook filter on ext4 read
++# use generic_file_aio_read() and inside the trace hook filter on ext4 read
+ # events (checking if file->f_op == ext4_file_operations).
+ if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+     ext4_read_fn = 'ext4_file_read_iter'
+     ext4_trace_read_fn = 'trace_entry'
+     ext4_trace_read_code = ''
+ else:
+-    ext4_read_fn = 'generic_file_read_iter'
++    ext4_read_fn = 'generic_file_aio_read'
+     ext4_trace_read_fn = 'trace_read_entry'
+     ext4_file_ops_addr = ''
+     with open(kallsyms) as syms:
+@@ -194,11 +195,11 @@ bpf_text = bpf_text.replace('FACTOR', str(factor))
+ b = BPF(text=bpf_text)
+ 
+ b.attach_kprobe(event=ext4_read_fn, fn_name=ext4_trace_read_fn)
+-b.attach_kprobe(event="ext4_file_write_iter", fn_name="trace_entry")
++b.attach_kprobe(event="ext4_file_write", fn_name="trace_entry")
+ b.attach_kprobe(event="ext4_file_open", fn_name="trace_entry")
+ b.attach_kprobe(event="ext4_sync_file", fn_name="trace_entry")
+ b.attach_kretprobe(event=ext4_read_fn, fn_name='trace_read_return')
+-b.attach_kretprobe(event="ext4_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="ext4_file_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="ext4_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="ext4_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/ext4slower.py b/tools/ext4slower.py
+index 0524f22e..d5fbb661 100755
+--- a/tools/ext4slower.py
++++ b/tools/ext4slower.py
+@@ -63,6 +63,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -97,7 +98,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// The current ext4 (Linux 4.5) uses generic_file_read_iter(), instead of it's
++// ext4 uses generic_file_aio_read(), instead of it's
+ // own function, for reads. So we need to trace that and then filter on ext4,
+ // which I do by checking file->f_op.
+ // The new Linux version (since form 4.10) uses ext4_file_read_iter(), And if the 'CONFIG_FS_DAX' 
+@@ -127,7 +128,7 @@ int trace_read_entry(struct pt_regs *ctx, struct kiocb *iocb)
+     return 0;
+ }
+ 
+-// ext4_file_write_iter():
++// ext4_file_write():
+ int trace_write_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -314,15 +315,15 @@ b = BPF(text=bpf_text)
+ if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+     b.attach_kprobe(event="ext4_file_read_iter", fn_name="trace_read_entry")
+ else:
+-    b.attach_kprobe(event="generic_file_read_iter", fn_name="trace_read_entry")
+-b.attach_kprobe(event="ext4_file_write_iter", fn_name="trace_write_entry")
++    b.attach_kprobe(event="generic_file_aio_read", fn_name="trace_read_entry")
++b.attach_kprobe(event="ext4_file_write", fn_name="trace_write_entry")
+ b.attach_kprobe(event="ext4_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="ext4_sync_file", fn_name="trace_fsync_entry")
+ if BPF.get_kprobe_functions(b'ext4_file_read_iter'):
+     b.attach_kretprobe(event="ext4_file_read_iter", fn_name="trace_read_return")
+ else:
+-    b.attach_kretprobe(event="generic_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="ext4_file_write_iter", fn_name="trace_write_return")
++    b.attach_kretprobe(event="generic_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="ext4_file_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="ext4_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="ext4_sync_file", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/fileslower.py b/tools/fileslower.py
+index 31e3adf9..05582c9e 100755
+--- a/tools/fileslower.py
++++ b/tools/fileslower.py
+@@ -123,7 +123,7 @@ int trace_read_entry(struct pt_regs *ctx, struct file *file,
+     char __user *buf, size_t count)
+ {
+     // skip non-sync I/O; see kernel code for __vfs_read()
+-    if (!(file->f_op->read_iter))
++    if (!(file->f_op->aio_read))
+         return 0;
+     return trace_rw_entry(ctx, file, buf, count);
+ }
+@@ -132,7 +132,7 @@ int trace_write_entry(struct pt_regs *ctx, struct file *file,
+     char __user *buf, size_t count)
+ {
+     // skip non-sync I/O; see kernel code for __vfs_write()
+-    if (!(file->f_op->write_iter))
++    if (!(file->f_op->aio_write))
+         return 0;
+     return trace_rw_entry(ctx, file, buf, count);
+ }
+@@ -199,8 +199,13 @@ b = BPF(text=bpf_text)
+ # do_sync_read/do_sync_write), but those became static. So trace these from
+ # the parent functions, at the cost of more overhead, instead.
+ # Ultimately, we should be using [V]FS tracepoints.
+-b.attach_kprobe(event="__vfs_read", fn_name="trace_read_entry")
+-b.attach_kretprobe(event="__vfs_read", fn_name="trace_read_return")
++try:
++    b.attach_kprobe(event="__vfs_read", fn_name="trace_read_entry")
++    b.attach_kretprobe(event="__vfs_read", fn_name="trace_read_return")
++except:
++    # older kernels don't have __vfs_read so try vfs_read instead
++    b.attach_kprobe(event="vfs_read", fn_name="trace_read_entry")
++    b.attach_kretprobe(event="vfs_read", fn_name="trace_read_return")
+ try:
+     b.attach_kprobe(event="__vfs_write", fn_name="trace_write_entry")
+     b.attach_kretprobe(event="__vfs_write", fn_name="trace_write_return")
+diff --git a/tools/memleak.py b/tools/memleak.py
+index fd08bc4d..db8b927a 100755
+--- a/tools/memleak.py
++++ b/tools/memleak.py
+@@ -357,13 +357,21 @@ TRACEPOINT_PROBE(kmem, kmem_cache_free) {
+         return gen_free_enter((struct pt_regs *)args, (void *)args->ptr);
+ }
+ 
++/*
++ * Upstream reads the PFN here, but on RHEL7 kernel this is not available
++ * and the address of the pages struct is returned instead. This value is
++ * used as the key in a hash to identify each allocation. No other allocation
++ * should return an address belonging to mem_map, so there's no risk of
++ * colision
++ */
++
+ TRACEPOINT_PROBE(kmem, mm_page_alloc) {
+         gen_alloc_enter((struct pt_regs *)args, PAGE_SIZE << args->order);
+-        return gen_alloc_exit2((struct pt_regs *)args, args->pfn);
++        return gen_alloc_exit2((struct pt_regs *)args, (size_t)args->page);
+ }
+ 
+ TRACEPOINT_PROBE(kmem, mm_page_free) {
+-        return gen_free_enter((struct pt_regs *)args, (void *)args->pfn);
++        return gen_free_enter((struct pt_regs *)args, (void *)args->page);
+ }
+ """
+ 
+diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py
+index eefb4ec7..5f3678b3 100755
+--- a/tools/mountsnoop.py
++++ b/tools/mountsnoop.py
+@@ -24,7 +24,6 @@ bpf_text = r"""
+ #include <linux/sched.h>
+ 
+ #include <linux/nsproxy.h>
+-#include <linux/ns_common.h>
+ 
+ /*
+  * XXX: struct mnt_namespace is defined in fs/mount.h, which is private to the
+@@ -34,7 +33,7 @@ bpf_text = r"""
+  */
+ struct mnt_namespace {
+     atomic_t count;
+-    struct ns_common ns;
++    unsigned int proc_inum;
+ };
+ 
+ /*
+@@ -69,7 +68,7 @@ struct data_t {
+     union {
+         /* EVENT_MOUNT, EVENT_UMOUNT */
+         struct {
+-            /* current->nsproxy->mnt_ns->ns.inum */
++            /* current->nsproxy->proc_inum */
+             unsigned int mnt_ns;
+             char comm[TASK_COMM_LEN];
+             unsigned long flags;
+@@ -106,7 +105,7 @@ int syscall__mount(struct pt_regs *ctx, char __user *source,
+     task = (struct task_struct *)bpf_get_current_task();
+     nsproxy = task->nsproxy;
+     mnt_ns = nsproxy->mnt_ns;
+-    event.enter.mnt_ns = mnt_ns->ns.inum;
++    event.enter.mnt_ns = mnt_ns->proc_inum;
+     events.perf_submit(ctx, &event, sizeof(event));
+ 
+     event.type = EVENT_MOUNT_SOURCE;
+@@ -161,7 +160,7 @@ int syscall__umount(struct pt_regs *ctx, char __user *target, int flags)
+     task = (struct task_struct *)bpf_get_current_task();
+     nsproxy = task->nsproxy;
+     mnt_ns = nsproxy->mnt_ns;
+-    event.enter.mnt_ns = mnt_ns->ns.inum;
++    event.enter.mnt_ns = mnt_ns->proc_inum;
+     events.perf_submit(ctx, &event, sizeof(event));
+ 
+     event.type = EVENT_UMOUNT_TARGET;
+diff --git a/tools/nfsslower.py b/tools/nfsslower.py
+index 36918ca0..9c6d8f6c 100755
+--- a/tools/nfsslower.py
++++ b/tools/nfsslower.py
+@@ -64,6 +64,7 @@ bpf_text = """
+ 
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+diff --git a/tools/offcputime.py b/tools/offcputime.py
+index ac3b7281..ea36b264 100755
+--- a/tools/offcputime.py
++++ b/tools/offcputime.py
+@@ -128,7 +128,9 @@ BPF_HASH(counts, struct key_t);
+ BPF_HASH(start, u32);
+ BPF_STACK_TRACE(stack_traces, STACK_STORAGE_SIZE);
+ 
+-int oncpu(struct pt_regs *ctx, struct task_struct *prev) {
++struct rq;
++
++int oncpu(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev) {
+     u32 pid = prev->pid;
+     u32 tgid = prev->tgid;
+     u64 ts, *tsp;
+diff --git a/tools/offwaketime.py b/tools/offwaketime.py
+index 4a1cebab..baa28801 100755
+--- a/tools/offwaketime.py
++++ b/tools/offwaketime.py
+@@ -163,7 +163,9 @@ int waker(struct pt_regs *ctx, struct task_struct *p) {
+     return 0;
+ }
+ 
+-int oncpu(struct pt_regs *ctx, struct task_struct *p) {
++struct rq;
++
++int oncpu(struct pt_regs *ctx, struct rq *rq, struct task_struct *p) {
+     // PID and TGID of the previous Process (Process going into waiting)
+     u32 pid = p->pid;
+     u32 tgid = p->tgid;
+diff --git a/tools/oomkill.py b/tools/oomkill.py
+index 4f3b6ce7..546c2dc6 100755
+--- a/tools/oomkill.py
++++ b/tools/oomkill.py
+@@ -35,15 +35,15 @@ struct data_t {
+ 
+ BPF_PERF_OUTPUT(events);
+ 
+-void kprobe__oom_kill_process(struct pt_regs *ctx, struct oom_control *oc, const char *message)
++void kprobe__oom_kill_process(struct pt_regs *ctx, struct task_struct *p,
++			gfp_t gfp_mask, int order, unsigned int points,
++			unsigned long totalpages, struct mem_cgroup *memcg)
+ {
+-    unsigned long totalpages;
+-    struct task_struct *p = oc->chosen;
+     struct data_t data = {};
+     u32 pid = bpf_get_current_pid_tgid();
+     data.fpid = pid;
+     data.tpid = p->pid;
+-    data.pages = oc->totalpages;
++    data.pages = totalpages;
+     bpf_get_current_comm(&data.fcomm, sizeof(data.fcomm));
+     bpf_probe_read(&data.tcomm, sizeof(data.tcomm), p->comm);
+     events.perf_submit(ctx, &data, sizeof(data));
+diff --git a/tools/runqlat.py b/tools/runqlat.py
+index 9fd40642..0c9bb1c4 100755
+--- a/tools/runqlat.py
++++ b/tools/runqlat.py
+@@ -111,7 +111,7 @@ int trace_ttwu_do_wakeup(struct pt_regs *ctx, struct rq *rq, struct task_struct
+ }
+ 
+ // calculate latency
+-int trace_run(struct pt_regs *ctx, struct task_struct *prev)
++int trace_run(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u32 pid, tgid;
+ 
+diff --git a/tools/runqslower.py b/tools/runqslower.py
+index 1d48be8a..16a5a4c2 100755
+--- a/tools/runqslower.py
++++ b/tools/runqslower.py
+@@ -97,7 +97,7 @@ int trace_ttwu_do_wakeup(struct pt_regs *ctx, struct rq *rq, struct task_struct
+ }
+ 
+ // calculate latency
+-int trace_run(struct pt_regs *ctx, struct task_struct *prev)
++int trace_run(struct pt_regs *ctx, struct rq *rq, struct task_struct *prev)
+ {
+     u32 pid, tgid;
+ 
+diff --git a/tools/solisten.py b/tools/solisten.py
+index f2a0a342..16872212 100755
+--- a/tools/solisten.py
++++ b/tools/solisten.py
+@@ -100,7 +100,7 @@ int kprobe__inet_listen(struct pt_regs *ctx, struct socket *sock, int backlog)
+ 
+         // Get network namespace id, if kernel supports it
+ #ifdef CONFIG_NET_NS
+-        evt.netns = sk->__sk_common.skc_net.net->ns.inum;
++        evt.netns = sk->__sk_common.skc_net->proc_inum;
+ #else
+         evt.netns = 0;
+ #endif
+diff --git a/tools/tcpsubnet.py b/tools/tcpsubnet.py
+index 5f2a8062..1ba275bc 100755
+--- a/tools/tcpsubnet.py
++++ b/tools/tcpsubnet.py
+@@ -110,8 +110,8 @@ struct index_key_t {
+ 
+ BPF_HASH(ipv4_send_bytes, struct index_key_t);
+ 
+-int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct sock *sk,
+-    struct msghdr *msg, size_t size)
++int kprobe__tcp_sendmsg(struct pt_regs *ctx, struct kiocb *iocb,
++    struct sock *sk, struct msghdr *msg, size_t size)
+ {
+     u16 family = sk->__sk_common.skc_family;
+ 
+diff --git a/tools/tcptracer.py b/tools/tcptracer.py
+index e61fe9ba..f00f0d19 100755
+--- a/tools/tcptracer.py
++++ b/tools/tcptracer.py
+@@ -115,7 +115,7 @@ static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp)
+   u16 sport = sockp->inet_sport;
+   u16 dport = skp->__sk_common.skc_dport;
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = skp->__sk_common.skc_net->proc_inum;
+ #endif
+ 
+   ##FILTER_NETNS##
+@@ -142,7 +142,7 @@ static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp)
+   u16 sport = sockp->inet_sport;
+   u16 dport = skp->__sk_common.skc_dport;
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = skp->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = skp->__sk_common.skc_net->proc_inum;
+ #endif
+   bpf_probe_read(&saddr, sizeof(saddr),
+                  skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
+@@ -360,8 +360,7 @@ int trace_close_entry(struct pt_regs *ctx, struct sock *skp)
+   // Don't generate close events for connections that were never
+   // established in the first place.
+   if (oldstate == TCP_SYN_SENT ||
+-      oldstate == TCP_SYN_RECV ||
+-      oldstate == TCP_NEW_SYN_RECV)
++      oldstate == TCP_SYN_RECV )
+       return 0;
+ 
+   u8 ipver = 0;
+@@ -432,7 +431,7 @@ int trace_accept_return(struct pt_regs *ctx)
+ 
+   // Get network namespace id, if kernel supports it
+ #ifdef CONFIG_NET_NS
+-  net_ns_inum = newsk->__sk_common.skc_net.net->ns.inum;
++  net_ns_inum = newsk->__sk_common.skc_net->proc_inum;
+ #endif
+ 
+   ##FILTER_NETNS##
+diff --git a/tools/xfsdist.py b/tools/xfsdist.py
+index f409f90d..2976f9e2 100755
+--- a/tools/xfsdist.py
++++ b/tools/xfsdist.py
+@@ -137,12 +137,12 @@ bpf_text = bpf_text.replace('FACTOR', str(factor))
+ b = BPF(text=bpf_text)
+ 
+ # common file functions
+-b.attach_kprobe(event="xfs_file_read_iter", fn_name="trace_entry")
+-b.attach_kprobe(event="xfs_file_write_iter", fn_name="trace_entry")
++b.attach_kprobe(event="xfs_file_aio_read", fn_name="trace_entry")
++b.attach_kprobe(event="xfs_file_aio_write", fn_name="trace_entry")
+ b.attach_kprobe(event="xfs_file_open", fn_name="trace_entry")
+ b.attach_kprobe(event="xfs_file_fsync", fn_name="trace_entry")
+-b.attach_kretprobe(event="xfs_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="xfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="xfs_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="xfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="xfs_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="xfs_file_fsync", fn_name="trace_fsync_return")
+ 
+diff --git a/tools/xfsslower.py b/tools/xfsslower.py
+index 9fa12566..0ef50f6e 100755
+--- a/tools/xfsslower.py
++++ b/tools/xfsslower.py
+@@ -59,6 +59,7 @@ debug = 0
+ bpf_text = """
+ #include <uapi/linux/ptrace.h>
+ #include <linux/fs.h>
++#include <linux/aio.h>
+ #include <linux/sched.h>
+ #include <linux/dcache.h>
+ 
+@@ -93,7 +94,7 @@ BPF_PERF_OUTPUT(events);
+ // Store timestamp and size on entry
+ //
+ 
+-// xfs_file_read_iter(), xfs_file_write_iter():
++// xfs_file_aio_read(), xfs_file_aio_write():
+ int trace_rw_entry(struct pt_regs *ctx, struct kiocb *iocb)
+ {
+     u64 id = bpf_get_current_pid_tgid();
+@@ -264,12 +265,12 @@ int trace_fsync_return(struct pt_regs *ctx)
+ b = BPF(text=bpf_text)
+ 
+ # common file functions
+-b.attach_kprobe(event="xfs_file_read_iter", fn_name="trace_rw_entry")
+-b.attach_kprobe(event="xfs_file_write_iter", fn_name="trace_rw_entry")
++b.attach_kprobe(event="xfs_file_aio_read", fn_name="trace_rw_entry")
++b.attach_kprobe(event="xfs_file_aio_write", fn_name="trace_rw_entry")
+ b.attach_kprobe(event="xfs_file_open", fn_name="trace_open_entry")
+ b.attach_kprobe(event="xfs_file_fsync", fn_name="trace_fsync_entry")
+-b.attach_kretprobe(event="xfs_file_read_iter", fn_name="trace_read_return")
+-b.attach_kretprobe(event="xfs_file_write_iter", fn_name="trace_write_return")
++b.attach_kretprobe(event="xfs_file_aio_read", fn_name="trace_read_return")
++b.attach_kretprobe(event="xfs_file_aio_write", fn_name="trace_write_return")
+ b.attach_kretprobe(event="xfs_file_open", fn_name="trace_open_return")
+ b.attach_kretprobe(event="xfs_file_fsync", fn_name="trace_fsync_return")
+ 
+-- 
+2.20.1
+
diff --git a/SOURCES/bcc-0.10.0-tools-fix-vfscount-output-when-no-duration-is-specif.patch b/SOURCES/bcc-0.10.0-tools-fix-vfscount-output-when-no-duration-is-specif.patch
new file mode 100644
index 0000000..84be464
--- /dev/null
+++ b/SOURCES/bcc-0.10.0-tools-fix-vfscount-output-when-no-duration-is-specif.patch
@@ -0,0 +1,62 @@
+From 0206fc4e3568eab6cacfc1d5916258a9ba764f5d Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Mon, 5 Aug 2019 15:29:22 +0200
+Subject: [PATCH] tools: fix vfscount output when no duration is specified
+
+Since commit a2e71a9eb71a ("vfscount.py: add args time (#2344)"),
+vfscount does not show any output when it is interrupted by a key
+press, which is the only way out when no time limit is specified. I
+assume the exit() that has been added in the keyboard interrupt
+handler is there so that no output is displayed when the program has
+been interrupted early when a time limit has been specified. But since
+the tool still invite the user to use Ctrl-C to end the tracing in
+that case, it seems more consistent to show an output in that case
+too.
+
+This patch removes the exit() and the tools always show a result at
+the end. It also adds the duration argument to the synopsis and the
+option section in the man page.
+---
+ man/man8/vfscount.8 | 6 +++++-
+ tools/vfscount.py   | 1 -
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/man/man8/vfscount.8 b/man/man8/vfscount.8
+index fbf0e89e..febbc9e6 100644
+--- a/man/man8/vfscount.8
++++ b/man/man8/vfscount.8
+@@ -2,7 +2,7 @@
+ .SH NAME
+ vfscount \- Count VFS calls ("vfs_*"). Uses Linux eBPF/bcc.
+ .SH SYNOPSIS
+-.B vfscount
++.B vfscount [duration]
+ .SH DESCRIPTION
+ This counts VFS calls. This can be useful for general workload
+ characterization of these operations.
+@@ -14,6 +14,10 @@ Edit the script to customize which functions to trace.
+ Since this uses BPF, only the root user can use this tool.
+ .SH REQUIREMENTS
+ CONFIG_BPF and bcc.
++.SH OPTIONS
++.TP
++duration
++duration of the trace in seconds.
+ .SH EXAMPLES
+ .TP
+ Count some VFS calls until Ctrl-C is hit:
+diff --git a/tools/vfscount.py b/tools/vfscount.py
+index b7c18efd..303d3fde 100755
+--- a/tools/vfscount.py
++++ b/tools/vfscount.py
+@@ -54,7 +54,6 @@ print("Tracing... Ctrl-C to end.")
+     sleep(interval)
+ except KeyboardInterrupt:
+     pass
+-    exit()
+ 
+ print("\n%-16s %-26s %8s" % ("ADDR", "FUNC", "COUNT"))
+ counts = b.get_table("counts")
+-- 
+2.20.1
+
diff --git a/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch b/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch
new file mode 100644
index 0000000..fe40e27
--- /dev/null
+++ b/SOURCES/link-against-libLLVM.so-instead-of-static-libs.patch
@@ -0,0 +1,30 @@
+From ddbdaef40b7db8259f7728a64839b9ff38fbfd76 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Fri, 15 Jun 2018 11:41:47 +0200
+Subject: [PATCH] Link against libLLVM.so instead of static libs
+
+---
+ src/cc/CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cc/CMakeLists.txt b/src/cc/CMakeLists.txt
+index 8ddfd8f..0c3d7df 100644
+--- a/src/cc/CMakeLists.txt
++++ b/src/cc/CMakeLists.txt
+@@ -62,11 +62,11 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${llvm_lib_exclude_f
+ # bcc_common_libs_for_a for archive libraries
+ # bcc_common_libs_for_s for shared libraries
+ set(bcc_common_libs_for_a b_frontend clang_frontend bpf-static
+-  -Wl,--whole-archive ${clang_libs} ${llvm_libs} -Wl,--no-whole-archive
++  -Wl,--whole-archive ${clang_libs} libLLVM-7-rhel.so -Wl,--no-whole-archive
+   ${LIBELF_LIBRARIES})
+ set(bcc_common_libs_for_s ${bcc_common_libs_for_a})
+ set(bcc_common_libs_for_lua b_frontend clang_frontend bpf-static
+-  ${clang_libs} ${llvm_libs} ${LIBELF_LIBRARIES})
++  ${clang_libs} libLLVM-7-rhel.so ${LIBELF_LIBRARIES})
+ 
+ if(ENABLE_CPP_API)
+   add_subdirectory(api)
+-- 
+2.17.1
+
diff --git a/SPECS/bcc.spec b/SPECS/bcc.spec
new file mode 100644
index 0000000..b7aa384
--- /dev/null
+++ b/SPECS/bcc.spec
@@ -0,0 +1,279 @@
+# luajit is not available for some architectures and not at all on RHEL7
+%if 0%{?rhel} <= 7
+%bcond_with lua
+%else
+%ifarch ppc64 ppc64le s390x
+%bcond_with lua
+%else
+%bcond_without lua
+%endif
+%endif
+
+Name:           bcc
+Version:        0.10.0
+Release:        1%{?dist}
+Summary:        BPF Compiler Collection (BCC)
+License:        ASL 2.0
+URL:            https://github.com/iovisor/bcc
+# Generate source tarball until upstream bug is fixed
+# See https://github.com/iovisor/bcc/issues/2261
+# To generate the tarball, use the following commands
+# git clone -b "v0.10.0" --single-branch --depth 1 url bcc-0.10.0
+# pushd bcc-0.10.0
+# git submodule update --init
+# popd
+# tar zcvf bcc-0.10.0.tar.gz bcc-0.10.0/
+#Source0:        %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
+Source0:        %{name}-%{version}.tar.gz
+Patch0:         link-against-libLLVM.so-instead-of-static-libs.patch
+Patch1:         Fix-tools-for-RHEL-7.patch
+Patch2:         %{name}-%{version}-tools-fix-vfscount-output-when-no-duration-is-specif.patch
+
+# Arches will be included as upstream support is added and dependencies are
+# satisfied in the respective arches
+ExcludeArch: i686 ppc s390
+
+BuildRequires:  bison, cmake >= 2.8.7, flex, libxml2-devel
+BuildRequires:  python-devel
+BuildRequires:  elfutils-libelf-devel
+BuildRequires:  ncurses-devel
+%if %{with lua}
+BuildRequires: pkgconfig(luajit)
+%endif
+BuildRequires: llvm-private-devel >= 6.0.1-0.3
+
+Requires:       %{name}-tools = %{version}-%{release}
+Requires:       llvm-private >= 6.0.1-0.3
+
+%description
+BCC is a toolkit for creating efficient kernel tracing and manipulation
+programs, and includes several useful tools and examples. It makes use of
+extended BPF (Berkeley Packet Filters), formally known as eBPF, a new feature
+that was first added to Linux 3.15. BCC makes BPF programs easier to write,
+with kernel instrumentation in C (and includes a C wrapper around LLVM), and
+front-ends in Python and lua. It is suited for many tasks, including
+performance analysis and network traffic control.
+
+
+%package devel
+Summary:        Shared library for BPF Compiler Collection (BCC)
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+The %{name}-devel package contains libraries and header files for developing
+application that use BPF Compiler Collection (BCC).
+
+
+%package doc
+Summary:        Examples for BPF Compiler Collection (BCC)
+BuildArch:      noarch
+
+%description doc
+Examples for BPF Compiler Collection (BCC)
+
+
+%package -n python-%{name}
+Summary:        Python bindings for BPF Compiler Collection (BCC)
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+%{?python_provide:%python_provide python-%{srcname}}
+
+%description -n python-%{name}
+Python bindings for BPF Compiler Collection (BCC)
+
+
+%if %{with lua}
+%package lua
+Summary:        Standalone tool to run BCC tracers written in Lua
+Requires:       %{name}%{?_isa} = %{version}-%{release}
+
+%description lua
+Standalone tool to run BCC tracers written in Lua
+%endif
+
+
+%package tools
+Summary:        Command line tools for BPF Compiler Collection (BCC)
+Requires:       python-%{name} = %{version}-%{release}
+Requires:       python-netaddr
+Requires:       kernel-devel
+
+%description tools
+Command line tools for BPF Compiler Collection (BCC)
+
+%prep
+%autosetup -p1
+
+%build
+%cmake . \
+        -DCMAKE_BUILD_TYPE=RelWithDebInfo\
+        -DCMAKE_CXX_FLAGS='-std=c++11 -I/usr/include/llvm-private/'\
+        -DREVISION_LAST=%{version} -DREVISION=%{version}\
+        -DCMAKE_LIBRARY_PATH=/usr/lib64/clang-private/\
+	-DCMAKE_INSTALL_RPATH=/usr/lib64/clang-private/
+%make_build
+
+%install
+%make_install
+
+# Move man pages to the right location
+mkdir -p %{buildroot}%{_mandir}
+mv %{buildroot}%{_datadir}/%{name}/man/* %{buildroot}%{_mandir}/
+# Avoid conflict with other manpages
+# https://bugzilla.redhat.com/show_bug.cgi?id=1517408
+for i in `find %{buildroot}%{_mandir} -name "*.gz"`; do
+  tname=$(basename $i)
+  rename $tname %{name}-$tname $i
+done
+# Fix the symlink too
+for i in `find %{buildroot}%{_mandir} -lname \*.gz` ; do
+    target=`readlink $i`;
+    ln -sf bcc-$target $i;
+done
+mkdir -p %{buildroot}%{_docdir}/%{name}
+mv %{buildroot}%{_datadir}/%{name}/examples %{buildroot}%{_docdir}/%{name}/
+
+# We cannot run the test suit since it requires root and it makes changes to
+# the machine (e.g, IP address)
+#%check
+
+%post -p /sbin/ldconfig
+%postun -p /sbin/ldconfig
+
+%files
+%doc README.md
+%license LICENSE.txt
+%{_libdir}/lib%{name}.so.*
+%{_libdir}/libbcc_bpf.so.*
+
+%files devel
+%{_libdir}/lib%{name}.so
+%{_libdir}/libbcc_bpf.so
+%{_libdir}/pkgconfig/lib%{name}.pc
+%{_includedir}/%{name}/
+
+%files -n python-%{name}
+%{python_sitelib}/%{name}*
+
+%files doc
+%dir %{_docdir}/%{name}
+%doc %{_docdir}/%{name}/examples/
+
+%files tools
+%dir %{_datadir}/%{name}
+%dir %{_datadir}/%{name}/tools
+%dir %{_datadir}/%{name}/introspection
+%{_datadir}/%{name}/tools/*
+%{_datadir}/%{name}/introspection/*
+%exclude %{_datadir}/%{name}/tools/old/
+# inject relies on BPF_KPROBE_OVERRIDE which is absent on RHEL 7
+%exclude %{_datadir}/%{name}/tools/inject
+%exclude %{_datadir}/%{name}/tools/doc/inject_example.txt
+%exclude %{_mandir}/man8/inject.8
+# ZFS isn't available on RHEL
+%exclude %{_datadir}/%{name}/tools/zfs*
+%exclude %{_datadir}/%{name}/tools/doc/zfs*
+%exclude %{_mandir}/man8/zfs*
+# criticalstat relies on CONFIG_PREEMPTIRQ_EVENTS which is absent on RHEL 7
+%exclude %{_datadir}/%{name}/tools/criticalstat
+%exclude %{_datadir}/%{name}/tools/doc/criticalstat_example.txt
+%exclude %{_mandir}/man8/criticalstat.8
+# tcpstates relies on sock:inet_sock_set_state which is absent on RHEL 7
+%exclude %{_datadir}/%{name}/tools/tcpstates
+%exclude %{_datadir}/%{name}/tools/doc/tcpstates_example.txt
+%exclude %{_mandir}/man8/tcpstates.8
+%{_mandir}/man8/*
+
+%if %{with lua}
+%files lua
+%{_bindir}/bcc-lua
+%endif
+
+
+%changelog
+* Tue Aug 06 2019 Jerome Marchand <jmarchan@redhat.com> - 0.10.0-1
+- Rebase on bcc-0.10.0
+- Fix regression of vfscount
+- Drop tools that relies on features unavailable on RHEL 7
+
+* Mon Jan 28 2019 Jerome Marchand <jmarchan@redhat.com> - 0.8.0-1
+- Rebase on bcc-8.0.0
+- Update libLLVM.so name for 7.0
+
+* Fri Sep 21 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.1-2
+- Set a minimal version for llvm-private(-devel)
+
+* Thu Aug 16 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.1-1
+- Rebase on v0.6.1
+- Fix tcpsubnet
+- Reinstate llcstat tool
+- Remove inject tool
+- Add NSS support to sslsniff
+- Fixes miscellaneous error uncovered by covscan
+
+* Wed Jul 04 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-3
+- Fix tools on RHEL 7
+- Remove llcstat and ZFS tools.
+
+* Tue Jun 26 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-2
+- Add llvm-private requirement
+- Fix manpages symlinks
+
+* Tue Jun 19 2018 Jerome Marchand <jmarchan@redhat.com> - 0.6.0-1
+- Rebase on bcc-0.6.0
+
+* Thu Jun 07 2018 Jerome Marchand <jmarchan@redhat.com> - 0.5.0-6
+- Enables build on RHEL 7
+
+* Thu May 24 2018 Jerome Marchand <jmarchan@redhat.com> - 0.5.0-5
+- Enables build on ppc64(le) and s390x arches
+
+* Thu Apr 05 2018 Rafael Santos <rdossant@redhat.com> - 0.5.0-4
+- Resolves #1555627 - fix compilation error with latest llvm/clang
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.5.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Fri Feb 02 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.5.0-2
+- Switch to %%ldconfig_scriptlets
+
+* Wed Jan 03 2018 Rafael Santos <rdossant@redhat.com> - 0.5.0-1
+- Rebase to new released version
+
+* Thu Nov 16 2017 Rafael Santos <rdossant@redhat.com> - 0.4.0-4
+- Resolves #1517408 - avoid conflict with other manpages
+
+* Thu Nov 02 2017 Rafael Santos <rdossant@redhat.com> - 0.4.0-3
+- Use weak deps to not require lua subpkg on ppc64(le)
+
+* Wed Nov 01 2017 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 0.4.0-2
+- Rebuild for LLVM5
+
+* Wed Nov 01 2017 Rafael Fonseca <rdossant@redhat.com> - 0.4.0-1
+- Resolves #1460482 - rebase to new release
+- Resolves #1505506 - add support for LLVM 5.0
+- Resolves #1460482 - BPF module compilation issue
+- Partially address #1479990 - location of man pages
+- Enable ppc64(le) support without lua
+- Soname versioning for libbpf by ignatenkobrain
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.3.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.3.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Thu Mar 30 2017 Igor Gnatenko <ignatenko@redhat.com> - 0.3.0-2
+- Rebuild for LLVM4
+- Trivial fixes in spec
+
+* Fri Mar 10 2017 Rafael Fonseca <rdossant@redhat.com> - 0.3.0-1
+- Rebase to new release.
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.2.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Tue Jan 10 2017 Rafael Fonseca <rdossant@redhat.com> - 0.2.0-2
+- Fix typo
+
+* Tue Nov 29 2016 Rafael Fonseca <rdossant@redhat.com> - 0.2.0-1
+- Initial import