Mirror of the lttng-dev mailing list
 help / color / mirror / Atom feed
* [lttng-dev] LTTng driver submission for inclusion in staging (resend)
@ 2011-11-26 15:03 Mathieu Desnoyers
  2011-11-26 15:03 ` [lttng-dev] [PATCH 01/19] lttng lib: ring buffer Mathieu Desnoyers
  2011-11-27  2:28 ` [lttng-dev] LTTng driver submission for inclusion in staging (resend) Greg KH
  0 siblings, 2 replies; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)



Hi,

I hereby propose the LTTng kernel tracer for inclusion into the staging
area of the Linux kernel. For those eager to try it out, and to get
information about the features of this tracer, you should grab the
control/consumer/viewer tools at: http://lttng.org/lttng2.0

Feedback is very welcome!

Diffstat:

 drivers/staging/lttng/lib/ringbuffer/api.h                                                           |   25 
 drivers/staging/lttng/lib/ringbuffer/backend.h                                                       |  250 +
 drivers/staging/lttng/lib/ringbuffer/backend_internal.h                                              |  449 ++
 drivers/staging/lttng/lib/ringbuffer/backend_types.h                                                 |   80 
 drivers/staging/lttng/lib/ringbuffer/config.h                                                        |  298 +
 drivers/staging/lttng/lib/ringbuffer/frontend.h                                                      |  228 +
 drivers/staging/lttng/lib/ringbuffer/frontend_api.h                                                  |  358 +
 drivers/staging/lttng/lib/ringbuffer/frontend_internal.h                                             |  424 +
 drivers/staging/lttng/lib/ringbuffer/frontend_types.h                                                |  176 
 drivers/staging/lttng/lib/ringbuffer/iterator.h                                                      |   70 
 drivers/staging/lttng/lib/ringbuffer/nohz.h                                                          |   30 
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c                                           |  854 +++
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c                                          | 1721 +++++++
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c                                          |  798 +++
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c                                              |  115 
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c                                            |  202 
 drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c                                               |  387 +
 drivers/staging/lttng/lib/ringbuffer/vatomic.h                                                       |   85 
 drivers/staging/lttng/lib/ringbuffer/vfs.h                                                           |   89 
 drivers/staging/lttng/lib/bitfield.h                                                                 |  400 +
 drivers/staging/lttng/lib/bug.h                                                                      |   29 
 drivers/staging/lttng/lib/align.h                                                                    |   61 
 drivers/staging/lttng/lib/Makefile                                                                   |   11 
 drivers/staging/lttng/wrapper/ftrace.h                                                               |   70 
 drivers/staging/lttng/wrapper/inline_memcpy.h                                                        |   11 
 drivers/staging/lttng/wrapper/kallsyms.h                                                             |   28 
 drivers/staging/lttng/wrapper/perf.h                                                                 |   32 
 drivers/staging/lttng/wrapper/poll.h                                                                 |   16 
 drivers/staging/lttng/wrapper/ringbuffer/api.h                                                       |    1 
 drivers/staging/lttng/wrapper/ringbuffer/backend.h                                                   |    1 
 drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h                                          |    2 
 drivers/staging/lttng/wrapper/ringbuffer/backend_types.h                                             |    1 
 drivers/staging/lttng/wrapper/ringbuffer/config.h                                                    |    1 
 drivers/staging/lttng/wrapper/ringbuffer/frontend.h                                                  |    1 
 drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h                                              |    1 
 drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h                                         |    1 
 drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h                                            |    1 
 drivers/staging/lttng/wrapper/ringbuffer/iterator.h                                                  |    1 
 drivers/staging/lttng/wrapper/ringbuffer/nohz.h                                                      |    1 
 drivers/staging/lttng/wrapper/ringbuffer/vatomic.h                                                   |    1 
 drivers/staging/lttng/wrapper/ringbuffer/vfs.h                                                       |    1 
 drivers/staging/lttng/wrapper/spinlock.h                                                             |   26 
 drivers/staging/lttng/wrapper/splice.c                                                               |   46 
 drivers/staging/lttng/wrapper/splice.h                                                               |   23 
 drivers/staging/lttng/wrapper/trace-clock.h                                                          |   77 
 drivers/staging/lttng/wrapper/uuid.h                                                                 |   29 
 drivers/staging/lttng/wrapper/vmalloc.h                                                              |   49 
 drivers/staging/lttng/instrumentation/events/README                                                  |    7 
 drivers/staging/lttng/instrumentation/events/lttng-module/block.h                                    |  626 ++
 drivers/staging/lttng/instrumentation/events/lttng-module/irq.h                                      |  155 
 drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h                                      |  312 +
 drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h                                    |   34 
 drivers/staging/lttng/instrumentation/events/lttng-module/sched.h                                    |  400 +
 drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h                                 |   76 
 drivers/staging/lttng/instrumentation/events/mainline/block.h                                        |  569 ++
 drivers/staging/lttng/instrumentation/events/mainline/irq.h                                          |  150 
 drivers/staging/lttng/instrumentation/events/mainline/kvm.h                                          |  312 +
 drivers/staging/lttng/instrumentation/events/mainline/sched.h                                        |  397 +
 drivers/staging/lttng/instrumentation/events/mainline/syscalls.h                                     |   75 
 drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4                           |  263 +
 drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6                   |  291 +
 drivers/staging/lttng/instrumentation/syscalls/README                                                |   18 
 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h                    |    3 
 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h                    |    3 
 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h                           |    9 
 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h                  |   13 
 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h                           |    9 
 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h                            |   55 
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h          | 1161 +++++
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h |   38 
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h          | 2230 ++++++++++
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h |   17 
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h              | 1011 ++++
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h              | 2074 +++++++++
 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h     |    5 
 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile                     |    1 
 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c   |   85 
 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh                    |  272 +
 drivers/staging/lttng/ltt-ring-buffer-client-discard.c                                               |   21 
 drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c                                          |   21 
 drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c                                        |   21 
 drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c                                             |   21 
 drivers/staging/lttng/ltt-ring-buffer-client.h                                                       |  569 ++
 drivers/staging/lttng/ltt-ring-buffer-metadata-client.c                                              |   21 
 drivers/staging/lttng/ltt-ring-buffer-metadata-client.h                                              |  330 +
 drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c                                         |   21 
 drivers/staging/lttng/ltt-endian.h                                                                   |   31 
 drivers/staging/lttng/ltt-events.c                                                                   | 1009 ++++
 drivers/staging/lttng/ltt-events.h                                                                   |  452 ++
 drivers/staging/lttng/ltt-probes.c                                                                   |  164 
 drivers/staging/lttng/ltt-tracer-core.h                                                              |   28 
 drivers/staging/lttng/ltt-tracer.h                                                                   |   67 
 drivers/staging/lttng/ltt-context.c                                                                  |   93 
 drivers/staging/lttng/lttng-context-nice.c                                                           |   68 
 drivers/staging/lttng/lttng-context-perf-counters.c                                                  |  271 +
 drivers/staging/lttng/lttng-context-pid.c                                                            |   68 
 drivers/staging/lttng/lttng-context-ppid.c                                                           |   71 
 drivers/staging/lttng/lttng-context-prio.c                                                           |   89 
 drivers/staging/lttng/lttng-context-procname.c                                                       |   72 
 drivers/staging/lttng/lttng-context-tid.c                                                            |   68 
 drivers/staging/lttng/lttng-context-vpid.c                                                           |   74 
 drivers/staging/lttng/lttng-context-vppid.c                                                          |   79 
 drivers/staging/lttng/lttng-context-vtid.c                                                           |   74 
 drivers/staging/lttng/lttng-calibrate.c                                                              |   30 
 drivers/staging/lttng/ltt-debugfs-abi.c                                                              |  777 +++
 drivers/staging/lttng/ltt-debugfs-abi.h                                                              |  153 
 drivers/staging/lttng/ChangeLog                                                                      |   75 
 drivers/staging/lttng/LICENSE                                                                        |   27 
 drivers/staging/lttng/README                                                                         |   46 
 drivers/staging/lttng/gpl-2.0.txt                                                                    |  339 +
 drivers/staging/lttng/lgpl-2.1.txt                                                                   |  504 ++
 drivers/staging/lttng/lttng-syscalls.c                                                               |  437 +
 drivers/staging/lttng/probes/Makefile                                                                |   37 
 drivers/staging/lttng/probes/define_trace.h                                                          |  132 
 drivers/staging/lttng/probes/lttng-events-reset.h                                                    |   84 
 drivers/staging/lttng/probes/lttng-events.h                                                          |  703 +++
 drivers/staging/lttng/probes/lttng-ftrace.c                                                          |  188 
 drivers/staging/lttng/probes/lttng-kprobes.c                                                         |  164 
 drivers/staging/lttng/probes/lttng-kretprobes.c                                                      |  277 +
 drivers/staging/lttng/probes/lttng-probe-block.c                                                     |   31 
 drivers/staging/lttng/probes/lttng-probe-irq.c                                                       |   31 
 drivers/staging/lttng/probes/lttng-probe-kvm.c                                                       |   31 
 drivers/staging/lttng/probes/lttng-probe-lttng.c                                                     |   24 
 drivers/staging/lttng/probes/lttng-probe-sched.c                                                     |   30 
 drivers/staging/lttng/probes/lttng-type-list.h                                                       |   21 
 drivers/staging/lttng/probes/lttng-types.c                                                           |   49 
 drivers/staging/lttng/probes/lttng-types.h                                                           |   72 
 drivers/staging/lttng/probes/lttng.h                                                                 |   15 
 drivers/staging/lttng/Kconfig                                                                        |   35 
 drivers/staging/lttng/Makefile                                                                       |   33 
 drivers/staging/Kconfig                                                                              |    2 
 drivers/staging/Makefile                                                                             |    1 
 MAINTAINERS                                                                                          |    7 
 133 files changed, 26390 insertions(+)

Best regards,

Mathieu



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 01/19] lttng lib: ring buffer
  2011-11-26 15:03 [lttng-dev] LTTng driver submission for inclusion in staging (resend) Mathieu Desnoyers
@ 2011-11-26 15:03 ` Mathieu Desnoyers
  2011-11-26 15:03   ` [lttng-dev] [PATCH 02/19] lttng lib: portable bitfield read/write header Mathieu Desnoyers
  2011-11-27  2:28 ` [lttng-dev] LTTng driver submission for inclusion in staging (resend) Greg KH
  1 sibling, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lib/ringbuffer/api.h         |   25 +
 drivers/staging/lttng/lib/ringbuffer/backend.h     |  250 +++
 .../lttng/lib/ringbuffer/backend_internal.h        |  449 +++++
 .../staging/lttng/lib/ringbuffer/backend_types.h   |   80 +
 drivers/staging/lttng/lib/ringbuffer/config.h      |  298 ++++
 drivers/staging/lttng/lib/ringbuffer/frontend.h    |  228 +++
 .../staging/lttng/lib/ringbuffer/frontend_api.h    |  358 ++++
 .../lttng/lib/ringbuffer/frontend_internal.h       |  424 +++++
 .../staging/lttng/lib/ringbuffer/frontend_types.h  |  176 ++
 drivers/staging/lttng/lib/ringbuffer/iterator.h    |   70 +
 drivers/staging/lttng/lib/ringbuffer/nohz.h        |   30 +
 .../lttng/lib/ringbuffer/ring_buffer_backend.c     |  854 ++++++++++
 .../lttng/lib/ringbuffer/ring_buffer_frontend.c    | 1721 ++++++++++++++++++++
 .../lttng/lib/ringbuffer/ring_buffer_iterator.c    |  798 +++++++++
 .../lttng/lib/ringbuffer/ring_buffer_mmap.c        |  115 ++
 .../lttng/lib/ringbuffer/ring_buffer_splice.c      |  202 +++
 .../staging/lttng/lib/ringbuffer/ring_buffer_vfs.c |  387 +++++
 drivers/staging/lttng/lib/ringbuffer/vatomic.h     |   85 +
 drivers/staging/lttng/lib/ringbuffer/vfs.h         |   89 +
 19 files changed, 6639 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/api.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend_internal.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend_types.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/config.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_api.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_internal.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_types.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/iterator.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/nohz.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/vatomic.h
 create mode 100644 drivers/staging/lttng/lib/ringbuffer/vfs.h

diff --git a/drivers/staging/lttng/lib/ringbuffer/api.h b/drivers/staging/lttng/lib/ringbuffer/api.h
new file mode 100644
index 0000000..f8a1145
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/api.h
@@ -0,0 +1,25 @@
+#ifndef _LINUX_RING_BUFFER_API_H
+#define _LINUX_RING_BUFFER_API_H
+
+/*
+ * linux/ringbuffer/api.h
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers "mathieu.desnoyers at efficios.com"
+ *
+ * Ring Buffer API.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+#include "../../wrapper/ringbuffer/vfs.h"
+
+/*
+ * ring_buffer_frontend_api.h contains static inline functions that depend on
+ * client static inlines. Hence the inclusion of this "api" header only
+ * within the client.
+ */
+#include "../../wrapper/ringbuffer/frontend_api.h"
+
+#endif /* _LINUX_RING_BUFFER_API_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/backend.h b/drivers/staging/lttng/lib/ringbuffer/backend.h
new file mode 100644
index 0000000..541dc53
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/backend.h
@@ -0,0 +1,250 @@
+#ifndef _LINUX_RING_BUFFER_BACKEND_H
+#define _LINUX_RING_BUFFER_BACKEND_H
+
+/*
+ * linux/ringbuffer/backend.h
+ *
+ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer backend (API).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ *
+ * Credits to Steven Rostedt for proposing to use an extra-subbuffer owned by
+ * the reader in flight recorder mode.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+/* Internal helpers */
+#include "../../wrapper/ringbuffer/backend_internal.h"
+#include "../../wrapper/ringbuffer/frontend_internal.h"
+
+/* Ring buffer backend API */
+
+/* Ring buffer backend access (read/write) */
+
+extern size_t lib_ring_buffer_read(struct lib_ring_buffer_backend *bufb,
+				   size_t offset, void *dest, size_t len);
+
+extern int __lib_ring_buffer_copy_to_user(struct lib_ring_buffer_backend *bufb,
+					  size_t offset, void __user *dest,
+					  size_t len);
+
+extern int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb,
+				     size_t offset, void *dest, size_t len);
+
+extern struct page **
+lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb, size_t offset,
+			      void ***virt);
+
+/*
+ * Return the address where a given offset is located.
+ * Should be used to get the current subbuffer header pointer. Given we know
+ * it's never on a page boundary, it's safe to write directly to this address,
+ * as long as the write is never bigger than a page size.
+ */
+extern void *
+lib_ring_buffer_offset_address(struct lib_ring_buffer_backend *bufb,
+			       size_t offset);
+extern void *
+lib_ring_buffer_read_offset_address(struct lib_ring_buffer_backend *bufb,
+				    size_t offset);
+
+/**
+ * lib_ring_buffer_write - write data to a buffer backend
+ * @config : ring buffer instance configuration
+ * @ctx: ring buffer context. (input arguments only)
+ * @src : source pointer to copy from
+ * @len : length of data to copy
+ *
+ * This function copies "len" bytes of data from a source pointer to a buffer
+ * backend, at the current context offset. This is more or less a buffer
+ * backend-specific memcpy() operation. Calls the slow path (_ring_buffer_write)
+ * if copy is crossing a page boundary.
+ */
+static inline
+void lib_ring_buffer_write(const struct lib_ring_buffer_config *config,
+			   struct lib_ring_buffer_ctx *ctx,
+			   const void *src, size_t len)
+{
+	struct lib_ring_buffer_backend *bufb = &ctx->buf->backend;
+	struct channel_backend *chanb = &ctx->chan->backend;
+	size_t sbidx, index;
+	size_t offset = ctx->buf_offset;
+	ssize_t pagecpy;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	sbidx = offset >> chanb->subbuf_size_order;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK);
+	id = bufb->buf_wsb[sbidx].id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(ctx->chan,
+		     config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+	if (likely(pagecpy == len))
+		lib_ring_buffer_do_copy(config,
+					rpages->p[index].virt
+					    + (offset & ~PAGE_MASK),
+					src, len);
+	else
+		_lib_ring_buffer_write(bufb, offset, src, len, 0);
+	ctx->buf_offset += len;
+}
+
+/**
+ * lib_ring_buffer_memset - write len bytes of c to a buffer backend
+ * @config : ring buffer instance configuration
+ * @bufb : ring buffer backend
+ * @offset : offset within the buffer
+ * @c : the byte to copy
+ * @len : number of bytes to copy
+ *
+ * This function writes "len" bytes of "c" to a buffer backend, at a specific
+ * offset. This is more or less a buffer backend-specific memset() operation.
+ * Calls the slow path (_ring_buffer_memset) if write is crossing a page
+ * boundary.
+ */
+static inline
+void lib_ring_buffer_memset(const struct lib_ring_buffer_config *config,
+			    struct lib_ring_buffer_ctx *ctx, int c, size_t len)
+{
+
+	struct lib_ring_buffer_backend *bufb = &ctx->buf->backend;
+	struct channel_backend *chanb = &ctx->chan->backend;
+	size_t sbidx, index;
+	size_t offset = ctx->buf_offset;
+	ssize_t pagecpy;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	sbidx = offset >> chanb->subbuf_size_order;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK);
+	id = bufb->buf_wsb[sbidx].id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(ctx->chan,
+		     config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+	if (likely(pagecpy == len))
+		lib_ring_buffer_do_memset(rpages->p[index].virt
+					  + (offset & ~PAGE_MASK),
+					  c, len);
+	else
+		_lib_ring_buffer_memset(bufb, offset, c, len, 0);
+	ctx->buf_offset += len;
+}
+
+/**
+ * lib_ring_buffer_copy_from_user - write userspace data to a buffer backend
+ * @config : ring buffer instance configuration
+ * @ctx: ring buffer context. (input arguments only)
+ * @src : userspace source pointer to copy from
+ * @len : length of data to copy
+ *
+ * This function copies "len" bytes of data from a userspace pointer to a
+ * buffer backend, at the current context offset. This is more or less a buffer
+ * backend-specific memcpy() operation. Calls the slow path
+ * (_ring_buffer_write_from_user) if copy is crossing a page boundary.
+ */
+static inline
+void lib_ring_buffer_copy_from_user(const struct lib_ring_buffer_config *config,
+				    struct lib_ring_buffer_ctx *ctx,
+				    const void __user *src, size_t len)
+{
+	struct lib_ring_buffer_backend *bufb = &ctx->buf->backend;
+	struct channel_backend *chanb = &ctx->chan->backend;
+	size_t sbidx, index;
+	size_t offset = ctx->buf_offset;
+	ssize_t pagecpy;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+	unsigned long ret;
+
+	offset &= chanb->buf_size - 1;
+	sbidx = offset >> chanb->subbuf_size_order;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK);
+	id = bufb->buf_wsb[sbidx].id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(ctx->chan,
+		     config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+
+	if (unlikely(!access_ok(VERIFY_READ, src, len)))
+		goto fill_buffer;
+
+	if (likely(pagecpy == len)) {
+		ret = lib_ring_buffer_do_copy_from_user(
+			rpages->p[index].virt + (offset & ~PAGE_MASK),
+			src, len);
+		if (unlikely(ret > 0)) {
+			len -= (pagecpy - ret);
+			offset += (pagecpy - ret);
+			goto fill_buffer;
+		}
+	} else {
+		_lib_ring_buffer_copy_from_user(bufb, offset, src, len, 0);
+	}
+	ctx->buf_offset += len;
+
+	return;
+
+fill_buffer:
+	/*
+	 * In the error path we call the slow path version to avoid
+	 * the pollution of static inline code.
+	 */
+	_lib_ring_buffer_memset(bufb, offset, 0, len, 0);
+}
+
+/*
+ * This accessor counts the number of unread records in a buffer.
+ * It only provides a consistent value if no reads not writes are performed
+ * concurrently.
+ */
+static inline
+unsigned long lib_ring_buffer_get_records_unread(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	struct lib_ring_buffer_backend *bufb = &buf->backend;
+	struct lib_ring_buffer_backend_pages *pages;
+	unsigned long records_unread = 0, sb_bindex, id;
+	unsigned int i;
+
+	for (i = 0; i < bufb->chan->backend.num_subbuf; i++) {
+		id = bufb->buf_wsb[i].id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		pages = bufb->array[sb_bindex];
+		records_unread += v_read(config, &pages->records_unread);
+	}
+	if (config->mode == RING_BUFFER_OVERWRITE) {
+		id = bufb->buf_rsb.id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		pages = bufb->array[sb_bindex];
+		records_unread += v_read(config, &pages->records_unread);
+	}
+	return records_unread;
+}
+
+ssize_t lib_ring_buffer_file_splice_read(struct file *in, loff_t *ppos,
+					 struct pipe_inode_info *pipe,
+					 size_t len, unsigned int flags);
+loff_t lib_ring_buffer_no_llseek(struct file *file, loff_t offset, int origin);
+
+#endif /* _LINUX_RING_BUFFER_BACKEND_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/backend_internal.h b/drivers/staging/lttng/lib/ringbuffer/backend_internal.h
new file mode 100644
index 0000000..442f357
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/backend_internal.h
@@ -0,0 +1,449 @@
+#ifndef _LINUX_RING_BUFFER_BACKEND_INTERNAL_H
+#define _LINUX_RING_BUFFER_BACKEND_INTERNAL_H
+
+/*
+ * linux/ringbuffer/backend_internal.h
+ *
+ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer backend (internal helpers).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/config.h"
+#include "../../wrapper/ringbuffer/backend_types.h"
+#include "../../wrapper/ringbuffer/frontend_types.h"
+#include <linux/string.h>
+#include <linux/uaccess.h>
+
+/* Ring buffer backend API presented to the frontend */
+
+/* Ring buffer and channel backend create/free */
+
+int lib_ring_buffer_backend_create(struct lib_ring_buffer_backend *bufb,
+				   struct channel_backend *chan, int cpu);
+void channel_backend_unregister_notifiers(struct channel_backend *chanb);
+void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb);
+int channel_backend_init(struct channel_backend *chanb,
+			 const char *name,
+			 const struct lib_ring_buffer_config *config,
+			 void *priv, size_t subbuf_size,
+			 size_t num_subbuf);
+void channel_backend_free(struct channel_backend *chanb);
+
+void lib_ring_buffer_backend_reset(struct lib_ring_buffer_backend *bufb);
+void channel_backend_reset(struct channel_backend *chanb);
+
+int lib_ring_buffer_backend_init(void);
+void lib_ring_buffer_backend_exit(void);
+
+extern void _lib_ring_buffer_write(struct lib_ring_buffer_backend *bufb,
+				   size_t offset, const void *src, size_t len,
+				   ssize_t pagecpy);
+extern void _lib_ring_buffer_memset(struct lib_ring_buffer_backend *bufb,
+				    size_t offset, int c, size_t len,
+				    ssize_t pagecpy);
+extern void _lib_ring_buffer_copy_from_user(struct lib_ring_buffer_backend *bufb,
+					    size_t offset, const void *src,
+					    size_t len, ssize_t pagecpy);
+
+/*
+ * Subbuffer ID bits for overwrite mode. Need to fit within a single word to be
+ * exchanged atomically.
+ *
+ * Top half word, except lowest bit, belongs to "offset", which is used to keep
+ * to count the produced buffers.  For overwrite mode, this provides the
+ * consumer with the capacity to read subbuffers in order, handling the
+ * situation where producers would write up to 2^15 buffers (or 2^31 for 64-bit
+ * systems) concurrently with a single execution of get_subbuf (between offset
+ * sampling and subbuffer ID exchange).
+ */
+
+#define HALF_ULONG_BITS		(BITS_PER_LONG >> 1)
+
+#define SB_ID_OFFSET_SHIFT	(HALF_ULONG_BITS + 1)
+#define SB_ID_OFFSET_COUNT	(1UL << SB_ID_OFFSET_SHIFT)
+#define SB_ID_OFFSET_MASK	(~(SB_ID_OFFSET_COUNT - 1))
+/*
+ * Lowest bit of top word half belongs to noref. Used only for overwrite mode.
+ */
+#define SB_ID_NOREF_SHIFT	(SB_ID_OFFSET_SHIFT - 1)
+#define SB_ID_NOREF_COUNT	(1UL << SB_ID_NOREF_SHIFT)
+#define SB_ID_NOREF_MASK	SB_ID_NOREF_COUNT
+/*
+ * In overwrite mode: lowest half of word is used for index.
+ * Limit of 2^16 subbuffers per buffer on 32-bit, 2^32 on 64-bit.
+ * In producer-consumer mode: whole word used for index.
+ */
+#define SB_ID_INDEX_SHIFT	0
+#define SB_ID_INDEX_COUNT	(1UL << SB_ID_INDEX_SHIFT)
+#define SB_ID_INDEX_MASK	(SB_ID_NOREF_COUNT - 1)
+
+/*
+ * Construct the subbuffer id from offset, index and noref. Use only the index
+ * for producer-consumer mode (offset and noref are only used in overwrite
+ * mode).
+ */
+static inline
+unsigned long subbuffer_id(const struct lib_ring_buffer_config *config,
+			   unsigned long offset, unsigned long noref,
+			   unsigned long index)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		return (offset << SB_ID_OFFSET_SHIFT)
+		       | (noref << SB_ID_NOREF_SHIFT)
+		       | index;
+	else
+		return index;
+}
+
+/*
+ * Compare offset with the offset contained within id. Return 1 if the offset
+ * bits are identical, else 0.
+ */
+static inline
+int subbuffer_id_compare_offset(const struct lib_ring_buffer_config *config,
+				unsigned long id, unsigned long offset)
+{
+	return (id & SB_ID_OFFSET_MASK) == (offset << SB_ID_OFFSET_SHIFT);
+}
+
+static inline
+unsigned long subbuffer_id_get_index(const struct lib_ring_buffer_config *config,
+				     unsigned long id)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		return id & SB_ID_INDEX_MASK;
+	else
+		return id;
+}
+
+static inline
+unsigned long subbuffer_id_is_noref(const struct lib_ring_buffer_config *config,
+				    unsigned long id)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		return !!(id & SB_ID_NOREF_MASK);
+	else
+		return 1;
+}
+
+/*
+ * Only used by reader on subbuffer ID it has exclusive access to. No volatile
+ * needed.
+ */
+static inline
+void subbuffer_id_set_noref(const struct lib_ring_buffer_config *config,
+			    unsigned long *id)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		*id |= SB_ID_NOREF_MASK;
+}
+
+static inline
+void subbuffer_id_set_noref_offset(const struct lib_ring_buffer_config *config,
+				   unsigned long *id, unsigned long offset)
+{
+	unsigned long tmp;
+
+	if (config->mode == RING_BUFFER_OVERWRITE) {
+		tmp = *id;
+		tmp &= ~SB_ID_OFFSET_MASK;
+		tmp |= offset << SB_ID_OFFSET_SHIFT;
+		tmp |= SB_ID_NOREF_MASK;
+		/* Volatile store, read concurrently by readers. */
+		ACCESS_ONCE(*id) = tmp;
+	}
+}
+
+/* No volatile access, since already used locally */
+static inline
+void subbuffer_id_clear_noref(const struct lib_ring_buffer_config *config,
+			      unsigned long *id)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		*id &= ~SB_ID_NOREF_MASK;
+}
+
+/*
+ * For overwrite mode, cap the number of subbuffers per buffer to:
+ * 2^16 on 32-bit architectures
+ * 2^32 on 64-bit architectures
+ * This is required to fit in the index part of the ID. Return 0 on success,
+ * -EPERM on failure.
+ */
+static inline
+int subbuffer_id_check_index(const struct lib_ring_buffer_config *config,
+			     unsigned long num_subbuf)
+{
+	if (config->mode == RING_BUFFER_OVERWRITE)
+		return (num_subbuf > (1UL << HALF_ULONG_BITS)) ? -EPERM : 0;
+	else
+		return 0;
+}
+
+static inline
+void subbuffer_count_record(const struct lib_ring_buffer_config *config,
+			    struct lib_ring_buffer_backend *bufb,
+			    unsigned long idx)
+{
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id);
+	v_inc(config, &bufb->array[sb_bindex]->records_commit);
+}
+
+/*
+ * Reader has exclusive subbuffer access for record consumption. No need to
+ * perform the decrement atomically.
+ */
+static inline
+void subbuffer_consume_record(const struct lib_ring_buffer_config *config,
+			      struct lib_ring_buffer_backend *bufb)
+{
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id);
+	CHAN_WARN_ON(bufb->chan,
+		     !v_read(config, &bufb->array[sb_bindex]->records_unread));
+	/* Non-atomic decrement protected by exclusive subbuffer access */
+	_v_dec(config, &bufb->array[sb_bindex]->records_unread);
+	v_inc(config, &bufb->records_read);
+}
+
+static inline
+unsigned long subbuffer_get_records_count(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer_backend *bufb,
+				unsigned long idx)
+{
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id);
+	return v_read(config, &bufb->array[sb_bindex]->records_commit);
+}
+
+/*
+ * Must be executed at subbuffer delivery when the writer has _exclusive_
+ * subbuffer access. See ring_buffer_check_deliver() for details.
+ * ring_buffer_get_records_count() must be called to get the records count
+ * before this function, because it resets the records_commit count.
+ */
+static inline
+unsigned long subbuffer_count_records_overrun(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer_backend *bufb,
+				unsigned long idx)
+{
+	struct lib_ring_buffer_backend_pages *pages;
+	unsigned long overruns, sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id);
+	pages = bufb->array[sb_bindex];
+	overruns = v_read(config, &pages->records_unread);
+	v_set(config, &pages->records_unread,
+	      v_read(config, &pages->records_commit));
+	v_set(config, &pages->records_commit, 0);
+
+	return overruns;
+}
+
+static inline
+void subbuffer_set_data_size(const struct lib_ring_buffer_config *config,
+			     struct lib_ring_buffer_backend *bufb,
+			     unsigned long idx,
+			     unsigned long data_size)
+{
+	struct lib_ring_buffer_backend_pages *pages;
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id);
+	pages = bufb->array[sb_bindex];
+	pages->data_size = data_size;
+}
+
+static inline
+unsigned long subbuffer_get_read_data_size(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer_backend *bufb)
+{
+	struct lib_ring_buffer_backend_pages *pages;
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id);
+	pages = bufb->array[sb_bindex];
+	return pages->data_size;
+}
+
+static inline
+unsigned long subbuffer_get_data_size(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer_backend *bufb,
+				unsigned long idx)
+{
+	struct lib_ring_buffer_backend_pages *pages;
+	unsigned long sb_bindex;
+
+	sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id);
+	pages = bufb->array[sb_bindex];
+	return pages->data_size;
+}
+
+/**
+ * lib_ring_buffer_clear_noref - Clear the noref subbuffer flag, called by
+ *                               writer.
+ */
+static inline
+void lib_ring_buffer_clear_noref(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer_backend *bufb,
+				 unsigned long idx)
+{
+	unsigned long id, new_id;
+
+	if (config->mode != RING_BUFFER_OVERWRITE)
+		return;
+
+	/*
+	 * Performing a volatile access to read the sb_pages, because we want to
+	 * read a coherent version of the pointer and the associated noref flag.
+	 */
+	id = ACCESS_ONCE(bufb->buf_wsb[idx].id);
+	for (;;) {
+		/* This check is called on the fast path for each record. */
+		if (likely(!subbuffer_id_is_noref(config, id))) {
+			/*
+			 * Store after load dependency ordering the writes to
+			 * the subbuffer after load and test of the noref flag
+			 * matches the memory barrier implied by the cmpxchg()
+			 * in update_read_sb_index().
+			 */
+			return;	/* Already writing to this buffer */
+		}
+		new_id = id;
+		subbuffer_id_clear_noref(config, &new_id);
+		new_id = cmpxchg(&bufb->buf_wsb[idx].id, id, new_id);
+		if (likely(new_id == id))
+			break;
+		id = new_id;
+	}
+}
+
+/**
+ * lib_ring_buffer_set_noref_offset - Set the noref subbuffer flag and offset,
+ *                                    called by writer.
+ */
+static inline
+void lib_ring_buffer_set_noref_offset(const struct lib_ring_buffer_config *config,
+				      struct lib_ring_buffer_backend *bufb,
+				      unsigned long idx, unsigned long offset)
+{
+	if (config->mode != RING_BUFFER_OVERWRITE)
+		return;
+
+	/*
+	 * Because ring_buffer_set_noref() is only called by a single thread
+	 * (the one which updated the cc_sb value), there are no concurrent
+	 * updates to take care of: other writers have not updated cc_sb, so
+	 * they cannot set the noref flag, and concurrent readers cannot modify
+	 * the pointer because the noref flag is not set yet.
+	 * The smp_wmb() in ring_buffer_commit() takes care of ordering writes
+	 * to the subbuffer before this set noref operation.
+	 * subbuffer_set_noref() uses a volatile store to deal with concurrent
+	 * readers of the noref flag.
+	 */
+	CHAN_WARN_ON(bufb->chan,
+		     subbuffer_id_is_noref(config, bufb->buf_wsb[idx].id));
+	/*
+	 * Memory barrier that ensures counter stores are ordered before set
+	 * noref and offset.
+	 */
+	smp_mb();
+	subbuffer_id_set_noref_offset(config, &bufb->buf_wsb[idx].id, offset);
+}
+
+/**
+ * update_read_sb_index - Read-side subbuffer index update.
+ */
+static inline
+int update_read_sb_index(const struct lib_ring_buffer_config *config,
+			 struct lib_ring_buffer_backend *bufb,
+			 struct channel_backend *chanb,
+			 unsigned long consumed_idx,
+			 unsigned long consumed_count)
+{
+	unsigned long old_id, new_id;
+
+	if (config->mode == RING_BUFFER_OVERWRITE) {
+		/*
+		 * Exchange the target writer subbuffer with our own unused
+		 * subbuffer. No need to use ACCESS_ONCE() here to read the
+		 * old_wpage, because the value read will be confirmed by the
+		 * following cmpxchg().
+		 */
+		old_id = bufb->buf_wsb[consumed_idx].id;
+		if (unlikely(!subbuffer_id_is_noref(config, old_id)))
+			return -EAGAIN;
+		/*
+		 * Make sure the offset count we are expecting matches the one
+		 * indicated by the writer.
+		 */
+		if (unlikely(!subbuffer_id_compare_offset(config, old_id,
+							  consumed_count)))
+			return -EAGAIN;
+		CHAN_WARN_ON(bufb->chan,
+			     !subbuffer_id_is_noref(config, bufb->buf_rsb.id));
+		subbuffer_id_set_noref_offset(config, &bufb->buf_rsb.id,
+					      consumed_count);
+		new_id = cmpxchg(&bufb->buf_wsb[consumed_idx].id, old_id,
+				 bufb->buf_rsb.id);
+		if (unlikely(old_id != new_id))
+			return -EAGAIN;
+		bufb->buf_rsb.id = new_id;
+	} else {
+		/* No page exchange, use the writer page directly */
+		bufb->buf_rsb.id = bufb->buf_wsb[consumed_idx].id;
+	}
+	return 0;
+}
+
+/*
+ * Use the architecture-specific memcpy implementation for constant-sized
+ * inputs, but rely on an inline memcpy for length statically unknown.
+ * The function call to memcpy is just way too expensive for a fast path.
+ */
+#define lib_ring_buffer_do_copy(config, dest, src, len)		\
+do {								\
+	size_t __len = (len);					\
+	if (__builtin_constant_p(len))				\
+		memcpy(dest, src, __len);			\
+	else							\
+		inline_memcpy(dest, src, __len);		\
+} while (0)
+
+/*
+ * We use __copy_from_user to copy userspace data since we already
+ * did the access_ok for the whole range.
+ */
+static inline
+unsigned long lib_ring_buffer_do_copy_from_user(void *dest,
+						const void __user *src,
+						unsigned long len)
+{
+	return __copy_from_user(dest, src, len);
+}
+
+/*
+ * write len bytes to dest with c
+ */
+static inline
+void lib_ring_buffer_do_memset(char *dest, int c,
+	unsigned long len)
+{
+	unsigned long i;
+
+	for (i = 0; i < len; i++)
+		dest[i] = c;
+}
+
+#endif /* _LINUX_RING_BUFFER_BACKEND_INTERNAL_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/backend_types.h b/drivers/staging/lttng/lib/ringbuffer/backend_types.h
new file mode 100644
index 0000000..1d301de
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/backend_types.h
@@ -0,0 +1,80 @@
+#ifndef _LINUX_RING_BUFFER_BACKEND_TYPES_H
+#define _LINUX_RING_BUFFER_BACKEND_TYPES_H
+
+/*
+ * linux/ringbuffer/backend_types.h
+ *
+ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer backend (types).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/types.h>
+
+struct lib_ring_buffer_backend_page {
+	void *virt;			/* page virtual address (cached) */
+	struct page *page;		/* pointer to page structure */
+};
+
+struct lib_ring_buffer_backend_pages {
+	unsigned long mmap_offset;	/* offset of the subbuffer in mmap */
+	union v_atomic records_commit;	/* current records committed count */
+	union v_atomic records_unread;	/* records to read */
+	unsigned long data_size;	/* Amount of data to read from subbuf */
+	struct lib_ring_buffer_backend_page p[];
+};
+
+struct lib_ring_buffer_backend_subbuffer {
+	/* Identifier for subbuf backend pages. Exchanged atomically. */
+	unsigned long id;		/* backend subbuffer identifier */
+};
+
+/*
+ * Forward declaration of frontend-specific channel and ring_buffer.
+ */
+struct channel;
+struct lib_ring_buffer;
+
+struct lib_ring_buffer_backend {
+	/* Array of ring_buffer_backend_subbuffer for writer */
+	struct lib_ring_buffer_backend_subbuffer *buf_wsb;
+	/* ring_buffer_backend_subbuffer for reader */
+	struct lib_ring_buffer_backend_subbuffer buf_rsb;
+	/*
+	 * Pointer array of backend pages, for whole buffer.
+	 * Indexed by ring_buffer_backend_subbuffer identifier (id) index.
+	 */
+	struct lib_ring_buffer_backend_pages **array;
+	unsigned int num_pages_per_subbuf;
+
+	struct channel *chan;		/* Associated channel */
+	int cpu;			/* This buffer's cpu. -1 if global. */
+	union v_atomic records_read;	/* Number of records read */
+	unsigned int allocated:1;	/* Bool: is buffer allocated ? */
+};
+
+struct channel_backend {
+	unsigned long buf_size;		/* Size of the buffer */
+	unsigned long subbuf_size;	/* Sub-buffer size */
+	unsigned int subbuf_size_order;	/* Order of sub-buffer size */
+	unsigned int num_subbuf_order;	/*
+					 * Order of number of sub-buffers/buffer
+					 * for writer.
+					 */
+	unsigned int buf_size_order;	/* Order of buffer size */
+	int extra_reader_sb:1;		/* Bool: has extra reader subbuffer */
+	struct lib_ring_buffer *buf;	/* Channel per-cpu buffers */
+
+	unsigned long num_subbuf;	/* Number of sub-buffers for writer */
+	u64 start_tsc;			/* Channel creation TSC value */
+	void *priv;			/* Client-specific information */
+	struct notifier_block cpu_hp_notifier;	 /* CPU hotplug notifier */
+	const struct lib_ring_buffer_config *config; /* Ring buffer configuration */
+	cpumask_var_t cpumask;		/* Allocated per-cpu buffers cpumask */
+	char name[NAME_MAX];		/* Channel name */
+};
+
+#endif /* _LINUX_RING_BUFFER_BACKEND_TYPES_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/config.h b/drivers/staging/lttng/lib/ringbuffer/config.h
new file mode 100644
index 0000000..fd73d55
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/config.h
@@ -0,0 +1,298 @@
+#ifndef _LINUX_RING_BUFFER_CONFIG_H
+#define _LINUX_RING_BUFFER_CONFIG_H
+
+/*
+ * linux/ringbuffer/config.h
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer configuration header. Note: after declaring the standard inline
+ * functions, clients should also include linux/ringbuffer/api.h.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include "../align.h"
+
+struct lib_ring_buffer;
+struct channel;
+struct lib_ring_buffer_config;
+struct lib_ring_buffer_ctx;
+
+/*
+ * Ring buffer client callbacks. Only used by slow path, never on fast path.
+ * For the fast path, record_header_size(), ring_buffer_clock_read() should be
+ * provided as inline functions too.  These may simply return 0 if not used by
+ * the client.
+ */
+struct lib_ring_buffer_client_cb {
+	/* Mandatory callbacks */
+
+	/* A static inline version is also required for fast path */
+	u64 (*ring_buffer_clock_read) (struct channel *chan);
+	size_t (*record_header_size) (const struct lib_ring_buffer_config *config,
+				      struct channel *chan, size_t offset,
+				      size_t *pre_header_padding,
+				      struct lib_ring_buffer_ctx *ctx);
+
+	/* Slow path only, at subbuffer switch */
+	size_t (*subbuffer_header_size) (void);
+	void (*buffer_begin) (struct lib_ring_buffer *buf, u64 tsc,
+			      unsigned int subbuf_idx);
+	void (*buffer_end) (struct lib_ring_buffer *buf, u64 tsc,
+			    unsigned int subbuf_idx, unsigned long data_size);
+
+	/* Optional callbacks (can be set to NULL) */
+
+	/* Called at buffer creation/finalize */
+	int (*buffer_create) (struct lib_ring_buffer *buf, void *priv,
+			      int cpu, const char *name);
+	/*
+	 * Clients should guarantee that no new reader handle can be opened
+	 * after finalize.
+	 */
+	void (*buffer_finalize) (struct lib_ring_buffer *buf, void *priv, int cpu);
+
+	/*
+	 * Extract header length, payload length and timestamp from event
+	 * record. Used by buffer iterators. Timestamp is only used by channel
+	 * iterator.
+	 */
+	void (*record_get) (const struct lib_ring_buffer_config *config,
+			    struct channel *chan, struct lib_ring_buffer *buf,
+			    size_t offset, size_t *header_len,
+			    size_t *payload_len, u64 *timestamp);
+};
+
+/*
+ * Ring buffer instance configuration.
+ *
+ * Declare as "static const" within the client object to ensure the inline fast
+ * paths can be optimized.
+ *
+ * alloc/sync pairs:
+ *
+ * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_PER_CPU :
+ *   Per-cpu buffers with per-cpu synchronization. Tracing must be performed
+ *   with preemption disabled (lib_ring_buffer_get_cpu() and
+ *   lib_ring_buffer_put_cpu()).
+ *
+ * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_GLOBAL :
+ *   Per-cpu buffer with global synchronization. Tracing can be performed with
+ *   preemption enabled, statistically stays on the local buffers.
+ *
+ * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_PER_CPU :
+ *   Should only be used for buffers belonging to a single thread or protected
+ *   by mutual exclusion by the client. Note that periodical sub-buffer switch
+ *   should be disabled in this kind of configuration.
+ *
+ * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_GLOBAL :
+ *   Global shared buffer with global synchronization.
+ *
+ * wakeup:
+ *
+ * RING_BUFFER_WAKEUP_BY_TIMER uses per-cpu deferrable timers to poll the
+ * buffers and wake up readers if data is ready. Mainly useful for tracers which
+ * don't want to call into the wakeup code on the tracing path. Use in
+ * combination with "read_timer_interval" channel_create() argument.
+ *
+ * RING_BUFFER_WAKEUP_BY_WRITER directly wakes up readers when a subbuffer is
+ * ready to read. Lower latencies before the reader is woken up. Mainly suitable
+ * for drivers.
+ *
+ * RING_BUFFER_WAKEUP_NONE does not perform any wakeup whatsoever. The client
+ * has the responsibility to perform wakeups.
+ */
+struct lib_ring_buffer_config {
+	enum {
+		RING_BUFFER_ALLOC_PER_CPU,
+		RING_BUFFER_ALLOC_GLOBAL,
+	} alloc;
+	enum {
+		RING_BUFFER_SYNC_PER_CPU,	/* Wait-free */
+		RING_BUFFER_SYNC_GLOBAL,	/* Lock-free */
+	} sync;
+	enum {
+		RING_BUFFER_OVERWRITE,		/* Overwrite when buffer full */
+		RING_BUFFER_DISCARD,		/* Discard when buffer full */
+	} mode;
+	enum {
+		RING_BUFFER_SPLICE,
+		RING_BUFFER_MMAP,
+		RING_BUFFER_READ,		/* TODO */
+		RING_BUFFER_ITERATOR,
+		RING_BUFFER_NONE,
+	} output;
+	enum {
+		RING_BUFFER_PAGE,
+		RING_BUFFER_VMAP,		/* TODO */
+		RING_BUFFER_STATIC,		/* TODO */
+	} backend;
+	enum {
+		RING_BUFFER_NO_OOPS_CONSISTENCY,
+		RING_BUFFER_OOPS_CONSISTENCY,
+	} oops;
+	enum {
+		RING_BUFFER_IPI_BARRIER,
+		RING_BUFFER_NO_IPI_BARRIER,
+	} ipi;
+	enum {
+		RING_BUFFER_WAKEUP_BY_TIMER,	/* wake up performed by timer */
+		RING_BUFFER_WAKEUP_BY_WRITER,	/*
+						 * writer wakes up reader,
+						 * not lock-free
+						 * (takes spinlock).
+						 */
+	} wakeup;
+	/*
+	 * tsc_bits: timestamp bits saved at each record.
+	 *   0 and 64 disable the timestamp compression scheme.
+	 */
+	unsigned int tsc_bits;
+	struct lib_ring_buffer_client_cb cb;
+};
+
+/*
+ * ring buffer context
+ *
+ * Context passed to lib_ring_buffer_reserve(), lib_ring_buffer_commit(),
+ * lib_ring_buffer_try_discard_reserve(), lib_ring_buffer_align_ctx() and
+ * lib_ring_buffer_write().
+ */
+struct lib_ring_buffer_ctx {
+	/* input received by lib_ring_buffer_reserve(), saved here. */
+	struct channel *chan;		/* channel */
+	void *priv;			/* client private data */
+	size_t data_size;		/* size of payload */
+	int largest_align;		/*
+					 * alignment of the largest element
+					 * in the payload
+					 */
+	int cpu;			/* processor id */
+
+	/* output from lib_ring_buffer_reserve() */
+	struct lib_ring_buffer *buf;	/*
+					 * buffer corresponding to processor id
+					 * for this channel
+					 */
+	size_t slot_size;		/* size of the reserved slot */
+	unsigned long buf_offset;	/* offset following the record header */
+	unsigned long pre_offset;	/*
+					 * Initial offset position _before_
+					 * the record is written. Positioned
+					 * prior to record header alignment
+					 * padding.
+					 */
+	u64 tsc;			/* time-stamp counter value */
+	unsigned int rflags;		/* reservation flags */
+};
+
+/**
+ * lib_ring_buffer_ctx_init - initialize ring buffer context
+ * @ctx: ring buffer context to initialize
+ * @chan: channel
+ * @priv: client private data
+ * @data_size: size of record data payload
+ * @largest_align: largest alignment within data payload types
+ * @cpu: processor id
+ */
+static inline
+void lib_ring_buffer_ctx_init(struct lib_ring_buffer_ctx *ctx,
+			      struct channel *chan, void *priv,
+			      size_t data_size, int largest_align,
+			      int cpu)
+{
+	ctx->chan = chan;
+	ctx->priv = priv;
+	ctx->data_size = data_size;
+	ctx->largest_align = largest_align;
+	ctx->cpu = cpu;
+	ctx->rflags = 0;
+}
+
+/*
+ * Reservation flags.
+ *
+ * RING_BUFFER_RFLAG_FULL_TSC
+ *
+ * This flag is passed to record_header_size() and to the primitive used to
+ * write the record header. It indicates that the full 64-bit time value is
+ * needed in the record header. If this flag is not set, the record header needs
+ * only to contain "tsc_bits" bit of time value.
+ *
+ * Reservation flags can be added by the client, starting from
+ * "(RING_BUFFER_FLAGS_END << 0)". It can be used to pass information from
+ * record_header_size() to lib_ring_buffer_write_record_header().
+ */
+#define	RING_BUFFER_RFLAG_FULL_TSC		(1U << 0)
+#define RING_BUFFER_RFLAG_END			(1U << 1)
+
+/*
+ * We need to define RING_BUFFER_ALIGN_ATTR so it is known early at
+ * compile-time. We have to duplicate the "config->align" information and the
+ * definition here because config->align is used both in the slow and fast
+ * paths, but RING_BUFFER_ALIGN_ATTR is only available for the client code.
+ */
+#ifdef RING_BUFFER_ALIGN
+
+# define RING_BUFFER_ALIGN_ATTR		/* Default arch alignment */
+
+/*
+ * Calculate the offset needed to align the type.
+ * size_of_type must be non-zero.
+ */
+static inline
+unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type)
+{
+	return offset_align(align_drift, size_of_type);
+}
+
+#else
+
+# define RING_BUFFER_ALIGN_ATTR __attribute__((packed))
+
+/*
+ * Calculate the offset needed to align the type.
+ * size_of_type must be non-zero.
+ */
+static inline
+unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type)
+{
+	return 0;
+}
+
+#endif
+
+/**
+ * lib_ring_buffer_align_ctx - Align context offset on "alignment"
+ * @ctx: ring buffer context.
+ */
+static inline
+void lib_ring_buffer_align_ctx(struct lib_ring_buffer_ctx *ctx,
+			   size_t alignment)
+{
+	ctx->buf_offset += lib_ring_buffer_align(ctx->buf_offset,
+						 alignment);
+}
+
+/*
+ * lib_ring_buffer_check_config() returns 0 on success.
+ * Used internally to check for valid configurations at channel creation.
+ */
+static inline
+int lib_ring_buffer_check_config(const struct lib_ring_buffer_config *config,
+			     unsigned int switch_timer_interval,
+			     unsigned int read_timer_interval)
+{
+	if (config->alloc == RING_BUFFER_ALLOC_GLOBAL
+	    && config->sync == RING_BUFFER_SYNC_PER_CPU
+	    && switch_timer_interval)
+		return -EINVAL;
+	return 0;
+}
+
+#include "../../wrapper/ringbuffer/vatomic.h"
+
+#endif /* _LINUX_RING_BUFFER_CONFIG_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend.h b/drivers/staging/lttng/lib/ringbuffer/frontend.h
new file mode 100644
index 0000000..01af77a
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/frontend.h
@@ -0,0 +1,228 @@
+#ifndef _LINUX_RING_BUFFER_FRONTEND_H
+#define _LINUX_RING_BUFFER_FRONTEND_H
+
+/*
+ * linux/ringbuffer/frontend.h
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring Buffer Library Synchronization Header (API).
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * See ring_buffer_frontend.c for more information on wait-free algorithms.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/pipe_fs_i.h>
+#include <linux/rcupdate.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/splice.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/cache.h>
+#include <linux/time.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/cpu.h>
+#include <linux/fs.h>
+
+#include <asm/atomic.h>
+#include <asm/local.h>
+
+/* Internal helpers */
+#include "../../wrapper/ringbuffer/frontend_internal.h"
+
+/* Buffer creation/removal and setup operations */
+
+/*
+ * switch_timer_interval is the time interval (in us) to fill sub-buffers with
+ * padding to let readers get those sub-buffers.  Used for live streaming.
+ *
+ * read_timer_interval is the time interval (in us) to wake up pending readers.
+ *
+ * buf_addr is a pointer the the beginning of the preallocated buffer contiguous
+ * address mapping. It is used only by RING_BUFFER_STATIC configuration. It can
+ * be set to NULL for other backends.
+ */
+
+extern
+struct channel *channel_create(const struct lib_ring_buffer_config *config,
+			       const char *name, void *priv,
+			       void *buf_addr,
+			       size_t subbuf_size, size_t num_subbuf,
+			       unsigned int switch_timer_interval,
+			       unsigned int read_timer_interval);
+
+/*
+ * channel_destroy returns the private data pointer. It finalizes all channel's
+ * buffers, waits for readers to release all references, and destroys the
+ * channel.
+ */
+extern
+void *channel_destroy(struct channel *chan);
+
+
+/* Buffer read operations */
+
+/*
+ * Iteration on channel cpumask needs to issue a read barrier to match the write
+ * barrier in cpu hotplug. It orders the cpumask read before read of per-cpu
+ * buffer data. The per-cpu buffer is never removed by cpu hotplug; teardown is
+ * only performed at channel destruction.
+ */
+#define for_each_channel_cpu(cpu, chan)					\
+	for ((cpu) = -1;						\
+		({ (cpu) = cpumask_next(cpu, (chan)->backend.cpumask);	\
+		   smp_read_barrier_depends(); (cpu) < nr_cpu_ids; });)
+
+extern struct lib_ring_buffer *channel_get_ring_buffer(
+				const struct lib_ring_buffer_config *config,
+				struct channel *chan, int cpu);
+extern int lib_ring_buffer_open_read(struct lib_ring_buffer *buf);
+extern void lib_ring_buffer_release_read(struct lib_ring_buffer *buf);
+
+/*
+ * Read sequence: snapshot, many get_subbuf/put_subbuf, move_consumer.
+ */
+extern int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf,
+				    unsigned long *consumed,
+				    unsigned long *produced);
+extern void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf,
+					  unsigned long consumed_new);
+
+extern int lib_ring_buffer_get_subbuf(struct lib_ring_buffer *buf,
+				      unsigned long consumed);
+extern void lib_ring_buffer_put_subbuf(struct lib_ring_buffer *buf);
+
+/*
+ * lib_ring_buffer_get_next_subbuf/lib_ring_buffer_put_next_subbuf are helpers
+ * to read sub-buffers sequentially.
+ */
+static inline int lib_ring_buffer_get_next_subbuf(struct lib_ring_buffer *buf)
+{
+	int ret;
+
+	ret = lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
+				       &buf->prod_snapshot);
+	if (ret)
+		return ret;
+	ret = lib_ring_buffer_get_subbuf(buf, buf->cons_snapshot);
+	return ret;
+}
+
+static inline void lib_ring_buffer_put_next_subbuf(struct lib_ring_buffer *buf)
+{
+	lib_ring_buffer_put_subbuf(buf);
+	lib_ring_buffer_move_consumer(buf, subbuf_align(buf->cons_snapshot,
+						    buf->backend.chan));
+}
+
+extern void channel_reset(struct channel *chan);
+extern void lib_ring_buffer_reset(struct lib_ring_buffer *buf);
+
+static inline
+unsigned long lib_ring_buffer_get_offset(const struct lib_ring_buffer_config *config,
+					 struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->offset);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_consumed(const struct lib_ring_buffer_config *config,
+					   struct lib_ring_buffer *buf)
+{
+	return atomic_long_read(&buf->consumed);
+}
+
+/*
+ * Must call lib_ring_buffer_is_finalized before reading counters (memory
+ * ordering enforced with respect to trace teardown).
+ */
+static inline
+int lib_ring_buffer_is_finalized(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer *buf)
+{
+	int finalized = ACCESS_ONCE(buf->finalized);
+	/*
+	 * Read finalized before counters.
+	 */
+	smp_rmb();
+	return finalized;
+}
+
+static inline
+int lib_ring_buffer_channel_is_finalized(const struct channel *chan)
+{
+	return chan->finalized;
+}
+
+static inline
+int lib_ring_buffer_channel_is_disabled(const struct channel *chan)
+{
+	return atomic_read(&chan->record_disabled);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_read_data_size(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return subbuffer_get_read_data_size(config, &buf->backend);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_count(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->records_count);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_overrun(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->records_overrun);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_lost_full(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->records_lost_full);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_lost_wrap(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->records_lost_wrap);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_lost_big(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->records_lost_big);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_records_read(
+				const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer *buf)
+{
+	return v_read(config, &buf->backend.records_read);
+}
+
+#endif /* _LINUX_RING_BUFFER_FRONTEND_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_api.h b/drivers/staging/lttng/lib/ringbuffer/frontend_api.h
new file mode 100644
index 0000000..391e593
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/frontend_api.h
@@ -0,0 +1,358 @@
+#ifndef _LINUX_RING_BUFFER_FRONTEND_API_H
+#define _LINUX_RING_BUFFER_FRONTEND_API_H
+
+/*
+ * linux/ringbuffer/frontend_api.h
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring Buffer Library Synchronization Header (buffer write API).
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * See ring_buffer_frontend.c for more information on wait-free algorithms.
+ * See linux/ringbuffer/frontend.h for channel allocation and read-side API.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/frontend.h"
+#include <linux/errno.h>
+
+/**
+ * lib_ring_buffer_get_cpu - Precedes ring buffer reserve/commit.
+ *
+ * Disables preemption (acts as a RCU read-side critical section) and keeps a
+ * ring buffer nesting count as supplementary safety net to ensure tracer client
+ * code will never trigger an endless recursion. Returns the processor ID on
+ * success, -EPERM on failure (nesting count too high).
+ *
+ * asm volatile and "memory" clobber prevent the compiler from moving
+ * instructions out of the ring buffer nesting count. This is required to ensure
+ * that probe side-effects which can cause recursion (e.g. unforeseen traps,
+ * divisions by 0, ...) are triggered within the incremented nesting count
+ * section.
+ */
+static inline
+int lib_ring_buffer_get_cpu(const struct lib_ring_buffer_config *config)
+{
+	int cpu, nesting;
+
+	rcu_read_lock_sched_notrace();
+	cpu = smp_processor_id();
+	nesting = ++per_cpu(lib_ring_buffer_nesting, cpu);
+	barrier();
+
+	if (unlikely(nesting > 4)) {
+		WARN_ON_ONCE(1);
+		per_cpu(lib_ring_buffer_nesting, cpu)--;
+		rcu_read_unlock_sched_notrace();
+		return -EPERM;
+	} else
+		return cpu;
+}
+
+/**
+ * lib_ring_buffer_put_cpu - Follows ring buffer reserve/commit.
+ */
+static inline
+void lib_ring_buffer_put_cpu(const struct lib_ring_buffer_config *config)
+{
+	barrier();
+	__get_cpu_var(lib_ring_buffer_nesting)--;
+	rcu_read_unlock_sched_notrace();
+}
+
+/*
+ * lib_ring_buffer_try_reserve is called by lib_ring_buffer_reserve(). It is not
+ * part of the API per se.
+ *
+ * returns 0 if reserve ok, or 1 if the slow path must be taken.
+ */
+static inline
+int lib_ring_buffer_try_reserve(const struct lib_ring_buffer_config *config,
+				struct lib_ring_buffer_ctx *ctx,
+				unsigned long *o_begin, unsigned long *o_end,
+				unsigned long *o_old, size_t *before_hdr_pad)
+{
+	struct channel *chan = ctx->chan;
+	struct lib_ring_buffer *buf = ctx->buf;
+	*o_begin = v_read(config, &buf->offset);
+	*o_old = *o_begin;
+
+	ctx->tsc = lib_ring_buffer_clock_read(chan);
+	if ((int64_t) ctx->tsc == -EIO)
+		return 1;
+
+	/*
+	 * Prefetch cacheline for read because we have to read the previous
+	 * commit counter to increment it and commit seq value to compare it to
+	 * the commit counter.
+	 */
+	prefetch(&buf->commit_hot[subbuf_index(*o_begin, chan)]);
+
+	if (last_tsc_overflow(config, buf, ctx->tsc))
+		ctx->rflags |= RING_BUFFER_RFLAG_FULL_TSC;
+
+	if (unlikely(subbuf_offset(*o_begin, chan) == 0))
+		return 1;
+
+	ctx->slot_size = record_header_size(config, chan, *o_begin,
+					    before_hdr_pad, ctx);
+	ctx->slot_size +=
+		lib_ring_buffer_align(*o_begin + ctx->slot_size,
+				      ctx->largest_align) + ctx->data_size;
+	if (unlikely((subbuf_offset(*o_begin, chan) + ctx->slot_size)
+		     > chan->backend.subbuf_size))
+		return 1;
+
+	/*
+	 * Record fits in the current buffer and we are not on a switch
+	 * boundary. It's safe to write.
+	 */
+	*o_end = *o_begin + ctx->slot_size;
+
+	if (unlikely((subbuf_offset(*o_end, chan)) == 0))
+		/*
+		 * The offset_end will fall at the very beginning of the next
+		 * subbuffer.
+		 */
+		return 1;
+
+	return 0;
+}
+
+/**
+ * lib_ring_buffer_reserve - Reserve space in a ring buffer.
+ * @config: ring buffer instance configuration.
+ * @ctx: ring buffer context. (input and output) Must be already initialized.
+ *
+ * Atomic wait-free slot reservation. The reserved space starts at the context
+ * "pre_offset". Its length is "slot_size". The associated time-stamp is "tsc".
+ *
+ * Return :
+ *  0 on success.
+ * -EAGAIN if channel is disabled.
+ * -ENOSPC if event size is too large for packet.
+ * -ENOBUFS if there is currently not enough space in buffer for the event.
+ * -EIO if data cannot be written into the buffer for any other reason.
+ */
+
+static inline
+int lib_ring_buffer_reserve(const struct lib_ring_buffer_config *config,
+			    struct lib_ring_buffer_ctx *ctx)
+{
+	struct channel *chan = ctx->chan;
+	struct lib_ring_buffer *buf;
+	unsigned long o_begin, o_end, o_old;
+	size_t before_hdr_pad = 0;
+
+	if (atomic_read(&chan->record_disabled))
+		return -EAGAIN;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		buf = per_cpu_ptr(chan->backend.buf, ctx->cpu);
+	else
+		buf = chan->backend.buf;
+	if (atomic_read(&buf->record_disabled))
+		return -EAGAIN;
+	ctx->buf = buf;
+
+	/*
+	 * Perform retryable operations.
+	 */
+	if (unlikely(lib_ring_buffer_try_reserve(config, ctx, &o_begin,
+						 &o_end, &o_old, &before_hdr_pad)))
+		goto slow_path;
+
+	if (unlikely(v_cmpxchg(config, &ctx->buf->offset, o_old, o_end)
+		     != o_old))
+		goto slow_path;
+
+	/*
+	 * Atomically update last_tsc. This update races against concurrent
+	 * atomic updates, but the race will always cause supplementary full TSC
+	 * record headers, never the opposite (missing a full TSC record header
+	 * when it would be needed).
+	 */
+	save_last_tsc(config, ctx->buf, ctx->tsc);
+
+	/*
+	 * Push the reader if necessary
+	 */
+	lib_ring_buffer_reserve_push_reader(ctx->buf, chan, o_end - 1);
+
+	/*
+	 * Clear noref flag for this subbuffer.
+	 */
+	lib_ring_buffer_clear_noref(config, &ctx->buf->backend,
+				subbuf_index(o_end - 1, chan));
+
+	ctx->pre_offset = o_begin;
+	ctx->buf_offset = o_begin + before_hdr_pad;
+	return 0;
+slow_path:
+	return lib_ring_buffer_reserve_slow(ctx);
+}
+
+/**
+ * lib_ring_buffer_switch - Perform a sub-buffer switch for a per-cpu buffer.
+ * @config: ring buffer instance configuration.
+ * @buf: buffer
+ * @mode: buffer switch mode (SWITCH_ACTIVE or SWITCH_FLUSH)
+ *
+ * This operation is completely reentrant : can be called while tracing is
+ * active with absolutely no lock held.
+ *
+ * Note, however, that as a v_cmpxchg is used for some atomic operations and
+ * requires to be executed locally for per-CPU buffers, this function must be
+ * called from the CPU which owns the buffer for a ACTIVE flush, with preemption
+ * disabled, for RING_BUFFER_SYNC_PER_CPU configuration.
+ */
+static inline
+void lib_ring_buffer_switch(const struct lib_ring_buffer_config *config,
+			    struct lib_ring_buffer *buf, enum switch_mode mode)
+{
+	lib_ring_buffer_switch_slow(buf, mode);
+}
+
+/* See ring_buffer_frontend_api.h for lib_ring_buffer_reserve(). */
+
+/**
+ * lib_ring_buffer_commit - Commit an record.
+ * @config: ring buffer instance configuration.
+ * @ctx: ring buffer context. (input arguments only)
+ *
+ * Atomic unordered slot commit. Increments the commit count in the
+ * specified sub-buffer, and delivers it if necessary.
+ */
+static inline
+void lib_ring_buffer_commit(const struct lib_ring_buffer_config *config,
+			    const struct lib_ring_buffer_ctx *ctx)
+{
+	struct channel *chan = ctx->chan;
+	struct lib_ring_buffer *buf = ctx->buf;
+	unsigned long offset_end = ctx->buf_offset;
+	unsigned long endidx = subbuf_index(offset_end - 1, chan);
+	unsigned long commit_count;
+
+	/*
+	 * Must count record before incrementing the commit count.
+	 */
+	subbuffer_count_record(config, &buf->backend, endidx);
+
+	/*
+	 * Order all writes to buffer before the commit count update that will
+	 * determine that the subbuffer is full.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		/*
+		 * Must write slot data before incrementing commit count.  This
+		 * compiler barrier is upgraded into a smp_mb() by the IPI sent
+		 * by get_subbuf().
+		 */
+		barrier();
+	} else
+		smp_wmb();
+
+	v_add(config, ctx->slot_size, &buf->commit_hot[endidx].cc);
+
+	/*
+	 * commit count read can race with concurrent OOO commit count updates.
+	 * This is only needed for lib_ring_buffer_check_deliver (for
+	 * non-polling delivery only) and for
+	 * lib_ring_buffer_write_commit_counter.  The race can only cause the
+	 * counter to be read with the same value more than once, which could
+	 * cause :
+	 * - Multiple delivery for the same sub-buffer (which is handled
+	 *   gracefully by the reader code) if the value is for a full
+	 *   sub-buffer. It's important that we can never miss a sub-buffer
+	 *   delivery. Re-reading the value after the v_add ensures this.
+	 * - Reading a commit_count with a higher value that what was actually
+	 *   added to it for the lib_ring_buffer_write_commit_counter call
+	 *   (again caused by a concurrent committer). It does not matter,
+	 *   because this function is interested in the fact that the commit
+	 *   count reaches back the reserve offset for a specific sub-buffer,
+	 *   which is completely independent of the order.
+	 */
+	commit_count = v_read(config, &buf->commit_hot[endidx].cc);
+
+	lib_ring_buffer_check_deliver(config, buf, chan, offset_end - 1,
+				      commit_count, endidx);
+	/*
+	 * Update used size at each commit. It's needed only for extracting
+	 * ring_buffer buffers from vmcore, after crash.
+	 */
+	lib_ring_buffer_write_commit_counter(config, buf, chan, endidx,
+					     ctx->buf_offset, commit_count,
+					 ctx->slot_size);
+}
+
+/**
+ * lib_ring_buffer_try_discard_reserve - Try discarding a record.
+ * @config: ring buffer instance configuration.
+ * @ctx: ring buffer context. (input arguments only)
+ *
+ * Only succeeds if no other record has been written after the record to
+ * discard. If discard fails, the record must be committed to the buffer.
+ *
+ * Returns 0 upon success, -EPERM if the record cannot be discarded.
+ */
+static inline
+int lib_ring_buffer_try_discard_reserve(const struct lib_ring_buffer_config *config,
+					const struct lib_ring_buffer_ctx *ctx)
+{
+	struct lib_ring_buffer *buf = ctx->buf;
+	unsigned long end_offset = ctx->pre_offset + ctx->slot_size;
+
+	/*
+	 * We need to ensure that if the cmpxchg succeeds and discards the
+	 * record, the next record will record a full TSC, because it cannot
+	 * rely on the last_tsc associated with the discarded record to detect
+	 * overflows. The only way to ensure this is to set the last_tsc to 0
+	 * (assuming no 64-bit TSC overflow), which forces to write a 64-bit
+	 * timestamp in the next record.
+	 *
+	 * Note: if discard fails, we must leave the TSC in the record header.
+	 * It is needed to keep track of TSC overflows for the following
+	 * records.
+	 */
+	save_last_tsc(config, buf, 0ULL);
+
+	if (likely(v_cmpxchg(config, &buf->offset, end_offset, ctx->pre_offset)
+		   != end_offset))
+		return -EPERM;
+	else
+		return 0;
+}
+
+static inline
+void channel_record_disable(const struct lib_ring_buffer_config *config,
+			    struct channel *chan)
+{
+	atomic_inc(&chan->record_disabled);
+}
+
+static inline
+void channel_record_enable(const struct lib_ring_buffer_config *config,
+			   struct channel *chan)
+{
+	atomic_dec(&chan->record_disabled);
+}
+
+static inline
+void lib_ring_buffer_record_disable(const struct lib_ring_buffer_config *config,
+				    struct lib_ring_buffer *buf)
+{
+	atomic_inc(&buf->record_disabled);
+}
+
+static inline
+void lib_ring_buffer_record_enable(const struct lib_ring_buffer_config *config,
+				   struct lib_ring_buffer *buf)
+{
+	atomic_dec(&buf->record_disabled);
+}
+
+#endif /* _LINUX_RING_BUFFER_FRONTEND_API_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h b/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h
new file mode 100644
index 0000000..3bd5721
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h
@@ -0,0 +1,424 @@
+#ifndef _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H
+#define _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H
+
+/*
+ * linux/ringbuffer/frontend_internal.h
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring Buffer Library Synchronization Header (internal helpers).
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * See ring_buffer_frontend.c for more information on wait-free algorithms.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/config.h"
+#include "../../wrapper/ringbuffer/backend_types.h"
+#include "../../wrapper/ringbuffer/frontend_types.h"
+#include "../../lib/prio_heap/lttng_prio_heap.h"	/* For per-CPU read-side iterator */
+
+/* Buffer offset macros */
+
+/* buf_trunc mask selects only the buffer number. */
+static inline
+unsigned long buf_trunc(unsigned long offset, struct channel *chan)
+{
+	return offset & ~(chan->backend.buf_size - 1);
+
+}
+
+/* Select the buffer number value (counter). */
+static inline
+unsigned long buf_trunc_val(unsigned long offset, struct channel *chan)
+{
+	return buf_trunc(offset, chan) >> chan->backend.buf_size_order;
+}
+
+/* buf_offset mask selects only the offset within the current buffer. */
+static inline
+unsigned long buf_offset(unsigned long offset, struct channel *chan)
+{
+	return offset & (chan->backend.buf_size - 1);
+}
+
+/* subbuf_offset mask selects the offset within the current subbuffer. */
+static inline
+unsigned long subbuf_offset(unsigned long offset, struct channel *chan)
+{
+	return offset & (chan->backend.subbuf_size - 1);
+}
+
+/* subbuf_trunc mask selects the subbuffer number. */
+static inline
+unsigned long subbuf_trunc(unsigned long offset, struct channel *chan)
+{
+	return offset & ~(chan->backend.subbuf_size - 1);
+}
+
+/* subbuf_align aligns the offset to the next subbuffer. */
+static inline
+unsigned long subbuf_align(unsigned long offset, struct channel *chan)
+{
+	return (offset + chan->backend.subbuf_size)
+	       & ~(chan->backend.subbuf_size - 1);
+}
+
+/* subbuf_index returns the index of the current subbuffer within the buffer. */
+static inline
+unsigned long subbuf_index(unsigned long offset, struct channel *chan)
+{
+	return buf_offset(offset, chan) >> chan->backend.subbuf_size_order;
+}
+
+/*
+ * Last TSC comparison functions. Check if the current TSC overflows tsc_bits
+ * bits from the last TSC read. When overflows are detected, the full 64-bit
+ * timestamp counter should be written in the record header. Reads and writes
+ * last_tsc atomically.
+ */
+
+#if (BITS_PER_LONG == 32)
+static inline
+void save_last_tsc(const struct lib_ring_buffer_config *config,
+		   struct lib_ring_buffer *buf, u64 tsc)
+{
+	if (config->tsc_bits == 0 || config->tsc_bits == 64)
+		return;
+
+	/*
+	 * Ensure the compiler performs this update in a single instruction.
+	 */
+	v_set(config, &buf->last_tsc, (unsigned long)(tsc >> config->tsc_bits));
+}
+
+static inline
+int last_tsc_overflow(const struct lib_ring_buffer_config *config,
+		      struct lib_ring_buffer *buf, u64 tsc)
+{
+	unsigned long tsc_shifted;
+
+	if (config->tsc_bits == 0 || config->tsc_bits == 64)
+		return 0;
+
+	tsc_shifted = (unsigned long)(tsc >> config->tsc_bits);
+	if (unlikely(tsc_shifted
+		     - (unsigned long)v_read(config, &buf->last_tsc)))
+		return 1;
+	else
+		return 0;
+}
+#else
+static inline
+void save_last_tsc(const struct lib_ring_buffer_config *config,
+		   struct lib_ring_buffer *buf, u64 tsc)
+{
+	if (config->tsc_bits == 0 || config->tsc_bits == 64)
+		return;
+
+	v_set(config, &buf->last_tsc, (unsigned long)tsc);
+}
+
+static inline
+int last_tsc_overflow(const struct lib_ring_buffer_config *config,
+		      struct lib_ring_buffer *buf, u64 tsc)
+{
+	if (config->tsc_bits == 0 || config->tsc_bits == 64)
+		return 0;
+
+	if (unlikely((tsc - v_read(config, &buf->last_tsc))
+		     >> config->tsc_bits))
+		return 1;
+	else
+		return 0;
+}
+#endif
+
+extern
+int lib_ring_buffer_reserve_slow(struct lib_ring_buffer_ctx *ctx);
+
+extern
+void lib_ring_buffer_switch_slow(struct lib_ring_buffer *buf,
+				 enum switch_mode mode);
+
+/* Buffer write helpers */
+
+static inline
+void lib_ring_buffer_reserve_push_reader(struct lib_ring_buffer *buf,
+					 struct channel *chan,
+					 unsigned long offset)
+{
+	unsigned long consumed_old, consumed_new;
+
+	do {
+		consumed_old = atomic_long_read(&buf->consumed);
+		/*
+		 * If buffer is in overwrite mode, push the reader consumed
+		 * count if the write position has reached it and we are not
+		 * at the first iteration (don't push the reader farther than
+		 * the writer). This operation can be done concurrently by many
+		 * writers in the same buffer, the writer being at the farthest
+		 * write position sub-buffer index in the buffer being the one
+		 * which will win this loop.
+		 */
+		if (unlikely(subbuf_trunc(offset, chan)
+			      - subbuf_trunc(consumed_old, chan)
+			     >= chan->backend.buf_size))
+			consumed_new = subbuf_align(consumed_old, chan);
+		else
+			return;
+	} while (unlikely(atomic_long_cmpxchg(&buf->consumed, consumed_old,
+					      consumed_new) != consumed_old));
+}
+
+static inline
+void lib_ring_buffer_vmcore_check_deliver(const struct lib_ring_buffer_config *config,
+					  struct lib_ring_buffer *buf,
+				          unsigned long commit_count,
+				          unsigned long idx)
+{
+	if (config->oops == RING_BUFFER_OOPS_CONSISTENCY)
+		v_set(config, &buf->commit_hot[idx].seq, commit_count);
+}
+
+static inline
+int lib_ring_buffer_poll_deliver(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer *buf,
+			         struct channel *chan)
+{
+	unsigned long consumed_old, consumed_idx, commit_count, write_offset;
+
+	consumed_old = atomic_long_read(&buf->consumed);
+	consumed_idx = subbuf_index(consumed_old, chan);
+	commit_count = v_read(config, &buf->commit_cold[consumed_idx].cc_sb);
+	/*
+	 * No memory barrier here, since we are only interested
+	 * in a statistically correct polling result. The next poll will
+	 * get the data is we are racing. The mb() that ensures correct
+	 * memory order is in get_subbuf.
+	 */
+	write_offset = v_read(config, &buf->offset);
+
+	/*
+	 * Check that the subbuffer we are trying to consume has been
+	 * already fully committed.
+	 */
+
+	if (((commit_count - chan->backend.subbuf_size)
+	     & chan->commit_count_mask)
+	    - (buf_trunc(consumed_old, chan)
+	       >> chan->backend.num_subbuf_order)
+	    != 0)
+		return 0;
+
+	/*
+	 * Check that we are not about to read the same subbuffer in
+	 * which the writer head is.
+	 */
+	if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_old, chan)
+	    == 0)
+		return 0;
+
+	return 1;
+
+}
+
+static inline
+int lib_ring_buffer_pending_data(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer *buf,
+				 struct channel *chan)
+{
+	return !!subbuf_offset(v_read(config, &buf->offset), chan);
+}
+
+static inline
+unsigned long lib_ring_buffer_get_data_size(const struct lib_ring_buffer_config *config,
+					    struct lib_ring_buffer *buf,
+					    unsigned long idx)
+{
+	return subbuffer_get_data_size(config, &buf->backend, idx);
+}
+
+/*
+ * Check if all space reservation in a buffer have been committed. This helps
+ * knowing if an execution context is nested (for per-cpu buffers only).
+ * This is a very specific ftrace use-case, so we keep this as "internal" API.
+ */
+static inline
+int lib_ring_buffer_reserve_committed(const struct lib_ring_buffer_config *config,
+				      struct lib_ring_buffer *buf,
+				      struct channel *chan)
+{
+	unsigned long offset, idx, commit_count;
+
+	CHAN_WARN_ON(chan, config->alloc != RING_BUFFER_ALLOC_PER_CPU);
+	CHAN_WARN_ON(chan, config->sync != RING_BUFFER_SYNC_PER_CPU);
+
+	/*
+	 * Read offset and commit count in a loop so they are both read
+	 * atomically wrt interrupts. By deal with interrupt concurrency by
+	 * restarting both reads if the offset has been pushed. Note that given
+	 * we only have to deal with interrupt concurrency here, an interrupt
+	 * modifying the commit count will also modify "offset", so it is safe
+	 * to only check for offset modifications.
+	 */
+	do {
+		offset = v_read(config, &buf->offset);
+		idx = subbuf_index(offset, chan);
+		commit_count = v_read(config, &buf->commit_hot[idx].cc);
+	} while (offset != v_read(config, &buf->offset));
+
+	return ((buf_trunc(offset, chan) >> chan->backend.num_subbuf_order)
+		     - (commit_count & chan->commit_count_mask) == 0);
+}
+
+static inline
+void lib_ring_buffer_check_deliver(const struct lib_ring_buffer_config *config,
+				   struct lib_ring_buffer *buf,
+			           struct channel *chan,
+			           unsigned long offset,
+				   unsigned long commit_count,
+			           unsigned long idx)
+{
+	unsigned long old_commit_count = commit_count
+					 - chan->backend.subbuf_size;
+	u64 tsc;
+
+	/* Check if all commits have been done */
+	if (unlikely((buf_trunc(offset, chan) >> chan->backend.num_subbuf_order)
+		     - (old_commit_count & chan->commit_count_mask) == 0)) {
+		/*
+		 * If we succeeded at updating cc_sb below, we are the subbuffer
+		 * writer delivering the subbuffer. Deals with concurrent
+		 * updates of the "cc" value without adding a add_return atomic
+		 * operation to the fast path.
+		 *
+		 * We are doing the delivery in two steps:
+		 * - First, we cmpxchg() cc_sb to the new value
+		 *   old_commit_count + 1. This ensures that we are the only
+		 *   subbuffer user successfully filling the subbuffer, but we
+		 *   do _not_ set the cc_sb value to "commit_count" yet.
+		 *   Therefore, other writers that would wrap around the ring
+		 *   buffer and try to start writing to our subbuffer would
+		 *   have to drop records, because it would appear as
+		 *   non-filled.
+		 *   We therefore have exclusive access to the subbuffer control
+		 *   structures.  This mutual exclusion with other writers is
+		 *   crucially important to perform record overruns count in
+		 *   flight recorder mode locklessly.
+		 * - When we are ready to release the subbuffer (either for
+		 *   reading or for overrun by other writers), we simply set the
+		 *   cc_sb value to "commit_count" and perform delivery.
+		 *
+		 * The subbuffer size is least 2 bytes (minimum size: 1 page).
+		 * This guarantees that old_commit_count + 1 != commit_count.
+		 */
+		if (likely(v_cmpxchg(config, &buf->commit_cold[idx].cc_sb,
+					 old_commit_count, old_commit_count + 1)
+			   == old_commit_count)) {
+			/*
+			 * Start of exclusive subbuffer access. We are
+			 * guaranteed to be the last writer in this subbuffer
+			 * and any other writer trying to access this subbuffer
+			 * in this state is required to drop records.
+			 */
+			tsc = config->cb.ring_buffer_clock_read(chan);
+			v_add(config,
+			      subbuffer_get_records_count(config,
+							  &buf->backend, idx),
+			      &buf->records_count);
+			v_add(config,
+			      subbuffer_count_records_overrun(config,
+							      &buf->backend,
+							      idx),
+			      &buf->records_overrun);
+			config->cb.buffer_end(buf, tsc, idx,
+					      lib_ring_buffer_get_data_size(config,
+									buf,
+									idx));
+
+			/*
+			 * Set noref flag and offset for this subbuffer id.
+			 * Contains a memory barrier that ensures counter stores
+			 * are ordered before set noref and offset.
+			 */
+			lib_ring_buffer_set_noref_offset(config, &buf->backend, idx,
+							 buf_trunc_val(offset, chan));
+
+			/*
+			 * Order set_noref and record counter updates before the
+			 * end of subbuffer exclusive access. Orders with
+			 * respect to writers coming into the subbuffer after
+			 * wrap around, and also order wrt concurrent readers.
+			 */
+			smp_mb();
+			/* End of exclusive subbuffer access */
+			v_set(config, &buf->commit_cold[idx].cc_sb,
+			      commit_count);
+			lib_ring_buffer_vmcore_check_deliver(config, buf,
+							 commit_count, idx);
+
+			/*
+			 * RING_BUFFER_WAKEUP_BY_WRITER wakeup is not lock-free.
+			 */
+			if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER
+			    && atomic_long_read(&buf->active_readers)
+			    && lib_ring_buffer_poll_deliver(config, buf, chan)) {
+				wake_up_interruptible(&buf->read_wait);
+				wake_up_interruptible(&chan->read_wait);
+			}
+
+		}
+	}
+}
+
+/*
+ * lib_ring_buffer_write_commit_counter
+ *
+ * For flight recording. must be called after commit.
+ * This function increments the subbuffer's commit_seq counter each time the
+ * commit count reaches back the reserve offset (modulo subbuffer size). It is
+ * useful for crash dump.
+ */
+static inline
+void lib_ring_buffer_write_commit_counter(const struct lib_ring_buffer_config *config,
+					  struct lib_ring_buffer *buf,
+				          struct channel *chan,
+				          unsigned long idx,
+				          unsigned long buf_offset,
+				          unsigned long commit_count,
+				          size_t slot_size)
+{
+	unsigned long offset, commit_seq_old;
+
+	if (config->oops != RING_BUFFER_OOPS_CONSISTENCY)
+		return;
+
+	offset = buf_offset + slot_size;
+
+	/*
+	 * subbuf_offset includes commit_count_mask. We can simply
+	 * compare the offsets within the subbuffer without caring about
+	 * buffer full/empty mismatch because offset is never zero here
+	 * (subbuffer header and record headers have non-zero length).
+	 */
+	if (unlikely(subbuf_offset(offset - commit_count, chan)))
+		return;
+
+	commit_seq_old = v_read(config, &buf->commit_hot[idx].seq);
+	while ((long) (commit_seq_old - commit_count) < 0)
+		commit_seq_old = v_cmpxchg(config, &buf->commit_hot[idx].seq,
+					   commit_seq_old, commit_count);
+}
+
+extern int lib_ring_buffer_create(struct lib_ring_buffer *buf,
+				  struct channel_backend *chanb, int cpu);
+extern void lib_ring_buffer_free(struct lib_ring_buffer *buf);
+
+/* Keep track of trap nesting inside ring buffer code */
+DECLARE_PER_CPU(unsigned int, lib_ring_buffer_nesting);
+
+#endif /* _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_types.h b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
new file mode 100644
index 0000000..5c7437f
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
@@ -0,0 +1,176 @@
+#ifndef _LINUX_RING_BUFFER_FRONTEND_TYPES_H
+#define _LINUX_RING_BUFFER_FRONTEND_TYPES_H
+
+/*
+ * linux/ringbuffer/frontend_types.h
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring Buffer Library Synchronization Header (types).
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * See ring_buffer_frontend.c for more information on wait-free algorithms.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/kref.h>
+#include "../../wrapper/ringbuffer/config.h"
+#include "../../wrapper/ringbuffer/backend_types.h"
+#include "../../wrapper/spinlock.h"
+#include "../../lib/prio_heap/lttng_prio_heap.h"	/* For per-CPU read-side iterator */
+
+/*
+ * A switch is done during tracing or as a final flush after tracing (so it
+ * won't write in the new sub-buffer).
+ */
+enum switch_mode { SWITCH_ACTIVE, SWITCH_FLUSH };
+
+/* channel-level read-side iterator */
+struct channel_iter {
+	/* Prio heap of buffers. Lowest timestamps at the top. */
+	struct lttng_ptr_heap heap;	/* Heap of struct lib_ring_buffer ptrs */
+	struct list_head empty_head;	/* Empty buffers linked-list head */
+	int read_open;			/* Opened for reading ? */
+	u64 last_qs;			/* Last quiescent state timestamp */
+	u64 last_timestamp;		/* Last timestamp (for WARN_ON) */
+	int last_cpu;			/* Last timestamp cpu */
+	/*
+	 * read() file operation state.
+	 */
+	unsigned long len_left;
+};
+
+/* channel: collection of per-cpu ring buffers. */
+struct channel {
+	atomic_t record_disabled;
+	unsigned long commit_count_mask;	/*
+						 * Commit count mask, removing
+						 * the MSBs corresponding to
+						 * bits used to represent the
+						 * subbuffer index.
+						 */
+
+	struct channel_backend backend;		/* Associated backend */
+
+	unsigned long switch_timer_interval;	/* Buffer flush (jiffies) */
+	unsigned long read_timer_interval;	/* Reader wakeup (jiffies) */
+	struct notifier_block cpu_hp_notifier;	/* CPU hotplug notifier */
+	struct notifier_block tick_nohz_notifier; /* CPU nohz notifier */
+	struct notifier_block hp_iter_notifier;	/* hotplug iterator notifier */
+	int cpu_hp_enable:1;			/* Enable CPU hotplug notif. */
+	int hp_iter_enable:1;			/* Enable hp iter notif. */
+	wait_queue_head_t read_wait;		/* reader wait queue */
+	wait_queue_head_t hp_wait;		/* CPU hotplug wait queue */
+	int finalized;				/* Has channel been finalized */
+	struct channel_iter iter;		/* Channel read-side iterator */
+	struct kref ref;			/* Reference count */
+};
+
+/* Per-subbuffer commit counters used on the hot path */
+struct commit_counters_hot {
+	union v_atomic cc;		/* Commit counter */
+	union v_atomic seq;		/* Consecutive commits */
+};
+
+/* Per-subbuffer commit counters used only on cold paths */
+struct commit_counters_cold {
+	union v_atomic cc_sb;		/* Incremented _once_ at sb switch */
+};
+
+/* Per-buffer read iterator */
+struct lib_ring_buffer_iter {
+	u64 timestamp;			/* Current record timestamp */
+	size_t header_len;		/* Current record header length */
+	size_t payload_len;		/* Current record payload length */
+
+	struct list_head empty_node;	/* Linked list of empty buffers */
+	unsigned long consumed, read_offset, data_size;
+	enum {
+		ITER_GET_SUBBUF = 0,
+		ITER_TEST_RECORD,
+		ITER_NEXT_RECORD,
+		ITER_PUT_SUBBUF,
+	} state;
+	int allocated:1;
+	int read_open:1;		/* Opened for reading ? */
+};
+
+/* ring buffer state */
+struct lib_ring_buffer {
+	/* First 32 bytes cache-hot cacheline */
+	union v_atomic offset;		/* Current offset in the buffer */
+	struct commit_counters_hot *commit_hot;
+					/* Commit count per sub-buffer */
+	atomic_long_t consumed;		/*
+					 * Current offset in the buffer
+					 * standard atomic access (shared)
+					 */
+	atomic_t record_disabled;
+	/* End of first 32 bytes cacheline */
+	union v_atomic last_tsc;	/*
+					 * Last timestamp written in the buffer.
+					 */
+
+	struct lib_ring_buffer_backend backend;	/* Associated backend */
+
+	struct commit_counters_cold *commit_cold;
+					/* Commit count per sub-buffer */
+	atomic_long_t active_readers;	/*
+					 * Active readers count
+					 * standard atomic access (shared)
+					 */
+					/* Dropped records */
+	union v_atomic records_lost_full;	/* Buffer full */
+	union v_atomic records_lost_wrap;	/* Nested wrap-around */
+	union v_atomic records_lost_big;	/* Events too big */
+	union v_atomic records_count;	/* Number of records written */
+	union v_atomic records_overrun;	/* Number of overwritten records */
+	wait_queue_head_t read_wait;	/* reader buffer-level wait queue */
+	wait_queue_head_t write_wait;	/* writer buffer-level wait queue (for metadata only) */
+	int finalized;			/* buffer has been finalized */
+	struct timer_list switch_timer;	/* timer for periodical switch */
+	struct timer_list read_timer;	/* timer for read poll */
+	raw_spinlock_t raw_tick_nohz_spinlock;	/* nohz entry lock/trylock */
+	struct lib_ring_buffer_iter iter;	/* read-side iterator */
+	unsigned long get_subbuf_consumed;	/* Read-side consumed */
+	unsigned long prod_snapshot;	/* Producer count snapshot */
+	unsigned long cons_snapshot;	/* Consumer count snapshot */
+	int get_subbuf:1;		/* Sub-buffer being held by reader */
+	int switch_timer_enabled:1;	/* Protected by ring_buffer_nohz_lock */
+	int read_timer_enabled:1;	/* Protected by ring_buffer_nohz_lock */
+};
+
+static inline
+void *channel_get_private(struct channel *chan)
+{
+	return chan->backend.priv;
+}
+
+/*
+ * Issue warnings and disable channels upon internal error.
+ * Can receive struct lib_ring_buffer or struct lib_ring_buffer_backend
+ * parameters.
+ */
+#define CHAN_WARN_ON(c, cond)						\
+	({								\
+		struct channel *__chan;					\
+		int _____ret = unlikely(cond);				\
+		if (_____ret) {						\
+			if (__same_type(*(c), struct channel_backend))	\
+				__chan = container_of((void *) (c),	\
+							struct channel, \
+							backend);	\
+			else if (__same_type(*(c), struct channel))	\
+				__chan = (void *) (c);			\
+			else						\
+				BUG_ON(1);				\
+			atomic_inc(&__chan->record_disabled);		\
+			WARN_ON(1);					\
+		}							\
+		_____ret;						\
+	})
+
+#endif /* _LINUX_RING_BUFFER_FRONTEND_TYPES_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/iterator.h b/drivers/staging/lttng/lib/ringbuffer/iterator.h
new file mode 100644
index 0000000..f2bd50d
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/iterator.h
@@ -0,0 +1,70 @@
+#ifndef _LINUX_RING_BUFFER_ITERATOR_H
+#define _LINUX_RING_BUFFER_ITERATOR_H
+
+/*
+ * linux/ringbuffer/iterator.h
+ *
+ * (C) Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer and channel iterators.
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+
+/*
+ * lib_ring_buffer_get_next_record advances the buffer read position to the next
+ * record. It returns either the size of the next record, -EAGAIN if there is
+ * currently no data available, or -ENODATA if no data is available and buffer
+ * is finalized.
+ */
+extern ssize_t lib_ring_buffer_get_next_record(struct channel *chan,
+					       struct lib_ring_buffer *buf);
+
+/*
+ * channel_get_next_record advances the buffer read position to the next record.
+ * It returns either the size of the next record, -EAGAIN if there is currently
+ * no data available, or -ENODATA if no data is available and buffer is
+ * finalized.
+ * Returns the current buffer in ret_buf.
+ */
+extern ssize_t channel_get_next_record(struct channel *chan,
+				       struct lib_ring_buffer **ret_buf);
+
+/**
+ * read_current_record - copy the buffer current record into dest.
+ * @buf: ring buffer
+ * @dest: destination where the record should be copied
+ *
+ * dest should be large enough to contain the record. Returns the number of
+ * bytes copied.
+ */
+static inline size_t read_current_record(struct lib_ring_buffer *buf, void *dest)
+{
+	return lib_ring_buffer_read(&buf->backend, buf->iter.read_offset,
+				    dest, buf->iter.payload_len);
+}
+
+extern int lib_ring_buffer_iterator_open(struct lib_ring_buffer *buf);
+extern void lib_ring_buffer_iterator_release(struct lib_ring_buffer *buf);
+extern int channel_iterator_open(struct channel *chan);
+extern void channel_iterator_release(struct channel *chan);
+
+extern const struct file_operations channel_payload_file_operations;
+extern const struct file_operations lib_ring_buffer_payload_file_operations;
+
+/*
+ * Used internally.
+ */
+int channel_iterator_init(struct channel *chan);
+void channel_iterator_unregister_notifiers(struct channel *chan);
+void channel_iterator_free(struct channel *chan);
+void channel_iterator_reset(struct channel *chan);
+void lib_ring_buffer_iterator_reset(struct lib_ring_buffer *buf);
+
+#endif /* _LINUX_RING_BUFFER_ITERATOR_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/nohz.h b/drivers/staging/lttng/lib/ringbuffer/nohz.h
new file mode 100644
index 0000000..3c31072
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/nohz.h
@@ -0,0 +1,30 @@
+#ifndef _LINUX_RING_BUFFER_NOHZ_H
+#define _LINUX_RING_BUFFER_NOHZ_H
+
+/*
+ * ringbuffer/nohz.h
+ *
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifdef CONFIG_LIB_RING_BUFFER
+void lib_ring_buffer_tick_nohz_flush(void);
+void lib_ring_buffer_tick_nohz_stop(void);
+void lib_ring_buffer_tick_nohz_restart(void);
+#else
+static inline void lib_ring_buffer_tick_nohz_flush(void)
+{
+}
+
+static inline void lib_ring_buffer_tick_nohz_stop(void)
+{
+}
+
+static inline void lib_ring_buffer_tick_nohz_restart(void)
+{
+}
+#endif
+
+#endif /* _LINUX_RING_BUFFER_NOHZ_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c
new file mode 100644
index 0000000..d1b5b8c
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c
@@ -0,0 +1,854 @@
+/*
+ * ring_buffer_backend.c
+ *
+ * Copyright (C) 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/stddef.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/mm.h>
+
+#include "../../wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "../../wrapper/ringbuffer/config.h"
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+
+/**
+ * lib_ring_buffer_backend_allocate - allocate a channel buffer
+ * @config: ring buffer instance configuration
+ * @buf: the buffer struct
+ * @size: total size of the buffer
+ * @num_subbuf: number of subbuffers
+ * @extra_reader_sb: need extra subbuffer for reader
+ */
+static
+int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config,
+				     struct lib_ring_buffer_backend *bufb,
+				     size_t size, size_t num_subbuf,
+				     int extra_reader_sb)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	unsigned long j, num_pages, num_pages_per_subbuf, page_idx = 0;
+	unsigned long subbuf_size, mmap_offset = 0;
+	unsigned long num_subbuf_alloc;
+	struct page **pages;
+	void **virt;
+	unsigned long i;
+
+	num_pages = size >> PAGE_SHIFT;
+	num_pages_per_subbuf = num_pages >> get_count_order(num_subbuf);
+	subbuf_size = chanb->subbuf_size;
+	num_subbuf_alloc = num_subbuf;
+
+	if (extra_reader_sb) {
+		num_pages += num_pages_per_subbuf; /* Add pages for reader */
+		num_subbuf_alloc++;
+	}
+
+	pages = kmalloc_node(ALIGN(sizeof(*pages) * num_pages,
+				   1 << INTERNODE_CACHE_SHIFT),
+			GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
+	if (unlikely(!pages))
+		goto pages_error;
+
+	virt = kmalloc_node(ALIGN(sizeof(*virt) * num_pages,
+				  1 << INTERNODE_CACHE_SHIFT),
+			GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
+	if (unlikely(!virt))
+		goto virt_error;
+
+	bufb->array = kmalloc_node(ALIGN(sizeof(*bufb->array)
+					 * num_subbuf_alloc,
+				  1 << INTERNODE_CACHE_SHIFT),
+			GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
+	if (unlikely(!bufb->array))
+		goto array_error;
+
+	for (i = 0; i < num_pages; i++) {
+		pages[i] = alloc_pages_node(cpu_to_node(max(bufb->cpu, 0)),
+					    GFP_KERNEL | __GFP_ZERO, 0);
+		if (unlikely(!pages[i]))
+			goto depopulate;
+		virt[i] = page_address(pages[i]);
+	}
+	bufb->num_pages_per_subbuf = num_pages_per_subbuf;
+
+	/* Allocate backend pages array elements */
+	for (i = 0; i < num_subbuf_alloc; i++) {
+		bufb->array[i] =
+			kzalloc_node(ALIGN(
+				sizeof(struct lib_ring_buffer_backend_pages) +
+				sizeof(struct lib_ring_buffer_backend_page)
+				* num_pages_per_subbuf,
+				1 << INTERNODE_CACHE_SHIFT),
+				GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
+		if (!bufb->array[i])
+			goto free_array;
+	}
+
+	/* Allocate write-side subbuffer table */
+	bufb->buf_wsb = kzalloc_node(ALIGN(
+				sizeof(struct lib_ring_buffer_backend_subbuffer)
+				* num_subbuf,
+				1 << INTERNODE_CACHE_SHIFT),
+				GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0)));
+	if (unlikely(!bufb->buf_wsb))
+		goto free_array;
+
+	for (i = 0; i < num_subbuf; i++)
+		bufb->buf_wsb[i].id = subbuffer_id(config, 0, 1, i);
+
+	/* Assign read-side subbuffer table */
+	if (extra_reader_sb)
+		bufb->buf_rsb.id = subbuffer_id(config, 0, 1,
+						num_subbuf_alloc - 1);
+	else
+		bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0);
+
+	/* Assign pages to page index */
+	for (i = 0; i < num_subbuf_alloc; i++) {
+		for (j = 0; j < num_pages_per_subbuf; j++) {
+			CHAN_WARN_ON(chanb, page_idx > num_pages);
+			bufb->array[i]->p[j].virt = virt[page_idx];
+			bufb->array[i]->p[j].page = pages[page_idx];
+			page_idx++;
+		}
+		if (config->output == RING_BUFFER_MMAP) {
+			bufb->array[i]->mmap_offset = mmap_offset;
+			mmap_offset += subbuf_size;
+		}
+	}
+
+	/*
+	 * If kmalloc ever uses vmalloc underneath, make sure the buffer pages
+	 * will not fault.
+	 */
+	wrapper_vmalloc_sync_all();
+	kfree(virt);
+	kfree(pages);
+	return 0;
+
+free_array:
+	for (i = 0; (i < num_subbuf_alloc && bufb->array[i]); i++)
+		kfree(bufb->array[i]);
+depopulate:
+	/* Free all allocated pages */
+	for (i = 0; (i < num_pages && pages[i]); i++)
+		__free_page(pages[i]);
+	kfree(bufb->array);
+array_error:
+	kfree(virt);
+virt_error:
+	kfree(pages);
+pages_error:
+	return -ENOMEM;
+}
+
+int lib_ring_buffer_backend_create(struct lib_ring_buffer_backend *bufb,
+				   struct channel_backend *chanb, int cpu)
+{
+	const struct lib_ring_buffer_config *config = chanb->config;
+
+	bufb->chan = container_of(chanb, struct channel, backend);
+	bufb->cpu = cpu;
+
+	return lib_ring_buffer_backend_allocate(config, bufb, chanb->buf_size,
+						chanb->num_subbuf,
+						chanb->extra_reader_sb);
+}
+
+void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	unsigned long i, j, num_subbuf_alloc;
+
+	num_subbuf_alloc = chanb->num_subbuf;
+	if (chanb->extra_reader_sb)
+		num_subbuf_alloc++;
+
+	kfree(bufb->buf_wsb);
+	for (i = 0; i < num_subbuf_alloc; i++) {
+		for (j = 0; j < bufb->num_pages_per_subbuf; j++)
+			__free_page(bufb->array[i]->p[j].page);
+		kfree(bufb->array[i]);
+	}
+	kfree(bufb->array);
+	bufb->allocated = 0;
+}
+
+void lib_ring_buffer_backend_reset(struct lib_ring_buffer_backend *bufb)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	unsigned long num_subbuf_alloc;
+	unsigned int i;
+
+	num_subbuf_alloc = chanb->num_subbuf;
+	if (chanb->extra_reader_sb)
+		num_subbuf_alloc++;
+
+	for (i = 0; i < chanb->num_subbuf; i++)
+		bufb->buf_wsb[i].id = subbuffer_id(config, 0, 1, i);
+	if (chanb->extra_reader_sb)
+		bufb->buf_rsb.id = subbuffer_id(config, 0, 1,
+						num_subbuf_alloc - 1);
+	else
+		bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0);
+
+	for (i = 0; i < num_subbuf_alloc; i++) {
+		/* Don't reset mmap_offset */
+		v_set(config, &bufb->array[i]->records_commit, 0);
+		v_set(config, &bufb->array[i]->records_unread, 0);
+		bufb->array[i]->data_size = 0;
+		/* Don't reset backend page and virt addresses */
+	}
+	/* Don't reset num_pages_per_subbuf, cpu, allocated */
+	v_set(config, &bufb->records_read, 0);
+}
+
+/*
+ * The frontend is responsible for also calling ring_buffer_backend_reset for
+ * each buffer when calling channel_backend_reset.
+ */
+void channel_backend_reset(struct channel_backend *chanb)
+{
+	struct channel *chan = container_of(chanb, struct channel, backend);
+	const struct lib_ring_buffer_config *config = chanb->config;
+
+	/*
+	 * Don't reset buf_size, subbuf_size, subbuf_size_order,
+	 * num_subbuf_order, buf_size_order, extra_reader_sb, num_subbuf,
+	 * priv, notifiers, config, cpumask and name.
+	 */
+	chanb->start_tsc = config->cb.ring_buffer_clock_read(chan);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/**
+ *	lib_ring_buffer_cpu_hp_callback - CPU hotplug callback
+ *	@nb: notifier block
+ *	@action: hotplug action to take
+ *	@hcpu: CPU number
+ *
+ *	Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
+ */
+static
+int __cpuinit lib_ring_buffer_cpu_hp_callback(struct notifier_block *nb,
+					      unsigned long action,
+					      void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+	struct channel_backend *chanb = container_of(nb, struct channel_backend,
+						     cpu_hp_notifier);
+	const struct lib_ring_buffer_config *config = chanb->config;
+	struct lib_ring_buffer *buf;
+	int ret;
+
+	CHAN_WARN_ON(chanb, config->alloc == RING_BUFFER_ALLOC_GLOBAL);
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		buf = per_cpu_ptr(chanb->buf, cpu);
+		ret = lib_ring_buffer_create(buf, chanb, cpu);
+		if (ret) {
+			printk(KERN_ERR
+			  "ring_buffer_cpu_hp_callback: cpu %d "
+			  "buffer creation failed\n", cpu);
+			return NOTIFY_BAD;
+		}
+		break;
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		/* No need to do a buffer switch here, because it will happen
+		 * when tracing is stopped, or will be done by switch timer CPU
+		 * DEAD callback. */
+		break;
+	}
+	return NOTIFY_OK;
+}
+#endif
+
+/**
+ * channel_backend_init - initialize a channel backend
+ * @chanb: channel backend
+ * @name: channel name
+ * @config: client ring buffer configuration
+ * @priv: client private data
+ * @parent: dentry of parent directory, %NULL for root directory
+ * @subbuf_size: size of sub-buffers (> PAGE_SIZE, power of 2)
+ * @num_subbuf: number of sub-buffers (power of 2)
+ *
+ * Returns channel pointer if successful, %NULL otherwise.
+ *
+ * Creates per-cpu channel buffers using the sizes and attributes
+ * specified.  The created channel buffer files will be named
+ * name_0...name_N-1.  File permissions will be %S_IRUSR.
+ *
+ * Called with CPU hotplug disabled.
+ */
+int channel_backend_init(struct channel_backend *chanb,
+			 const char *name,
+			 const struct lib_ring_buffer_config *config,
+			 void *priv, size_t subbuf_size, size_t num_subbuf)
+{
+	struct channel *chan = container_of(chanb, struct channel, backend);
+	unsigned int i;
+	int ret;
+
+	if (!name)
+		return -EPERM;
+
+	if (!(subbuf_size && num_subbuf))
+		return -EPERM;
+
+	/* Check that the subbuffer size is larger than a page. */
+	if (subbuf_size < PAGE_SIZE)
+		return -EINVAL;
+
+	/*
+	 * Make sure the number of subbuffers and subbuffer size are power of 2.
+	 */
+	CHAN_WARN_ON(chanb, hweight32(subbuf_size) != 1);
+	CHAN_WARN_ON(chanb, hweight32(num_subbuf) != 1);
+
+	ret = subbuffer_id_check_index(config, num_subbuf);
+	if (ret)
+		return ret;
+
+	chanb->priv = priv;
+	chanb->buf_size = num_subbuf * subbuf_size;
+	chanb->subbuf_size = subbuf_size;
+	chanb->buf_size_order = get_count_order(chanb->buf_size);
+	chanb->subbuf_size_order = get_count_order(subbuf_size);
+	chanb->num_subbuf_order = get_count_order(num_subbuf);
+	chanb->extra_reader_sb =
+			(config->mode == RING_BUFFER_OVERWRITE) ? 1 : 0;
+	chanb->num_subbuf = num_subbuf;
+	strlcpy(chanb->name, name, NAME_MAX);
+	chanb->config = config;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		if (!zalloc_cpumask_var(&chanb->cpumask, GFP_KERNEL))
+			return -ENOMEM;
+	}
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		/* Allocating the buffer per-cpu structures */
+		chanb->buf = alloc_percpu(struct lib_ring_buffer);
+		if (!chanb->buf)
+			goto free_cpumask;
+
+		/*
+		 * In case of non-hotplug cpu, if the ring-buffer is allocated
+		 * in early initcall, it will not be notified of secondary cpus.
+		 * In that off case, we need to allocate for all possible cpus.
+		 */
+#ifdef CONFIG_HOTPLUG_CPU
+		/*
+		 * buf->backend.allocated test takes care of concurrent CPU
+		 * hotplug.
+		 * Priority higher than frontend, so we create the ring buffer
+		 * before we start the timer.
+		 */
+		chanb->cpu_hp_notifier.notifier_call =
+				lib_ring_buffer_cpu_hp_callback;
+		chanb->cpu_hp_notifier.priority = 5;
+		register_hotcpu_notifier(&chanb->cpu_hp_notifier);
+
+		get_online_cpus();
+		for_each_online_cpu(i) {
+			ret = lib_ring_buffer_create(per_cpu_ptr(chanb->buf, i),
+						 chanb, i);
+			if (ret)
+				goto free_bufs;	/* cpu hotplug locked */
+		}
+		put_online_cpus();
+#else
+		for_each_possible_cpu(i) {
+			ret = lib_ring_buffer_create(per_cpu_ptr(chanb->buf, i),
+						 chanb, i);
+			if (ret)
+				goto free_bufs;	/* cpu hotplug locked */
+		}
+#endif
+	} else {
+		chanb->buf = kzalloc(sizeof(struct lib_ring_buffer), GFP_KERNEL);
+		if (!chanb->buf)
+			goto free_cpumask;
+		ret = lib_ring_buffer_create(chanb->buf, chanb, -1);
+		if (ret)
+			goto free_bufs;
+	}
+	chanb->start_tsc = config->cb.ring_buffer_clock_read(chan);
+
+	return 0;
+
+free_bufs:
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		for_each_possible_cpu(i) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chanb->buf, i);
+
+			if (!buf->backend.allocated)
+				continue;
+			lib_ring_buffer_free(buf);
+		}
+#ifdef CONFIG_HOTPLUG_CPU
+		put_online_cpus();
+#endif
+		free_percpu(chanb->buf);
+	} else
+		kfree(chanb->buf);
+free_cpumask:
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		free_cpumask_var(chanb->cpumask);
+	return -ENOMEM;
+}
+
+/**
+ * channel_backend_unregister_notifiers - unregister notifiers
+ * @chan: the channel
+ *
+ * Holds CPU hotplug.
+ */
+void channel_backend_unregister_notifiers(struct channel_backend *chanb)
+{
+	const struct lib_ring_buffer_config *config = chanb->config;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		unregister_hotcpu_notifier(&chanb->cpu_hp_notifier);
+}
+
+/**
+ * channel_backend_free - destroy the channel
+ * @chan: the channel
+ *
+ * Destroy all channel buffers and frees the channel.
+ */
+void channel_backend_free(struct channel_backend *chanb)
+{
+	const struct lib_ring_buffer_config *config = chanb->config;
+	unsigned int i;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		for_each_possible_cpu(i) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chanb->buf, i);
+
+			if (!buf->backend.allocated)
+				continue;
+			lib_ring_buffer_free(buf);
+		}
+		free_cpumask_var(chanb->cpumask);
+		free_percpu(chanb->buf);
+	} else {
+		struct lib_ring_buffer *buf = chanb->buf;
+
+		CHAN_WARN_ON(chanb, !buf->backend.allocated);
+		lib_ring_buffer_free(buf);
+		kfree(buf);
+	}
+}
+
+/**
+ * lib_ring_buffer_write - write data to a ring_buffer buffer.
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @src : source address
+ * @len : length to write
+ * @pagecpy : page size copied so far
+ */
+void _lib_ring_buffer_write(struct lib_ring_buffer_backend *bufb, size_t offset,
+			    const void *src, size_t len, ssize_t pagecpy)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t sbidx, index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	do {
+		len -= pagecpy;
+		src += pagecpy;
+		offset += pagecpy;
+		sbidx = offset >> chanb->subbuf_size_order;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+
+		/*
+		 * Underlying layer should never ask for writes across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+
+		pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK));
+		id = bufb->buf_wsb[sbidx].id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+			     && subbuffer_id_is_noref(config, id));
+		lib_ring_buffer_do_copy(config,
+					rpages->p[index].virt
+						+ (offset & ~PAGE_MASK),
+					src, pagecpy);
+	} while (unlikely(len != pagecpy));
+}
+EXPORT_SYMBOL_GPL(_lib_ring_buffer_write);
+
+
+/**
+ * lib_ring_buffer_memset - write len bytes of c to a ring_buffer buffer.
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @c : the byte to write
+ * @len : length to write
+ * @pagecpy : page size copied so far
+ */
+void _lib_ring_buffer_memset(struct lib_ring_buffer_backend *bufb,
+			     size_t offset,
+			     int c, size_t len, ssize_t pagecpy)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t sbidx, index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	do {
+		len -= pagecpy;
+		offset += pagecpy;
+		sbidx = offset >> chanb->subbuf_size_order;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+
+		/*
+		 * Underlying layer should never ask for writes across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+
+		pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK));
+		id = bufb->buf_wsb[sbidx].id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+			     && subbuffer_id_is_noref(config, id));
+		lib_ring_buffer_do_memset(rpages->p[index].virt
+					  + (offset & ~PAGE_MASK),
+					  c, pagecpy);
+	} while (unlikely(len != pagecpy));
+}
+EXPORT_SYMBOL_GPL(_lib_ring_buffer_memset);
+
+
+/**
+ * lib_ring_buffer_copy_from_user - write user data to a ring_buffer buffer.
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @src : source address
+ * @len : length to write
+ * @pagecpy : page size copied so far
+ *
+ * This function deals with userspace pointers, it should never be called
+ * directly without having the src pointer checked with access_ok()
+ * previously.
+ */
+void _lib_ring_buffer_copy_from_user(struct lib_ring_buffer_backend *bufb,
+				      size_t offset,
+				      const void __user *src, size_t len,
+				      ssize_t pagecpy)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t sbidx, index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+	int ret;
+
+	do {
+		len -= pagecpy;
+		src += pagecpy;
+		offset += pagecpy;
+		sbidx = offset >> chanb->subbuf_size_order;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+
+		/*
+		 * Underlying layer should never ask for writes across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+
+		pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK));
+		id = bufb->buf_wsb[sbidx].id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+				&& subbuffer_id_is_noref(config, id));
+		ret = lib_ring_buffer_do_copy_from_user(rpages->p[index].virt
+							+ (offset & ~PAGE_MASK),
+							src, pagecpy) != 0;
+		if (ret > 0) {
+			offset += (pagecpy - ret);
+			len -= (pagecpy - ret);
+			_lib_ring_buffer_memset(bufb, offset, 0, len, 0);
+			break; /* stop copy */
+		}
+	} while (unlikely(len != pagecpy));
+}
+EXPORT_SYMBOL_GPL(_lib_ring_buffer_copy_from_user);
+
+/**
+ * lib_ring_buffer_read - read data from ring_buffer_buffer.
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @dest : destination address
+ * @len : length to copy to destination
+ *
+ * Should be protected by get_subbuf/put_subbuf.
+ * Returns the length copied.
+ */
+size_t lib_ring_buffer_read(struct lib_ring_buffer_backend *bufb, size_t offset,
+			    void *dest, size_t len)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t index;
+	ssize_t pagecpy, orig_len;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	orig_len = len;
+	offset &= chanb->buf_size - 1;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	if (unlikely(!len))
+		return 0;
+	for (;;) {
+		pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK));
+		id = bufb->buf_rsb.id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+			     && subbuffer_id_is_noref(config, id));
+		memcpy(dest, rpages->p[index].virt + (offset & ~PAGE_MASK),
+		       pagecpy);
+		len -= pagecpy;
+		if (likely(!len))
+			break;
+		dest += pagecpy;
+		offset += pagecpy;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+		/*
+		 * Underlying layer should never ask for reads across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+	}
+	return orig_len;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_read);
+
+/**
+ * __lib_ring_buffer_copy_to_user - read data from ring_buffer to userspace
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @dest : destination userspace address
+ * @len : length to copy to destination
+ *
+ * Should be protected by get_subbuf/put_subbuf.
+ * access_ok() must have been performed on dest addresses prior to call this
+ * function.
+ * Returns -EFAULT on error, 0 if ok.
+ */
+int __lib_ring_buffer_copy_to_user(struct lib_ring_buffer_backend *bufb,
+				   size_t offset, void __user *dest, size_t len)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t index;
+	ssize_t pagecpy;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	if (unlikely(!len))
+		return 0;
+	for (;;) {
+		pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK));
+		id = bufb->buf_rsb.id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+			     && subbuffer_id_is_noref(config, id));
+		if (__copy_to_user(dest,
+			       rpages->p[index].virt + (offset & ~PAGE_MASK),
+			       pagecpy))
+			return -EFAULT;
+		len -= pagecpy;
+		if (likely(!len))
+			break;
+		dest += pagecpy;
+		offset += pagecpy;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+		/*
+		 * Underlying layer should never ask for reads across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__lib_ring_buffer_copy_to_user);
+
+/**
+ * lib_ring_buffer_read_cstr - read a C-style string from ring_buffer.
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @dest : destination address
+ * @len : destination's length
+ *
+ * return string's length
+ * Should be protected by get_subbuf/put_subbuf.
+ */
+int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb, size_t offset,
+			      void *dest, size_t len)
+{
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	size_t index;
+	ssize_t pagecpy, pagelen, strpagelen, orig_offset;
+	char *str;
+	struct lib_ring_buffer_backend_pages *rpages;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	orig_offset = offset;
+	for (;;) {
+		id = bufb->buf_rsb.id;
+		sb_bindex = subbuffer_id_get_index(config, id);
+		rpages = bufb->array[sb_bindex];
+		CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+			     && subbuffer_id_is_noref(config, id));
+		str = (char *)rpages->p[index].virt + (offset & ~PAGE_MASK);
+		pagelen = PAGE_SIZE - (offset & ~PAGE_MASK);
+		strpagelen = strnlen(str, pagelen);
+		if (len) {
+			pagecpy = min_t(size_t, len, strpagelen);
+			if (dest) {
+				memcpy(dest, str, pagecpy);
+				dest += pagecpy;
+			}
+			len -= pagecpy;
+		}
+		offset += strpagelen;
+		index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+		if (strpagelen < pagelen)
+			break;
+		/*
+		 * Underlying layer should never ask for reads across
+		 * subbuffers.
+		 */
+		CHAN_WARN_ON(chanb, offset >= chanb->buf_size);
+	}
+	if (dest && len)
+		((char *)dest)[0] = 0;
+	return offset - orig_offset;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_read_cstr);
+
+/**
+ * lib_ring_buffer_read_get_page - Get a whole page to read from
+ * @bufb : buffer backend
+ * @offset : offset within the buffer
+ * @virt : pointer to page address (output)
+ *
+ * Should be protected by get_subbuf/put_subbuf.
+ * Returns the pointer to the page struct pointer.
+ */
+struct page **lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb,
+					    size_t offset, void ***virt)
+{
+	size_t index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	id = bufb->buf_rsb.id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+	*virt = &rpages->p[index].virt;
+	return &rpages->p[index].page;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_read_get_page);
+
+/**
+ * lib_ring_buffer_read_offset_address - get address of a buffer location
+ * @bufb : buffer backend
+ * @offset : offset within the buffer.
+ *
+ * Return the address where a given offset is located (for read).
+ * Should be used to get the current subbuffer header pointer. Given we know
+ * it's never on a page boundary, it's safe to write directly to this address,
+ * as long as the write is never bigger than a page size.
+ */
+void *lib_ring_buffer_read_offset_address(struct lib_ring_buffer_backend *bufb,
+					  size_t offset)
+{
+	size_t index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	id = bufb->buf_rsb.id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+	return rpages->p[index].virt + (offset & ~PAGE_MASK);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_read_offset_address);
+
+/**
+ * lib_ring_buffer_offset_address - get address of a location within the buffer
+ * @bufb : buffer backend
+ * @offset : offset within the buffer.
+ *
+ * Return the address where a given offset is located.
+ * Should be used to get the current subbuffer header pointer. Given we know
+ * it's always at the beginning of a page, it's safe to write directly to this
+ * address, as long as the write is never bigger than a page size.
+ */
+void *lib_ring_buffer_offset_address(struct lib_ring_buffer_backend *bufb,
+				     size_t offset)
+{
+	size_t sbidx, index;
+	struct lib_ring_buffer_backend_pages *rpages;
+	struct channel_backend *chanb = &bufb->chan->backend;
+	const struct lib_ring_buffer_config *config = chanb->config;
+	unsigned long sb_bindex, id;
+
+	offset &= chanb->buf_size - 1;
+	sbidx = offset >> chanb->subbuf_size_order;
+	index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT;
+	id = bufb->buf_wsb[sbidx].id;
+	sb_bindex = subbuffer_id_get_index(config, id);
+	rpages = bufb->array[sb_bindex];
+	CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, id));
+	return rpages->p[index].virt + (offset & ~PAGE_MASK);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_offset_address);
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
new file mode 100644
index 0000000..802f5cd
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
@@ -0,0 +1,1721 @@
+/*
+ * ring_buffer_frontend.c
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer wait-free buffer synchronization. Producer-consumer and flight
+ * recorder (overwrite) modes. See thesis:
+ *
+ * Desnoyers, Mathieu (2009), "Low-Impact Operating System Tracing", Ph.D.
+ * dissertation, Ecole Polytechnique de Montreal.
+ * http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf
+ *
+ * - Algorithm presentation in Chapter 5:
+ *     "Lockless Multi-Core High-Throughput Buffering".
+ * - Algorithm formal verification in Section 8.6:
+ *     "Formal verification of LTTng"
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Inspired from LTT and RelayFS:
+ *  Karim Yaghmour <karim at opersys.com>
+ *  Tom Zanussi <zanussi at us.ibm.com>
+ *  Bob Wisniewski <bob at watson.ibm.com>
+ * And from K42 :
+ *  Bob Wisniewski <bob at watson.ibm.com>
+ *
+ * Buffer reader semantic :
+ *
+ * - get_subbuf_size
+ * while buffer is not finalized and empty
+ *   - get_subbuf
+ *     - if return value != 0, continue
+ *   - splice one subbuffer worth of data to a pipe
+ *   - splice the data from pipe to disk/network
+ *   - put_subbuf
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+
+#include "../../wrapper/ringbuffer/config.h"
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+#include "../../wrapper/ringbuffer/iterator.h"
+#include "../../wrapper/ringbuffer/nohz.h"
+
+/*
+ * Internal structure representing offsets to use at a sub-buffer switch.
+ */
+struct switch_offsets {
+	unsigned long begin, end, old;
+	size_t pre_header_padding, size;
+	unsigned int switch_new_start:1, switch_new_end:1, switch_old_start:1,
+		     switch_old_end:1;
+};
+
+#ifdef CONFIG_NO_HZ
+enum tick_nohz_val {
+	TICK_NOHZ_STOP,
+	TICK_NOHZ_FLUSH,
+	TICK_NOHZ_RESTART,
+};
+
+static ATOMIC_NOTIFIER_HEAD(tick_nohz_notifier);
+#endif /* CONFIG_NO_HZ */
+
+static DEFINE_PER_CPU(spinlock_t, ring_buffer_nohz_lock);
+
+DEFINE_PER_CPU(unsigned int, lib_ring_buffer_nesting);
+EXPORT_PER_CPU_SYMBOL(lib_ring_buffer_nesting);
+
+static
+void lib_ring_buffer_print_errors(struct channel *chan,
+				  struct lib_ring_buffer *buf, int cpu);
+
+/*
+ * Must be called under cpu hotplug protection.
+ */
+void lib_ring_buffer_free(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+
+	lib_ring_buffer_print_errors(chan, buf, buf->backend.cpu);
+	kfree(buf->commit_hot);
+	kfree(buf->commit_cold);
+
+	lib_ring_buffer_backend_free(&buf->backend);
+}
+
+/**
+ * lib_ring_buffer_reset - Reset ring buffer to initial values.
+ * @buf: Ring buffer.
+ *
+ * Effectively empty the ring buffer. Should be called when the buffer is not
+ * used for writing. The ring buffer can be opened for reading, but the reader
+ * should not be using the iterator concurrently with reset. The previous
+ * current iterator record is reset.
+ */
+void lib_ring_buffer_reset(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned int i;
+
+	/*
+	 * Reset iterator first. It will put the subbuffer if it currently holds
+	 * it.
+	 */
+	lib_ring_buffer_iterator_reset(buf);
+	v_set(config, &buf->offset, 0);
+	for (i = 0; i < chan->backend.num_subbuf; i++) {
+		v_set(config, &buf->commit_hot[i].cc, 0);
+		v_set(config, &buf->commit_hot[i].seq, 0);
+		v_set(config, &buf->commit_cold[i].cc_sb, 0);
+	}
+	atomic_long_set(&buf->consumed, 0);
+	atomic_set(&buf->record_disabled, 0);
+	v_set(config, &buf->last_tsc, 0);
+	lib_ring_buffer_backend_reset(&buf->backend);
+	/* Don't reset number of active readers */
+	v_set(config, &buf->records_lost_full, 0);
+	v_set(config, &buf->records_lost_wrap, 0);
+	v_set(config, &buf->records_lost_big, 0);
+	v_set(config, &buf->records_count, 0);
+	v_set(config, &buf->records_overrun, 0);
+	buf->finalized = 0;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_reset);
+
+/**
+ * channel_reset - Reset channel to initial values.
+ * @chan: Channel.
+ *
+ * Effectively empty the channel. Should be called when the channel is not used
+ * for writing. The channel can be opened for reading, but the reader should not
+ * be using the iterator concurrently with reset. The previous current iterator
+ * record is reset.
+ */
+void channel_reset(struct channel *chan)
+{
+	/*
+	 * Reset iterators first. Will put the subbuffer if held for reading.
+	 */
+	channel_iterator_reset(chan);
+	atomic_set(&chan->record_disabled, 0);
+	/* Don't reset commit_count_mask, still valid */
+	channel_backend_reset(&chan->backend);
+	/* Don't reset switch/read timer interval */
+	/* Don't reset notifiers and notifier enable bits */
+	/* Don't reset reader reference count */
+}
+EXPORT_SYMBOL_GPL(channel_reset);
+
+/*
+ * Must be called under cpu hotplug protection.
+ */
+int lib_ring_buffer_create(struct lib_ring_buffer *buf,
+			   struct channel_backend *chanb, int cpu)
+{
+	const struct lib_ring_buffer_config *config = chanb->config;
+	struct channel *chan = container_of(chanb, struct channel, backend);
+	void *priv = chanb->priv;
+	size_t subbuf_header_size;
+	u64 tsc;
+	int ret;
+
+	/* Test for cpu hotplug */
+	if (buf->backend.allocated)
+		return 0;
+
+	/*
+	 * Paranoia: per cpu dynamic allocation is not officially documented as
+	 * zeroing the memory, so let's do it here too, just in case.
+	 */
+	memset(buf, 0, sizeof(*buf));
+
+	ret = lib_ring_buffer_backend_create(&buf->backend, &chan->backend, cpu);
+	if (ret)
+		return ret;
+
+	buf->commit_hot =
+		kzalloc_node(ALIGN(sizeof(*buf->commit_hot)
+				   * chan->backend.num_subbuf,
+				   1 << INTERNODE_CACHE_SHIFT),
+			GFP_KERNEL, cpu_to_node(max(cpu, 0)));
+	if (!buf->commit_hot) {
+		ret = -ENOMEM;
+		goto free_chanbuf;
+	}
+
+	buf->commit_cold =
+		kzalloc_node(ALIGN(sizeof(*buf->commit_cold)
+				   * chan->backend.num_subbuf,
+				   1 << INTERNODE_CACHE_SHIFT),
+			GFP_KERNEL, cpu_to_node(max(cpu, 0)));
+	if (!buf->commit_cold) {
+		ret = -ENOMEM;
+		goto free_commit;
+	}
+
+	init_waitqueue_head(&buf->read_wait);
+	init_waitqueue_head(&buf->write_wait);
+	raw_spin_lock_init(&buf->raw_tick_nohz_spinlock);
+
+	/*
+	 * Write the subbuffer header for first subbuffer so we know the total
+	 * duration of data gathering.
+	 */
+	subbuf_header_size = config->cb.subbuffer_header_size();
+	v_set(config, &buf->offset, subbuf_header_size);
+	subbuffer_id_clear_noref(config, &buf->backend.buf_wsb[0].id);
+	tsc = config->cb.ring_buffer_clock_read(buf->backend.chan);
+	config->cb.buffer_begin(buf, tsc, 0);
+	v_add(config, subbuf_header_size, &buf->commit_hot[0].cc);
+
+	if (config->cb.buffer_create) {
+		ret = config->cb.buffer_create(buf, priv, cpu, chanb->name);
+		if (ret)
+			goto free_init;
+	}
+
+	/*
+	 * Ensure the buffer is ready before setting it to allocated and setting
+	 * the cpumask.
+	 * Used for cpu hotplug vs cpumask iteration.
+	 */
+	smp_wmb();
+	buf->backend.allocated = 1;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		CHAN_WARN_ON(chan, cpumask_test_cpu(cpu,
+			     chan->backend.cpumask));
+		cpumask_set_cpu(cpu, chan->backend.cpumask);
+	}
+
+	return 0;
+
+	/* Error handling */
+free_init:
+	kfree(buf->commit_cold);
+free_commit:
+	kfree(buf->commit_hot);
+free_chanbuf:
+	lib_ring_buffer_backend_free(&buf->backend);
+	return ret;
+}
+
+static void switch_buffer_timer(unsigned long data)
+{
+	struct lib_ring_buffer *buf = (struct lib_ring_buffer *)data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	/*
+	 * Only flush buffers periodically if readers are active.
+	 */
+	if (atomic_long_read(&buf->active_readers))
+		lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		mod_timer_pinned(&buf->switch_timer,
+				 jiffies + chan->switch_timer_interval);
+	else
+		mod_timer(&buf->switch_timer,
+			  jiffies + chan->switch_timer_interval);
+}
+
+/*
+ * Called with ring_buffer_nohz_lock held for per-cpu buffers.
+ */
+static void lib_ring_buffer_start_switch_timer(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (!chan->switch_timer_interval || buf->switch_timer_enabled)
+		return;
+	init_timer(&buf->switch_timer);
+	buf->switch_timer.function = switch_buffer_timer;
+	buf->switch_timer.expires = jiffies + chan->switch_timer_interval;
+	buf->switch_timer.data = (unsigned long)buf;
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		add_timer_on(&buf->switch_timer, buf->backend.cpu);
+	else
+		add_timer(&buf->switch_timer);
+	buf->switch_timer_enabled = 1;
+}
+
+/*
+ * Called with ring_buffer_nohz_lock held for per-cpu buffers.
+ */
+static void lib_ring_buffer_stop_switch_timer(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+
+	if (!chan->switch_timer_interval || !buf->switch_timer_enabled)
+		return;
+
+	del_timer_sync(&buf->switch_timer);
+	buf->switch_timer_enabled = 0;
+}
+
+/*
+ * Polling timer to check the channels for data.
+ */
+static void read_buffer_timer(unsigned long data)
+{
+	struct lib_ring_buffer *buf = (struct lib_ring_buffer *)data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	CHAN_WARN_ON(chan, !buf->backend.allocated);
+
+	if (atomic_long_read(&buf->active_readers)
+	    && lib_ring_buffer_poll_deliver(config, buf, chan)) {
+		wake_up_interruptible(&buf->read_wait);
+		wake_up_interruptible(&chan->read_wait);
+	}
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		mod_timer_pinned(&buf->read_timer,
+				 jiffies + chan->read_timer_interval);
+	else
+		mod_timer(&buf->read_timer,
+			  jiffies + chan->read_timer_interval);
+}
+
+/*
+ * Called with ring_buffer_nohz_lock held for per-cpu buffers.
+ */
+static void lib_ring_buffer_start_read_timer(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER
+	    || !chan->read_timer_interval
+	    || buf->read_timer_enabled)
+		return;
+
+	init_timer(&buf->read_timer);
+	buf->read_timer.function = read_buffer_timer;
+	buf->read_timer.expires = jiffies + chan->read_timer_interval;
+	buf->read_timer.data = (unsigned long)buf;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		add_timer_on(&buf->read_timer, buf->backend.cpu);
+	else
+		add_timer(&buf->read_timer);
+	buf->read_timer_enabled = 1;
+}
+
+/*
+ * Called with ring_buffer_nohz_lock held for per-cpu buffers.
+ */
+static void lib_ring_buffer_stop_read_timer(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER
+	    || !chan->read_timer_interval
+	    || !buf->read_timer_enabled)
+		return;
+
+	del_timer_sync(&buf->read_timer);
+	/*
+	 * do one more check to catch data that has been written in the last
+	 * timer period.
+	 */
+	if (lib_ring_buffer_poll_deliver(config, buf, chan)) {
+		wake_up_interruptible(&buf->read_wait);
+		wake_up_interruptible(&chan->read_wait);
+	}
+	buf->read_timer_enabled = 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/**
+ *	lib_ring_buffer_cpu_hp_callback - CPU hotplug callback
+ *	@nb: notifier block
+ *	@action: hotplug action to take
+ *	@hcpu: CPU number
+ *
+ *	Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
+ */
+static
+int __cpuinit lib_ring_buffer_cpu_hp_callback(struct notifier_block *nb,
+					      unsigned long action,
+					      void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+	struct channel *chan = container_of(nb, struct channel,
+					    cpu_hp_notifier);
+	struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, cpu);
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (!chan->cpu_hp_enable)
+		return NOTIFY_DONE;
+
+	CHAN_WARN_ON(chan, config->alloc == RING_BUFFER_ALLOC_GLOBAL);
+
+	switch (action) {
+	case CPU_DOWN_FAILED:
+	case CPU_DOWN_FAILED_FROZEN:
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+		wake_up_interruptible(&chan->hp_wait);
+		lib_ring_buffer_start_switch_timer(buf);
+		lib_ring_buffer_start_read_timer(buf);
+		return NOTIFY_OK;
+
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+		lib_ring_buffer_stop_switch_timer(buf);
+		lib_ring_buffer_stop_read_timer(buf);
+		return NOTIFY_OK;
+
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		/*
+		 * Performing a buffer switch on a remote CPU. Performed by
+		 * the CPU responsible for doing the hotunplug after the target
+		 * CPU stopped running completely. Ensures that all data
+		 * from that remote CPU is flushed.
+		 */
+		lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+		return NOTIFY_OK;
+
+	default:
+		return NOTIFY_DONE;
+	}
+}
+#endif
+
+#if defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER)
+/*
+ * For per-cpu buffers, call the reader wakeups before switching the buffer, so
+ * that wake-up-tracing generated events are flushed before going idle (in
+ * tick_nohz). We test if the spinlock is locked to deal with the race where
+ * readers try to sample the ring buffer before we perform the switch. We let
+ * the readers retry in that case. If there is data in the buffer, the wake up
+ * is going to forbid the CPU running the reader thread from going idle.
+ */
+static int notrace ring_buffer_tick_nohz_callback(struct notifier_block *nb,
+						  unsigned long val,
+						  void *data)
+{
+	struct channel *chan = container_of(nb, struct channel,
+					    tick_nohz_notifier);
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	int cpu = smp_processor_id();
+
+	if (config->alloc != RING_BUFFER_ALLOC_PER_CPU) {
+		/*
+		 * We don't support keeping the system idle with global buffers
+		 * and streaming active. In order to do so, we would need to
+		 * sample a non-nohz-cpumask racelessly with the nohz updates
+		 * without adding synchronization overhead to nohz. Leave this
+		 * use-case out for now.
+		 */
+		return 0;
+	}
+
+	buf = channel_get_ring_buffer(config, chan, cpu);
+	switch (val) {
+	case TICK_NOHZ_FLUSH:
+		raw_spin_lock(&buf->raw_tick_nohz_spinlock);
+		if (config->wakeup == RING_BUFFER_WAKEUP_BY_TIMER
+		    && chan->read_timer_interval
+		    && atomic_long_read(&buf->active_readers)
+		    && (lib_ring_buffer_poll_deliver(config, buf, chan)
+			|| lib_ring_buffer_pending_data(config, buf, chan))) {
+			wake_up_interruptible(&buf->read_wait);
+			wake_up_interruptible(&chan->read_wait);
+		}
+		if (chan->switch_timer_interval)
+			lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+		raw_spin_unlock(&buf->raw_tick_nohz_spinlock);
+		break;
+	case TICK_NOHZ_STOP:
+		spin_lock(&__get_cpu_var(ring_buffer_nohz_lock));
+		lib_ring_buffer_stop_switch_timer(buf);
+		lib_ring_buffer_stop_read_timer(buf);
+		spin_unlock(&__get_cpu_var(ring_buffer_nohz_lock));
+		break;
+	case TICK_NOHZ_RESTART:
+		spin_lock(&__get_cpu_var(ring_buffer_nohz_lock));
+		lib_ring_buffer_start_read_timer(buf);
+		lib_ring_buffer_start_switch_timer(buf);
+		spin_unlock(&__get_cpu_var(ring_buffer_nohz_lock));
+		break;
+	}
+
+	return 0;
+}
+
+void notrace lib_ring_buffer_tick_nohz_flush(void)
+{
+	atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_FLUSH,
+				   NULL);
+}
+
+void notrace lib_ring_buffer_tick_nohz_stop(void)
+{
+	atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_STOP,
+				   NULL);
+}
+
+void notrace lib_ring_buffer_tick_nohz_restart(void)
+{
+	atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_RESTART,
+				   NULL);
+}
+#endif /* defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) */
+
+/*
+ * Holds CPU hotplug.
+ */
+static void channel_unregister_notifiers(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	int cpu;
+
+	channel_iterator_unregister_notifiers(chan);
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+#ifdef CONFIG_NO_HZ
+		/*
+		 * Remove the nohz notifier first, so we are certain we stop
+		 * the timers.
+		 */
+		atomic_notifier_chain_unregister(&tick_nohz_notifier,
+						 &chan->tick_nohz_notifier);
+		/*
+		 * ring_buffer_nohz_lock will not be needed below, because
+		 * we just removed the notifiers, which were the only source of
+		 * concurrency.
+		 */
+#endif /* CONFIG_NO_HZ */
+#ifdef CONFIG_HOTPLUG_CPU
+		get_online_cpus();
+		chan->cpu_hp_enable = 0;
+		for_each_online_cpu(cpu) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf,
+							      cpu);
+			lib_ring_buffer_stop_switch_timer(buf);
+			lib_ring_buffer_stop_read_timer(buf);
+		}
+		put_online_cpus();
+		unregister_cpu_notifier(&chan->cpu_hp_notifier);
+#else
+		for_each_possible_cpu(cpu) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf,
+							      cpu);
+			lib_ring_buffer_stop_switch_timer(buf);
+			lib_ring_buffer_stop_read_timer(buf);
+		}
+#endif
+	} else {
+		struct lib_ring_buffer *buf = chan->backend.buf;
+
+		lib_ring_buffer_stop_switch_timer(buf);
+		lib_ring_buffer_stop_read_timer(buf);
+	}
+	channel_backend_unregister_notifiers(&chan->backend);
+}
+
+static void channel_free(struct channel *chan)
+{
+	channel_iterator_free(chan);
+	channel_backend_free(&chan->backend);
+	kfree(chan);
+}
+
+/**
+ * channel_create - Create channel.
+ * @config: ring buffer instance configuration
+ * @name: name of the channel
+ * @priv: ring buffer client private data
+ * @buf_addr: pointer the the beginning of the preallocated buffer contiguous
+ *            address mapping. It is used only by RING_BUFFER_STATIC
+ *            configuration. It can be set to NULL for other backends.
+ * @subbuf_size: subbuffer size
+ * @num_subbuf: number of subbuffers
+ * @switch_timer_interval: Time interval (in us) to fill sub-buffers with
+ *                         padding to let readers get those sub-buffers.
+ *                         Used for live streaming.
+ * @read_timer_interval: Time interval (in us) to wake up pending readers.
+ *
+ * Holds cpu hotplug.
+ * Returns NULL on failure.
+ */
+struct channel *channel_create(const struct lib_ring_buffer_config *config,
+		   const char *name, void *priv, void *buf_addr,
+		   size_t subbuf_size,
+		   size_t num_subbuf, unsigned int switch_timer_interval,
+		   unsigned int read_timer_interval)
+{
+	int ret, cpu;
+	struct channel *chan;
+
+	if (lib_ring_buffer_check_config(config, switch_timer_interval,
+					 read_timer_interval))
+		return NULL;
+
+	chan = kzalloc(sizeof(struct channel), GFP_KERNEL);
+	if (!chan)
+		return NULL;
+
+	ret = channel_backend_init(&chan->backend, name, config, priv,
+				   subbuf_size, num_subbuf);
+	if (ret)
+		goto error;
+
+	ret = channel_iterator_init(chan);
+	if (ret)
+		goto error_free_backend;
+
+	chan->commit_count_mask = (~0UL >> chan->backend.num_subbuf_order);
+	chan->switch_timer_interval = usecs_to_jiffies(switch_timer_interval);
+	chan->read_timer_interval = usecs_to_jiffies(read_timer_interval);
+	kref_init(&chan->ref);
+	init_waitqueue_head(&chan->read_wait);
+	init_waitqueue_head(&chan->hp_wait);
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+#if defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER)
+		/* Only benefit from NO_HZ idle with per-cpu buffers for now. */
+		chan->tick_nohz_notifier.notifier_call =
+			ring_buffer_tick_nohz_callback;
+		chan->tick_nohz_notifier.priority = ~0U;
+		atomic_notifier_chain_register(&tick_nohz_notifier,
+				       &chan->tick_nohz_notifier);
+#endif /* defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) */
+
+		/*
+		 * In case of non-hotplug cpu, if the ring-buffer is allocated
+		 * in early initcall, it will not be notified of secondary cpus.
+		 * In that off case, we need to allocate for all possible cpus.
+		 */
+#ifdef CONFIG_HOTPLUG_CPU
+		chan->cpu_hp_notifier.notifier_call =
+				lib_ring_buffer_cpu_hp_callback;
+		chan->cpu_hp_notifier.priority = 6;
+		register_cpu_notifier(&chan->cpu_hp_notifier);
+
+		get_online_cpus();
+		for_each_online_cpu(cpu) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf,
+							       cpu);
+			spin_lock(&per_cpu(ring_buffer_nohz_lock, cpu));
+			lib_ring_buffer_start_switch_timer(buf);
+			lib_ring_buffer_start_read_timer(buf);
+			spin_unlock(&per_cpu(ring_buffer_nohz_lock, cpu));
+		}
+		chan->cpu_hp_enable = 1;
+		put_online_cpus();
+#else
+		for_each_possible_cpu(cpu) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf,
+							      cpu);
+			spin_lock(&per_cpu(ring_buffer_nohz_lock, cpu));
+			lib_ring_buffer_start_switch_timer(buf);
+			lib_ring_buffer_start_read_timer(buf);
+			spin_unlock(&per_cpu(ring_buffer_nohz_lock, cpu));
+		}
+#endif
+	} else {
+		struct lib_ring_buffer *buf = chan->backend.buf;
+
+		lib_ring_buffer_start_switch_timer(buf);
+		lib_ring_buffer_start_read_timer(buf);
+	}
+
+	return chan;
+
+error_free_backend:
+	channel_backend_free(&chan->backend);
+error:
+	kfree(chan);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(channel_create);
+
+static
+void channel_release(struct kref *kref)
+{
+	struct channel *chan = container_of(kref, struct channel, ref);
+	channel_free(chan);
+}
+
+/**
+ * channel_destroy - Finalize, wait for q.s. and destroy channel.
+ * @chan: channel to destroy
+ *
+ * Holds cpu hotplug.
+ * Call "destroy" callback, finalize channels, and then decrement the
+ * channel reference count.  Note that when readers have completed data
+ * consumption of finalized channels, get_subbuf() will return -ENODATA.
+ * They should release their handle at that point.  Returns the private
+ * data pointer.
+ */
+void *channel_destroy(struct channel *chan)
+{
+	int cpu;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	void *priv;
+
+	channel_unregister_notifiers(chan);
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		/*
+		 * No need to hold cpu hotplug, because all notifiers have been
+		 * unregistered.
+		 */
+		for_each_channel_cpu(cpu, chan) {
+			struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf,
+							      cpu);
+
+			if (config->cb.buffer_finalize)
+				config->cb.buffer_finalize(buf,
+							   chan->backend.priv,
+							   cpu);
+			if (buf->backend.allocated)
+				lib_ring_buffer_switch_slow(buf, SWITCH_FLUSH);
+			/*
+			 * Perform flush before writing to finalized.
+			 */
+			smp_wmb();
+			ACCESS_ONCE(buf->finalized) = 1;
+			wake_up_interruptible(&buf->read_wait);
+		}
+	} else {
+		struct lib_ring_buffer *buf = chan->backend.buf;
+
+		if (config->cb.buffer_finalize)
+			config->cb.buffer_finalize(buf, chan->backend.priv, -1);
+		if (buf->backend.allocated)
+			lib_ring_buffer_switch_slow(buf, SWITCH_FLUSH);
+		/*
+		 * Perform flush before writing to finalized.
+		 */
+		smp_wmb();
+		ACCESS_ONCE(buf->finalized) = 1;
+		wake_up_interruptible(&buf->read_wait);
+	}
+	ACCESS_ONCE(chan->finalized) = 1;
+	wake_up_interruptible(&chan->hp_wait);
+	wake_up_interruptible(&chan->read_wait);
+	priv = chan->backend.priv;
+	kref_put(&chan->ref, channel_release);
+	return priv;
+}
+EXPORT_SYMBOL_GPL(channel_destroy);
+
+struct lib_ring_buffer *channel_get_ring_buffer(
+					const struct lib_ring_buffer_config *config,
+					struct channel *chan, int cpu)
+{
+	if (config->alloc == RING_BUFFER_ALLOC_GLOBAL)
+		return chan->backend.buf;
+	else
+		return per_cpu_ptr(chan->backend.buf, cpu);
+}
+EXPORT_SYMBOL_GPL(channel_get_ring_buffer);
+
+int lib_ring_buffer_open_read(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+
+	if (!atomic_long_add_unless(&buf->active_readers, 1, 1))
+		return -EBUSY;
+	kref_get(&chan->ref);
+	smp_mb__after_atomic_inc();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_open_read);
+
+void lib_ring_buffer_release_read(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+
+	CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1);
+	smp_mb__before_atomic_dec();
+	atomic_long_dec(&buf->active_readers);
+	kref_put(&chan->ref, channel_release);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_release_read);
+
+/*
+ * Promote compiler barrier to a smp_mb().
+ * For the specific ring buffer case, this IPI call should be removed if the
+ * architecture does not reorder writes.  This should eventually be provided by
+ * a separate architecture-specific infrastructure.
+ */
+static void remote_mb(void *info)
+{
+	smp_mb();
+}
+
+/**
+ * lib_ring_buffer_snapshot - save subbuffer position snapshot (for read)
+ * @buf: ring buffer
+ * @consumed: consumed count indicating the position where to read
+ * @produced: produced count, indicates position when to stop reading
+ *
+ * Returns -ENODATA if buffer is finalized, -EAGAIN if there is currently no
+ * data to read at consumed position, or 0 if the get operation succeeds.
+ * Busy-loop trying to get data if the tick_nohz sequence lock is held.
+ */
+
+int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf,
+			     unsigned long *consumed, unsigned long *produced)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long consumed_cur, write_offset;
+	int finalized;
+
+retry:
+	finalized = ACCESS_ONCE(buf->finalized);
+	/*
+	 * Read finalized before counters.
+	 */
+	smp_rmb();
+	consumed_cur = atomic_long_read(&buf->consumed);
+	/*
+	 * No need to issue a memory barrier between consumed count read and
+	 * write offset read, because consumed count can only change
+	 * concurrently in overwrite mode, and we keep a sequence counter
+	 * identifier derived from the write offset to check we are getting
+	 * the same sub-buffer we are expecting (the sub-buffers are atomically
+	 * "tagged" upon writes, tags are checked upon read).
+	 */
+	write_offset = v_read(config, &buf->offset);
+
+	/*
+	 * Check that we are not about to read the same subbuffer in
+	 * which the writer head is.
+	 */
+	if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_cur, chan)
+	    == 0)
+		goto nodata;
+
+	*consumed = consumed_cur;
+	*produced = subbuf_trunc(write_offset, chan);
+
+	return 0;
+
+nodata:
+	/*
+	 * The memory barriers __wait_event()/wake_up_interruptible() take care
+	 * of "raw_spin_is_locked" memory ordering.
+	 */
+	if (finalized)
+		return -ENODATA;
+	else if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock))
+		goto retry;
+	else
+		return -EAGAIN;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_snapshot);
+
+/**
+ * lib_ring_buffer_put_snapshot - move consumed counter forward
+ *
+ * Should only be called from consumer context.
+ * @buf: ring buffer
+ * @consumed_new: new consumed count value
+ */
+void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf,
+				   unsigned long consumed_new)
+{
+	struct lib_ring_buffer_backend *bufb = &buf->backend;
+	struct channel *chan = bufb->chan;
+	unsigned long consumed;
+
+	CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1);
+
+	/*
+	 * Only push the consumed value forward.
+	 * If the consumed cmpxchg fails, this is because we have been pushed by
+	 * the writer in flight recorder mode.
+	 */
+	consumed = atomic_long_read(&buf->consumed);
+	while ((long) consumed - (long) consumed_new < 0)
+		consumed = atomic_long_cmpxchg(&buf->consumed, consumed,
+					       consumed_new);
+	/* Wake-up the metadata producer */
+	wake_up_interruptible(&buf->write_wait);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_move_consumer);
+
+/**
+ * lib_ring_buffer_get_subbuf - get exclusive access to subbuffer for reading
+ * @buf: ring buffer
+ * @consumed: consumed count indicating the position where to read
+ *
+ * Returns -ENODATA if buffer is finalized, -EAGAIN if there is currently no
+ * data to read at consumed position, or 0 if the get operation succeeds.
+ * Busy-loop trying to get data if the tick_nohz sequence lock is held.
+ */
+int lib_ring_buffer_get_subbuf(struct lib_ring_buffer *buf,
+			       unsigned long consumed)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long consumed_cur, consumed_idx, commit_count, write_offset;
+	int ret;
+	int finalized;
+
+retry:
+	finalized = ACCESS_ONCE(buf->finalized);
+	/*
+	 * Read finalized before counters.
+	 */
+	smp_rmb();
+	consumed_cur = atomic_long_read(&buf->consumed);
+	consumed_idx = subbuf_index(consumed, chan);
+	commit_count = v_read(config, &buf->commit_cold[consumed_idx].cc_sb);
+	/*
+	 * Make sure we read the commit count before reading the buffer
+	 * data and the write offset. Correct consumed offset ordering
+	 * wrt commit count is insured by the use of cmpxchg to update
+	 * the consumed offset.
+	 * smp_call_function_single can fail if the remote CPU is offline,
+	 * this is OK because then there is no wmb to execute there.
+	 * If our thread is executing on the same CPU as the on the buffers
+	 * belongs to, we don't have to synchronize it at all. If we are
+	 * migrated, the scheduler will take care of the memory barriers.
+	 * Normally, smp_call_function_single() should ensure program order when
+	 * executing the remote function, which implies that it surrounds the
+	 * function execution with :
+	 * smp_mb()
+	 * send IPI
+	 * csd_lock_wait
+	 *                recv IPI
+	 *                smp_mb()
+	 *                exec. function
+	 *                smp_mb()
+	 *                csd unlock
+	 * smp_mb()
+	 *
+	 * However, smp_call_function_single() does not seem to clearly execute
+	 * such barriers. It depends on spinlock semantic to provide the barrier
+	 * before executing the IPI and, when busy-looping, csd_lock_wait only
+	 * executes smp_mb() when it has to wait for the other CPU.
+	 *
+	 * I don't trust this code. Therefore, let's add the smp_mb() sequence
+	 * required ourself, even if duplicated. It has no performance impact
+	 * anyway.
+	 *
+	 * smp_mb() is needed because smp_rmb() and smp_wmb() only order read vs
+	 * read and write vs write. They do not ensure core synchronization. We
+	 * really have to ensure total order between the 3 barriers running on
+	 * the 2 CPUs.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		if (config->sync == RING_BUFFER_SYNC_PER_CPU
+		    && config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+			if (raw_smp_processor_id() != buf->backend.cpu) {
+				/* Total order with IPI handler smp_mb() */
+				smp_mb();
+				smp_call_function_single(buf->backend.cpu,
+							 remote_mb, NULL, 1);
+				/* Total order with IPI handler smp_mb() */
+				smp_mb();
+			}
+		} else {
+			/* Total order with IPI handler smp_mb() */
+			smp_mb();
+			smp_call_function(remote_mb, NULL, 1);
+			/* Total order with IPI handler smp_mb() */
+			smp_mb();
+		}
+	} else {
+		/*
+		 * Local rmb to match the remote wmb to read the commit count
+		 * before the buffer data and the write offset.
+		 */
+		smp_rmb();
+	}
+
+	write_offset = v_read(config, &buf->offset);
+
+	/*
+	 * Check that the buffer we are getting is after or at consumed_cur
+	 * position.
+	 */
+	if ((long) subbuf_trunc(consumed, chan)
+	    - (long) subbuf_trunc(consumed_cur, chan) < 0)
+		goto nodata;
+
+	/*
+	 * Check that the subbuffer we are trying to consume has been
+	 * already fully committed.
+	 */
+	if (((commit_count - chan->backend.subbuf_size)
+	     & chan->commit_count_mask)
+	    - (buf_trunc(consumed_cur, chan)
+	       >> chan->backend.num_subbuf_order)
+	    != 0)
+		goto nodata;
+
+	/*
+	 * Check that we are not about to read the same subbuffer in
+	 * which the writer head is.
+	 */
+	if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_cur, chan)
+	    == 0)
+		goto nodata;
+
+	/*
+	 * Failure to get the subbuffer causes a busy-loop retry without going
+	 * to a wait queue. These are caused by short-lived race windows where
+	 * the writer is getting access to a subbuffer we were trying to get
+	 * access to. Also checks that the "consumed" buffer count we are
+	 * looking for matches the one contained in the subbuffer id.
+	 */
+	ret = update_read_sb_index(config, &buf->backend, &chan->backend,
+				   consumed_idx, buf_trunc_val(consumed, chan));
+	if (ret)
+		goto retry;
+	subbuffer_id_clear_noref(config, &buf->backend.buf_rsb.id);
+
+	buf->get_subbuf_consumed = consumed;
+	buf->get_subbuf = 1;
+
+	return 0;
+
+nodata:
+	/*
+	 * The memory barriers __wait_event()/wake_up_interruptible() take care
+	 * of "raw_spin_is_locked" memory ordering.
+	 */
+	if (finalized)
+		return -ENODATA;
+	else if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock))
+		goto retry;
+	else
+		return -EAGAIN;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_get_subbuf);
+
+/**
+ * lib_ring_buffer_put_subbuf - release exclusive subbuffer access
+ * @buf: ring buffer
+ */
+void lib_ring_buffer_put_subbuf(struct lib_ring_buffer *buf)
+{
+	struct lib_ring_buffer_backend *bufb = &buf->backend;
+	struct channel *chan = bufb->chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long read_sb_bindex, consumed_idx, consumed;
+
+	CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1);
+
+	if (!buf->get_subbuf) {
+		/*
+		 * Reader puts a subbuffer it did not get.
+		 */
+		CHAN_WARN_ON(chan, 1);
+		return;
+	}
+	consumed = buf->get_subbuf_consumed;
+	buf->get_subbuf = 0;
+
+	/*
+	 * Clear the records_unread counter. (overruns counter)
+	 * Can still be non-zero if a file reader simply grabbed the data
+	 * without using iterators.
+	 * Can be below zero if an iterator is used on a snapshot more than
+	 * once.
+	 */
+	read_sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id);
+	v_add(config, v_read(config,
+			     &bufb->array[read_sb_bindex]->records_unread),
+	      &bufb->records_read);
+	v_set(config, &bufb->array[read_sb_bindex]->records_unread, 0);
+	CHAN_WARN_ON(chan, config->mode == RING_BUFFER_OVERWRITE
+		     && subbuffer_id_is_noref(config, bufb->buf_rsb.id));
+	subbuffer_id_set_noref(config, &bufb->buf_rsb.id);
+
+	/*
+	 * Exchange the reader subbuffer with the one we put in its place in the
+	 * writer subbuffer table. Expect the original consumed count. If
+	 * update_read_sb_index fails, this is because the writer updated the
+	 * subbuffer concurrently. We should therefore keep the subbuffer we
+	 * currently have: it has become invalid to try reading this sub-buffer
+	 * consumed count value anyway.
+	 */
+	consumed_idx = subbuf_index(consumed, chan);
+	update_read_sb_index(config, &buf->backend, &chan->backend,
+			     consumed_idx, buf_trunc_val(consumed, chan));
+	/*
+	 * update_read_sb_index return value ignored. Don't exchange sub-buffer
+	 * if the writer concurrently updated it.
+	 */
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_put_subbuf);
+
+/*
+ * cons_offset is an iterator on all subbuffer offsets between the reader
+ * position and the writer position. (inclusive)
+ */
+static
+void lib_ring_buffer_print_subbuffer_errors(struct lib_ring_buffer *buf,
+					    struct channel *chan,
+					    unsigned long cons_offset,
+					    int cpu)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long cons_idx, commit_count, commit_count_sb;
+
+	cons_idx = subbuf_index(cons_offset, chan);
+	commit_count = v_read(config, &buf->commit_hot[cons_idx].cc);
+	commit_count_sb = v_read(config, &buf->commit_cold[cons_idx].cc_sb);
+
+	if (subbuf_offset(commit_count, chan) != 0)
+		printk(KERN_WARNING
+		       "ring buffer %s, cpu %d: "
+		       "commit count in subbuffer %lu,\n"
+		       "expecting multiples of %lu bytes\n"
+		       "  [ %lu bytes committed, %lu bytes reader-visible ]\n",
+		       chan->backend.name, cpu, cons_idx,
+		       chan->backend.subbuf_size,
+		       commit_count, commit_count_sb);
+
+	printk(KERN_DEBUG "ring buffer: %s, cpu %d: %lu bytes committed\n",
+	       chan->backend.name, cpu, commit_count);
+}
+
+static
+void lib_ring_buffer_print_buffer_errors(struct lib_ring_buffer *buf,
+					 struct channel *chan,
+					 void *priv, int cpu)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long write_offset, cons_offset;
+
+	/*
+	 * Can be called in the error path of allocation when
+	 * trans_channel_data is not yet set.
+	 */
+	if (!chan)
+		return;
+	/*
+	 * No need to order commit_count, write_offset and cons_offset reads
+	 * because we execute at teardown when no more writer nor reader
+	 * references are left.
+	 */
+	write_offset = v_read(config, &buf->offset);
+	cons_offset = atomic_long_read(&buf->consumed);
+	if (write_offset != cons_offset)
+		printk(KERN_DEBUG
+		       "ring buffer %s, cpu %d: "
+		       "non-consumed data\n"
+		       "  [ %lu bytes written, %lu bytes read ]\n",
+		       chan->backend.name, cpu, write_offset, cons_offset);
+
+	for (cons_offset = atomic_long_read(&buf->consumed);
+	     (long) (subbuf_trunc((unsigned long) v_read(config, &buf->offset),
+				  chan)
+		     - cons_offset) > 0;
+	     cons_offset = subbuf_align(cons_offset, chan))
+		lib_ring_buffer_print_subbuffer_errors(buf, chan, cons_offset,
+						       cpu);
+}
+
+static
+void lib_ring_buffer_print_errors(struct channel *chan,
+				  struct lib_ring_buffer *buf, int cpu)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	void *priv = chan->backend.priv;
+
+	printk(KERN_DEBUG "ring buffer %s, cpu %d: %lu records written, "
+			  "%lu records overrun\n",
+			  chan->backend.name, cpu,
+			  v_read(config, &buf->records_count),
+			  v_read(config, &buf->records_overrun));
+
+	if (v_read(config, &buf->records_lost_full)
+	    || v_read(config, &buf->records_lost_wrap)
+	    || v_read(config, &buf->records_lost_big))
+		printk(KERN_WARNING
+		       "ring buffer %s, cpu %d: records were lost. Caused by:\n"
+		       "  [ %lu buffer full, %lu nest buffer wrap-around, "
+		       "%lu event too big ]\n",
+		       chan->backend.name, cpu,
+		       v_read(config, &buf->records_lost_full),
+		       v_read(config, &buf->records_lost_wrap),
+		       v_read(config, &buf->records_lost_big));
+
+	lib_ring_buffer_print_buffer_errors(buf, chan, priv, cpu);
+}
+
+/*
+ * lib_ring_buffer_switch_old_start: Populate old subbuffer header.
+ *
+ * Only executed when the buffer is finalized, in SWITCH_FLUSH.
+ */
+static
+void lib_ring_buffer_switch_old_start(struct lib_ring_buffer *buf,
+				      struct channel *chan,
+				      struct switch_offsets *offsets,
+				      u64 tsc)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long oldidx = subbuf_index(offsets->old, chan);
+	unsigned long commit_count;
+
+	config->cb.buffer_begin(buf, tsc, oldidx);
+
+	/*
+	 * Order all writes to buffer before the commit count update that will
+	 * determine that the subbuffer is full.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		/*
+		 * Must write slot data before incrementing commit count.  This
+		 * compiler barrier is upgraded into a smp_mb() by the IPI sent
+		 * by get_subbuf().
+		 */
+		barrier();
+	} else
+		smp_wmb();
+	v_add(config, config->cb.subbuffer_header_size(),
+	      &buf->commit_hot[oldidx].cc);
+	commit_count = v_read(config, &buf->commit_hot[oldidx].cc);
+	/* Check if the written buffer has to be delivered */
+	lib_ring_buffer_check_deliver(config, buf, chan, offsets->old,
+				      commit_count, oldidx);
+	lib_ring_buffer_write_commit_counter(config, buf, chan, oldidx,
+					     offsets->old, commit_count,
+					     config->cb.subbuffer_header_size());
+}
+
+/*
+ * lib_ring_buffer_switch_old_end: switch old subbuffer
+ *
+ * Note : offset_old should never be 0 here. It is ok, because we never perform
+ * buffer switch on an empty subbuffer in SWITCH_ACTIVE mode. The caller
+ * increments the offset_old value when doing a SWITCH_FLUSH on an empty
+ * subbuffer.
+ */
+static
+void lib_ring_buffer_switch_old_end(struct lib_ring_buffer *buf,
+				    struct channel *chan,
+				    struct switch_offsets *offsets,
+				    u64 tsc)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long oldidx = subbuf_index(offsets->old - 1, chan);
+	unsigned long commit_count, padding_size, data_size;
+
+	data_size = subbuf_offset(offsets->old - 1, chan) + 1;
+	padding_size = chan->backend.subbuf_size - data_size;
+	subbuffer_set_data_size(config, &buf->backend, oldidx, data_size);
+
+	/*
+	 * Order all writes to buffer before the commit count update that will
+	 * determine that the subbuffer is full.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		/*
+		 * Must write slot data before incrementing commit count.  This
+		 * compiler barrier is upgraded into a smp_mb() by the IPI sent
+		 * by get_subbuf().
+		 */
+		barrier();
+	} else
+		smp_wmb();
+	v_add(config, padding_size, &buf->commit_hot[oldidx].cc);
+	commit_count = v_read(config, &buf->commit_hot[oldidx].cc);
+	lib_ring_buffer_check_deliver(config, buf, chan, offsets->old - 1,
+				      commit_count, oldidx);
+	lib_ring_buffer_write_commit_counter(config, buf, chan, oldidx,
+					     offsets->old, commit_count,
+					     padding_size);
+}
+
+/*
+ * lib_ring_buffer_switch_new_start: Populate new subbuffer.
+ *
+ * This code can be executed unordered : writers may already have written to the
+ * sub-buffer before this code gets executed, caution.  The commit makes sure
+ * that this code is executed before the deliver of this sub-buffer.
+ */
+static
+void lib_ring_buffer_switch_new_start(struct lib_ring_buffer *buf,
+				      struct channel *chan,
+				      struct switch_offsets *offsets,
+				      u64 tsc)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long beginidx = subbuf_index(offsets->begin, chan);
+	unsigned long commit_count;
+
+	config->cb.buffer_begin(buf, tsc, beginidx);
+
+	/*
+	 * Order all writes to buffer before the commit count update that will
+	 * determine that the subbuffer is full.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		/*
+		 * Must write slot data before incrementing commit count.  This
+		 * compiler barrier is upgraded into a smp_mb() by the IPI sent
+		 * by get_subbuf().
+		 */
+		barrier();
+	} else
+		smp_wmb();
+	v_add(config, config->cb.subbuffer_header_size(),
+	      &buf->commit_hot[beginidx].cc);
+	commit_count = v_read(config, &buf->commit_hot[beginidx].cc);
+	/* Check if the written buffer has to be delivered */
+	lib_ring_buffer_check_deliver(config, buf, chan, offsets->begin,
+				      commit_count, beginidx);
+	lib_ring_buffer_write_commit_counter(config, buf, chan, beginidx,
+					     offsets->begin, commit_count,
+					     config->cb.subbuffer_header_size());
+}
+
+/*
+ * lib_ring_buffer_switch_new_end: finish switching current subbuffer
+ *
+ * The only remaining threads could be the ones with pending commits. They will
+ * have to do the deliver themselves.
+ */
+static
+void lib_ring_buffer_switch_new_end(struct lib_ring_buffer *buf,
+					    struct channel *chan,
+					    struct switch_offsets *offsets,
+					    u64 tsc)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long endidx = subbuf_index(offsets->end - 1, chan);
+	unsigned long commit_count, padding_size, data_size;
+
+	data_size = subbuf_offset(offsets->end - 1, chan) + 1;
+	padding_size = chan->backend.subbuf_size - data_size;
+	subbuffer_set_data_size(config, &buf->backend, endidx, data_size);
+
+	/*
+	 * Order all writes to buffer before the commit count update that will
+	 * determine that the subbuffer is full.
+	 */
+	if (config->ipi == RING_BUFFER_IPI_BARRIER) {
+		/*
+		 * Must write slot data before incrementing commit count.  This
+		 * compiler barrier is upgraded into a smp_mb() by the IPI sent
+		 * by get_subbuf().
+		 */
+		barrier();
+	} else
+		smp_wmb();
+	v_add(config, padding_size, &buf->commit_hot[endidx].cc);
+	commit_count = v_read(config, &buf->commit_hot[endidx].cc);
+	lib_ring_buffer_check_deliver(config, buf, chan, offsets->end - 1,
+				  commit_count, endidx);
+	lib_ring_buffer_write_commit_counter(config, buf, chan, endidx,
+					     offsets->end, commit_count,
+					     padding_size);
+}
+
+/*
+ * Returns :
+ * 0 if ok
+ * !0 if execution must be aborted.
+ */
+static
+int lib_ring_buffer_try_switch_slow(enum switch_mode mode,
+				    struct lib_ring_buffer *buf,
+				    struct channel *chan,
+				    struct switch_offsets *offsets,
+				    u64 *tsc)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long off;
+
+	offsets->begin = v_read(config, &buf->offset);
+	offsets->old = offsets->begin;
+	offsets->switch_old_start = 0;
+	off = subbuf_offset(offsets->begin, chan);
+
+	*tsc = config->cb.ring_buffer_clock_read(chan);
+
+	/*
+	 * Ensure we flush the header of an empty subbuffer when doing the
+	 * finalize (SWITCH_FLUSH). This ensures that we end up knowing the
+	 * total data gathering duration even if there were no records saved
+	 * after the last buffer switch.
+	 * In SWITCH_ACTIVE mode, switch the buffer when it contains events.
+	 * SWITCH_ACTIVE only flushes the current subbuffer, dealing with end of
+	 * subbuffer header as appropriate.
+	 * The next record that reserves space will be responsible for
+	 * populating the following subbuffer header. We choose not to populate
+	 * the next subbuffer header here because we want to be able to use
+	 * SWITCH_ACTIVE for periodical buffer flush and CPU tick_nohz stop
+	 * buffer flush, which must guarantee that all the buffer content
+	 * (records and header timestamps) are visible to the reader. This is
+	 * required for quiescence guarantees for the fusion merge.
+	 */
+	if (mode == SWITCH_FLUSH || off > 0) {
+		if (unlikely(off == 0)) {
+			/*
+			 * The client does not save any header information.
+			 * Don't switch empty subbuffer on finalize, because it
+			 * is invalid to deliver a completely empty subbuffer.
+			 */
+			if (!config->cb.subbuffer_header_size())
+				return -1;
+			/*
+			 * Need to write the subbuffer start header on finalize.
+			 */
+			offsets->switch_old_start = 1;
+		}
+		offsets->begin = subbuf_align(offsets->begin, chan);
+	} else
+		return -1;	/* we do not have to switch : buffer is empty */
+	/* Note: old points to the next subbuf at offset 0 */
+	offsets->end = offsets->begin;
+	return 0;
+}
+
+/*
+ * Force a sub-buffer switch. This operation is completely reentrant : can be
+ * called while tracing is active with absolutely no lock held.
+ *
+ * Note, however, that as a v_cmpxchg is used for some atomic
+ * operations, this function must be called from the CPU which owns the buffer
+ * for a ACTIVE flush.
+ */
+void lib_ring_buffer_switch_slow(struct lib_ring_buffer *buf, enum switch_mode mode)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct switch_offsets offsets;
+	unsigned long oldidx;
+	u64 tsc;
+
+	offsets.size = 0;
+
+	/*
+	 * Perform retryable operations.
+	 */
+	do {
+		if (lib_ring_buffer_try_switch_slow(mode, buf, chan, &offsets,
+						    &tsc))
+			return;	/* Switch not needed */
+	} while (v_cmpxchg(config, &buf->offset, offsets.old, offsets.end)
+		 != offsets.old);
+
+	/*
+	 * Atomically update last_tsc. This update races against concurrent
+	 * atomic updates, but the race will always cause supplementary full TSC
+	 * records, never the opposite (missing a full TSC record when it would
+	 * be needed).
+	 */
+	save_last_tsc(config, buf, tsc);
+
+	/*
+	 * Push the reader if necessary
+	 */
+	lib_ring_buffer_reserve_push_reader(buf, chan, offsets.old);
+
+	oldidx = subbuf_index(offsets.old, chan);
+	lib_ring_buffer_clear_noref(config, &buf->backend, oldidx);
+
+	/*
+	 * May need to populate header start on SWITCH_FLUSH.
+	 */
+	if (offsets.switch_old_start) {
+		lib_ring_buffer_switch_old_start(buf, chan, &offsets, tsc);
+		offsets.old += config->cb.subbuffer_header_size();
+	}
+
+	/*
+	 * Switch old subbuffer.
+	 */
+	lib_ring_buffer_switch_old_end(buf, chan, &offsets, tsc);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_slow);
+
+/*
+ * Returns :
+ * 0 if ok
+ * -ENOSPC if event size is too large for packet.
+ * -ENOBUFS if there is currently not enough space in buffer for the event.
+ * -EIO if data cannot be written into the buffer for any other reason.
+ */
+static
+int lib_ring_buffer_try_reserve_slow(struct lib_ring_buffer *buf,
+				     struct channel *chan,
+				     struct switch_offsets *offsets,
+				     struct lib_ring_buffer_ctx *ctx)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long reserve_commit_diff;
+
+	offsets->begin = v_read(config, &buf->offset);
+	offsets->old = offsets->begin;
+	offsets->switch_new_start = 0;
+	offsets->switch_new_end = 0;
+	offsets->switch_old_end = 0;
+	offsets->pre_header_padding = 0;
+
+	ctx->tsc = config->cb.ring_buffer_clock_read(chan);
+	if ((int64_t) ctx->tsc == -EIO)
+		return -EIO;
+
+	if (last_tsc_overflow(config, buf, ctx->tsc))
+		ctx->rflags |= RING_BUFFER_RFLAG_FULL_TSC;
+
+	if (unlikely(subbuf_offset(offsets->begin, ctx->chan) == 0)) {
+		offsets->switch_new_start = 1;		/* For offsets->begin */
+	} else {
+		offsets->size = config->cb.record_header_size(config, chan,
+						offsets->begin,
+						&offsets->pre_header_padding,
+						ctx);
+		offsets->size +=
+			lib_ring_buffer_align(offsets->begin + offsets->size,
+					      ctx->largest_align)
+			+ ctx->data_size;
+		if (unlikely(subbuf_offset(offsets->begin, chan) +
+			     offsets->size > chan->backend.subbuf_size)) {
+			offsets->switch_old_end = 1;	/* For offsets->old */
+			offsets->switch_new_start = 1;	/* For offsets->begin */
+		}
+	}
+	if (unlikely(offsets->switch_new_start)) {
+		unsigned long sb_index;
+
+		/*
+		 * We are typically not filling the previous buffer completely.
+		 */
+		if (likely(offsets->switch_old_end))
+			offsets->begin = subbuf_align(offsets->begin, chan);
+		offsets->begin = offsets->begin
+				 + config->cb.subbuffer_header_size();
+		/* Test new buffer integrity */
+		sb_index = subbuf_index(offsets->begin, chan);
+		reserve_commit_diff =
+		  (buf_trunc(offsets->begin, chan)
+		   >> chan->backend.num_subbuf_order)
+		  - ((unsigned long) v_read(config,
+					    &buf->commit_cold[sb_index].cc_sb)
+		     & chan->commit_count_mask);
+		if (likely(reserve_commit_diff == 0)) {
+			/* Next subbuffer not being written to. */
+			if (unlikely(config->mode != RING_BUFFER_OVERWRITE &&
+				subbuf_trunc(offsets->begin, chan)
+				 - subbuf_trunc((unsigned long)
+				     atomic_long_read(&buf->consumed), chan)
+				>= chan->backend.buf_size)) {
+				/*
+				 * We do not overwrite non consumed buffers
+				 * and we are full : record is lost.
+				 */
+				v_inc(config, &buf->records_lost_full);
+				return -ENOBUFS;
+			} else {
+				/*
+				 * Next subbuffer not being written to, and we
+				 * are either in overwrite mode or the buffer is
+				 * not full. It's safe to write in this new
+				 * subbuffer.
+				 */
+			}
+		} else {
+			/*
+			 * Next subbuffer reserve offset does not match the
+			 * commit offset. Drop record in producer-consumer and
+			 * overwrite mode. Caused by either a writer OOPS or too
+			 * many nested writes over a reserve/commit pair.
+			 */
+			v_inc(config, &buf->records_lost_wrap);
+			return -EIO;
+		}
+		offsets->size =
+			config->cb.record_header_size(config, chan,
+						offsets->begin,
+						&offsets->pre_header_padding,
+						ctx);
+		offsets->size +=
+			lib_ring_buffer_align(offsets->begin + offsets->size,
+					      ctx->largest_align)
+			+ ctx->data_size;
+		if (unlikely(subbuf_offset(offsets->begin, chan)
+			     + offsets->size > chan->backend.subbuf_size)) {
+			/*
+			 * Record too big for subbuffers, report error, don't
+			 * complete the sub-buffer switch.
+			 */
+			v_inc(config, &buf->records_lost_big);
+			return -ENOSPC;
+		} else {
+			/*
+			 * We just made a successful buffer switch and the
+			 * record fits in the new subbuffer. Let's write.
+			 */
+		}
+	} else {
+		/*
+		 * Record fits in the current buffer and we are not on a switch
+		 * boundary. It's safe to write.
+		 */
+	}
+	offsets->end = offsets->begin + offsets->size;
+
+	if (unlikely(subbuf_offset(offsets->end, chan) == 0)) {
+		/*
+		 * The offset_end will fall at the very beginning of the next
+		 * subbuffer.
+		 */
+		offsets->switch_new_end = 1;	/* For offsets->begin */
+	}
+	return 0;
+}
+
+/**
+ * lib_ring_buffer_reserve_slow - Atomic slot reservation in a buffer.
+ * @ctx: ring buffer context.
+ *
+ * Return : -NOBUFS if not enough space, -ENOSPC if event size too large,
+ * -EIO for other errors, else returns 0.
+ * It will take care of sub-buffer switching.
+ */
+int lib_ring_buffer_reserve_slow(struct lib_ring_buffer_ctx *ctx)
+{
+	struct channel *chan = ctx->chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	struct switch_offsets offsets;
+	int ret;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		buf = per_cpu_ptr(chan->backend.buf, ctx->cpu);
+	else
+		buf = chan->backend.buf;
+	ctx->buf = buf;
+
+	offsets.size = 0;
+
+	do {
+		ret = lib_ring_buffer_try_reserve_slow(buf, chan, &offsets,
+						       ctx);
+		if (unlikely(ret))
+			return ret;
+	} while (unlikely(v_cmpxchg(config, &buf->offset, offsets.old,
+				    offsets.end)
+			  != offsets.old));
+
+	/*
+	 * Atomically update last_tsc. This update races against concurrent
+	 * atomic updates, but the race will always cause supplementary full TSC
+	 * records, never the opposite (missing a full TSC record when it would
+	 * be needed).
+	 */
+	save_last_tsc(config, buf, ctx->tsc);
+
+	/*
+	 * Push the reader if necessary
+	 */
+	lib_ring_buffer_reserve_push_reader(buf, chan, offsets.end - 1);
+
+	/*
+	 * Clear noref flag for this subbuffer.
+	 */
+	lib_ring_buffer_clear_noref(config, &buf->backend,
+				    subbuf_index(offsets.end - 1, chan));
+
+	/*
+	 * Switch old subbuffer if needed.
+	 */
+	if (unlikely(offsets.switch_old_end)) {
+		lib_ring_buffer_clear_noref(config, &buf->backend,
+					    subbuf_index(offsets.old - 1, chan));
+		lib_ring_buffer_switch_old_end(buf, chan, &offsets, ctx->tsc);
+	}
+
+	/*
+	 * Populate new subbuffer.
+	 */
+	if (unlikely(offsets.switch_new_start))
+		lib_ring_buffer_switch_new_start(buf, chan, &offsets, ctx->tsc);
+
+	if (unlikely(offsets.switch_new_end))
+		lib_ring_buffer_switch_new_end(buf, chan, &offsets, ctx->tsc);
+
+	ctx->slot_size = offsets.size;
+	ctx->pre_offset = offsets.begin;
+	ctx->buf_offset = offsets.begin + offsets.pre_header_padding;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_reserve_slow);
+
+int __init init_lib_ring_buffer_frontend(void)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		spin_lock_init(&per_cpu(ring_buffer_nohz_lock, cpu));
+	return 0;
+}
+
+module_init(init_lib_ring_buffer_frontend);
+
+void __exit exit_lib_ring_buffer_frontend(void)
+{
+}
+
+module_exit(exit_lib_ring_buffer_frontend);
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c
new file mode 100644
index 0000000..1321b5f
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c
@@ -0,0 +1,798 @@
+/*
+ * ring_buffer_iterator.c
+ *
+ * (C) Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring buffer and channel iterators. Get each event of a channel in order. Uses
+ * a prio heap for per-cpu buffers, giving a O(log(NR_CPUS)) algorithmic
+ * complexity for the "get next event" operation.
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "../../wrapper/ringbuffer/iterator.h"
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+/*
+ * Safety factor taking into account internal kernel interrupt latency.
+ * Assuming 250ms worse-case latency.
+ */
+#define MAX_SYSTEM_LATENCY	250
+
+/*
+ * Maximum delta expected between trace clocks. At most 1 jiffy delta.
+ */
+#define MAX_CLOCK_DELTA		(jiffies_to_usecs(1) * 1000)
+
+/**
+ * lib_ring_buffer_get_next_record - Get the next record in a buffer.
+ * @chan: channel
+ * @buf: buffer
+ *
+ * Returns the size of the event read, -EAGAIN if buffer is empty, -ENODATA if
+ * buffer is empty and finalized. The buffer must already be opened for reading.
+ */
+ssize_t lib_ring_buffer_get_next_record(struct channel *chan,
+					struct lib_ring_buffer *buf)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer_iter *iter = &buf->iter;
+	int ret;
+
+restart:
+	switch (iter->state) {
+	case ITER_GET_SUBBUF:
+		ret = lib_ring_buffer_get_next_subbuf(buf);
+		if (ret && !ACCESS_ONCE(buf->finalized)
+		    && config->alloc == RING_BUFFER_ALLOC_GLOBAL) {
+			/*
+			 * Use "pull" scheme for global buffers. The reader
+			 * itself flushes the buffer to "pull" data not visible
+			 * to readers yet. Flush current subbuffer and re-try.
+			 *
+			 * Per-CPU buffers rather use a "push" scheme because
+			 * the IPI needed to flush all CPU's buffers is too
+			 * costly. In the "push" scheme, the reader waits for
+			 * the writer periodic deferrable timer to flush the
+			 * buffers (keeping track of a quiescent state
+			 * timestamp). Therefore, the writer "pushes" data out
+			 * of the buffers rather than letting the reader "pull"
+			 * data from the buffer.
+			 */
+			lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+			ret = lib_ring_buffer_get_next_subbuf(buf);
+		}
+		if (ret)
+			return ret;
+		iter->consumed = buf->cons_snapshot;
+		iter->data_size = lib_ring_buffer_get_read_data_size(config, buf);
+		iter->read_offset = iter->consumed;
+		/* skip header */
+		iter->read_offset += config->cb.subbuffer_header_size();
+		iter->state = ITER_TEST_RECORD;
+		goto restart;
+	case ITER_TEST_RECORD:
+		if (iter->read_offset - iter->consumed >= iter->data_size) {
+			iter->state = ITER_PUT_SUBBUF;
+		} else {
+			CHAN_WARN_ON(chan, !config->cb.record_get);
+			config->cb.record_get(config, chan, buf,
+					      iter->read_offset,
+					      &iter->header_len,
+					      &iter->payload_len,
+					      &iter->timestamp);
+			iter->read_offset += iter->header_len;
+			subbuffer_consume_record(config, &buf->backend);
+			iter->state = ITER_NEXT_RECORD;
+			return iter->payload_len;
+		}
+		goto restart;
+	case ITER_NEXT_RECORD:
+		iter->read_offset += iter->payload_len;
+		iter->state = ITER_TEST_RECORD;
+		goto restart;
+	case ITER_PUT_SUBBUF:
+		lib_ring_buffer_put_next_subbuf(buf);
+		iter->state = ITER_GET_SUBBUF;
+		goto restart;
+	default:
+		CHAN_WARN_ON(chan, 1);	/* Should not happen */
+		return -EPERM;
+	}
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_get_next_record);
+
+static int buf_is_higher(void *a, void *b)
+{
+	struct lib_ring_buffer *bufa = a;
+	struct lib_ring_buffer *bufb = b;
+
+	/* Consider lowest timestamps to be at the top of the heap */
+	return (bufa->iter.timestamp < bufb->iter.timestamp);
+}
+
+static
+void lib_ring_buffer_get_empty_buf_records(const struct lib_ring_buffer_config *config,
+					   struct channel *chan)
+{
+	struct lttng_ptr_heap *heap = &chan->iter.heap;
+	struct lib_ring_buffer *buf, *tmp;
+	ssize_t len;
+
+	list_for_each_entry_safe(buf, tmp, &chan->iter.empty_head,
+				 iter.empty_node) {
+		len = lib_ring_buffer_get_next_record(chan, buf);
+
+		/*
+		 * Deal with -EAGAIN and -ENODATA.
+		 * len >= 0 means record contains data.
+		 * -EBUSY should never happen, because we support only one
+		 * reader.
+		 */
+		switch (len) {
+		case -EAGAIN:
+			/* Keep node in empty list */
+			break;
+		case -ENODATA:
+			/*
+			 * Buffer is finalized. Don't add to list of empty
+			 * buffer, because it has no more data to provide, ever.
+			 */
+			list_del(&buf->iter.empty_node);
+			break;
+		case -EBUSY:
+			CHAN_WARN_ON(chan, 1);
+			break;
+		default:
+			/*
+			 * Insert buffer into the heap, remove from empty buffer
+			 * list.
+			 */
+			CHAN_WARN_ON(chan, len < 0);
+			list_del(&buf->iter.empty_node);
+			CHAN_WARN_ON(chan, lttng_heap_insert(heap, buf));
+		}
+	}
+}
+
+static
+void lib_ring_buffer_wait_for_qs(const struct lib_ring_buffer_config *config,
+				 struct channel *chan)
+{
+	u64 timestamp_qs;
+	unsigned long wait_msecs;
+
+	/*
+	 * No need to wait if no empty buffers are present.
+	 */
+	if (list_empty(&chan->iter.empty_head))
+		return;
+
+	timestamp_qs = config->cb.ring_buffer_clock_read(chan);
+	/*
+	 * We need to consider previously empty buffers.
+	 * Do a get next buf record on each of them. Add them to
+	 * the heap if they have data. If at least one of them
+	 * don't have data, we need to wait for
+	 * switch_timer_interval + MAX_SYSTEM_LATENCY (so we are sure the
+	 * buffers have been switched either by the timer or idle entry) and
+	 * check them again, adding them if they have data.
+	 */
+	lib_ring_buffer_get_empty_buf_records(config, chan);
+
+	/*
+	 * No need to wait if no empty buffers are present.
+	 */
+	if (list_empty(&chan->iter.empty_head))
+		return;
+
+	/*
+	 * We need to wait for the buffer switch timer to run. If the
+	 * CPU is idle, idle entry performed the switch.
+	 * TODO: we could optimize further by skipping the sleep if all
+	 * empty buffers belong to idle or offline cpus.
+	 */
+	wait_msecs = jiffies_to_msecs(chan->switch_timer_interval);
+	wait_msecs += MAX_SYSTEM_LATENCY;
+	msleep(wait_msecs);
+	lib_ring_buffer_get_empty_buf_records(config, chan);
+	/*
+	 * Any buffer still in the empty list here cannot possibly
+	 * contain an event with a timestamp prior to "timestamp_qs".
+	 * The new quiescent state timestamp is the one we grabbed
+	 * before waiting for buffer data.  It is therefore safe to
+	 * ignore empty buffers up to last_qs timestamp for fusion
+	 * merge.
+	 */
+	chan->iter.last_qs = timestamp_qs;
+}
+
+/**
+ * channel_get_next_record - Get the next record in a channel.
+ * @chan: channel
+ * @ret_buf: the buffer in which the event is located (output)
+ *
+ * Returns the size of new current event, -EAGAIN if all buffers are empty,
+ * -ENODATA if all buffers are empty and finalized. The channel must already be
+ * opened for reading.
+ */
+
+ssize_t channel_get_next_record(struct channel *chan,
+				struct lib_ring_buffer **ret_buf)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	struct lttng_ptr_heap *heap;
+	ssize_t len;
+
+	if (config->alloc == RING_BUFFER_ALLOC_GLOBAL) {
+		*ret_buf = channel_get_ring_buffer(config, chan, 0);
+		return lib_ring_buffer_get_next_record(chan, *ret_buf);
+	}
+
+	heap = &chan->iter.heap;
+
+	/*
+	 * get next record for topmost buffer.
+	 */
+	buf = lttng_heap_maximum(heap);
+	if (buf) {
+		len = lib_ring_buffer_get_next_record(chan, buf);
+		/*
+		 * Deal with -EAGAIN and -ENODATA.
+		 * len >= 0 means record contains data.
+		 */
+		switch (len) {
+		case -EAGAIN:
+			buf->iter.timestamp = 0;
+			list_add(&buf->iter.empty_node, &chan->iter.empty_head);
+			/* Remove topmost buffer from the heap */
+			CHAN_WARN_ON(chan, lttng_heap_remove(heap) != buf);
+			break;
+		case -ENODATA:
+			/*
+			 * Buffer is finalized. Remove buffer from heap and
+			 * don't add to list of empty buffer, because it has no
+			 * more data to provide, ever.
+			 */
+			CHAN_WARN_ON(chan, lttng_heap_remove(heap) != buf);
+			break;
+		case -EBUSY:
+			CHAN_WARN_ON(chan, 1);
+			break;
+		default:
+			/*
+			 * Reinsert buffer into the heap. Note that heap can be
+			 * partially empty, so we need to use
+			 * lttng_heap_replace_max().
+			 */
+			CHAN_WARN_ON(chan, len < 0);
+			CHAN_WARN_ON(chan, lttng_heap_replace_max(heap, buf) != buf);
+			break;
+		}
+	}
+
+	buf = lttng_heap_maximum(heap);
+	if (!buf || buf->iter.timestamp > chan->iter.last_qs) {
+		/*
+		 * Deal with buffers previously showing no data.
+		 * Add buffers containing data to the heap, update
+		 * last_qs.
+		 */
+		lib_ring_buffer_wait_for_qs(config, chan);
+	}
+
+	*ret_buf = buf = lttng_heap_maximum(heap);
+	if (buf) {
+		/*
+		 * If this warning triggers, you probably need to check your
+		 * system interrupt latency. Typical causes: too many printk()
+		 * output going to a serial console with interrupts off.
+		 * Allow for MAX_CLOCK_DELTA ns timestamp delta going backward.
+		 * Observed on SMP KVM setups with trace_clock().
+		 */
+		if (chan->iter.last_timestamp
+		    > (buf->iter.timestamp + MAX_CLOCK_DELTA)) {
+			printk(KERN_WARNING "ring_buffer: timestamps going "
+			       "backward. Last time %llu ns, cpu %d, "
+			       "current time %llu ns, cpu %d, "
+			       "delta %llu ns.\n",
+			       chan->iter.last_timestamp, chan->iter.last_cpu,
+			       buf->iter.timestamp, buf->backend.cpu,
+			       chan->iter.last_timestamp - buf->iter.timestamp);
+			CHAN_WARN_ON(chan, 1);
+		}
+		chan->iter.last_timestamp = buf->iter.timestamp;
+		chan->iter.last_cpu = buf->backend.cpu;
+		return buf->iter.payload_len;
+	} else {
+		/* Heap is empty */
+		if (list_empty(&chan->iter.empty_head))
+			return -ENODATA;	/* All buffers finalized */
+		else
+			return -EAGAIN;		/* Temporarily empty */
+	}
+}
+EXPORT_SYMBOL_GPL(channel_get_next_record);
+
+static
+void lib_ring_buffer_iterator_init(struct channel *chan, struct lib_ring_buffer *buf)
+{
+	if (buf->iter.allocated)
+		return;
+
+	buf->iter.allocated = 1;
+	if (chan->iter.read_open && !buf->iter.read_open) {
+		CHAN_WARN_ON(chan, lib_ring_buffer_open_read(buf) != 0);
+		buf->iter.read_open = 1;
+	}
+
+	/* Add to list of buffers without any current record */
+	if (chan->backend.config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		list_add(&buf->iter.empty_node, &chan->iter.empty_head);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static
+int __cpuinit channel_iterator_cpu_hotplug(struct notifier_block *nb,
+					   unsigned long action,
+					   void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+	struct channel *chan = container_of(nb, struct channel,
+					    hp_iter_notifier);
+	struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, cpu);
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (!chan->hp_iter_enable)
+		return NOTIFY_DONE;
+
+	CHAN_WARN_ON(chan, config->alloc == RING_BUFFER_ALLOC_GLOBAL);
+
+	switch (action) {
+	case CPU_DOWN_FAILED:
+	case CPU_DOWN_FAILED_FROZEN:
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+		lib_ring_buffer_iterator_init(chan, buf);
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
+}
+#endif
+
+int channel_iterator_init(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		int cpu, ret;
+
+		INIT_LIST_HEAD(&chan->iter.empty_head);
+		ret = lttng_heap_init(&chan->iter.heap,
+				num_possible_cpus(),
+				GFP_KERNEL, buf_is_higher);
+		if (ret)
+			return ret;
+		/*
+		 * In case of non-hotplug cpu, if the ring-buffer is allocated
+		 * in early initcall, it will not be notified of secondary cpus.
+		 * In that off case, we need to allocate for all possible cpus.
+		 */
+#ifdef CONFIG_HOTPLUG_CPU
+		chan->hp_iter_notifier.notifier_call =
+			channel_iterator_cpu_hotplug;
+		chan->hp_iter_notifier.priority = 10;
+		register_cpu_notifier(&chan->hp_iter_notifier);
+		get_online_cpus();
+		for_each_online_cpu(cpu) {
+			buf = per_cpu_ptr(chan->backend.buf, cpu);
+			lib_ring_buffer_iterator_init(chan, buf);
+		}
+		chan->hp_iter_enable = 1;
+		put_online_cpus();
+#else
+		for_each_possible_cpu(cpu) {
+			buf = per_cpu_ptr(chan->backend.buf, cpu);
+			lib_ring_buffer_iterator_init(chan, buf);
+		}
+#endif
+	} else {
+		buf = channel_get_ring_buffer(config, chan, 0);
+		lib_ring_buffer_iterator_init(chan, buf);
+	}
+	return 0;
+}
+
+void channel_iterator_unregister_notifiers(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		chan->hp_iter_enable = 0;
+		unregister_cpu_notifier(&chan->hp_iter_notifier);
+	}
+}
+
+void channel_iterator_free(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		lttng_heap_free(&chan->iter.heap);
+}
+
+int lib_ring_buffer_iterator_open(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	CHAN_WARN_ON(chan, config->output != RING_BUFFER_ITERATOR);
+	return lib_ring_buffer_open_read(buf);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_iterator_open);
+
+/*
+ * Note: Iterators must not be mixed with other types of outputs, because an
+ * iterator can leave the buffer in "GET" state, which is not consistent with
+ * other types of output (mmap, splice, raw data read).
+ */
+void lib_ring_buffer_iterator_release(struct lib_ring_buffer *buf)
+{
+	lib_ring_buffer_release_read(buf);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_iterator_release);
+
+int channel_iterator_open(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	int ret = 0, cpu;
+
+	CHAN_WARN_ON(chan, config->output != RING_BUFFER_ITERATOR);
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		get_online_cpus();
+		/* Allow CPU hotplug to keep track of opened reader */
+		chan->iter.read_open = 1;
+		for_each_channel_cpu(cpu, chan) {
+			buf = channel_get_ring_buffer(config, chan, cpu);
+			ret = lib_ring_buffer_iterator_open(buf);
+			if (ret)
+				goto error;
+			buf->iter.read_open = 1;
+		}
+		put_online_cpus();
+	} else {
+		buf = channel_get_ring_buffer(config, chan, 0);
+		ret = lib_ring_buffer_iterator_open(buf);
+	}
+	return ret;
+error:
+	/* Error should always happen on CPU 0, hence no close is required. */
+	CHAN_WARN_ON(chan, cpu != 0);
+	put_online_cpus();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(channel_iterator_open);
+
+void channel_iterator_release(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	int cpu;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+		get_online_cpus();
+		for_each_channel_cpu(cpu, chan) {
+			buf = channel_get_ring_buffer(config, chan, cpu);
+			if (buf->iter.read_open) {
+				lib_ring_buffer_iterator_release(buf);
+				buf->iter.read_open = 0;
+			}
+		}
+		chan->iter.read_open = 0;
+		put_online_cpus();
+	} else {
+		buf = channel_get_ring_buffer(config, chan, 0);
+		lib_ring_buffer_iterator_release(buf);
+	}
+}
+EXPORT_SYMBOL_GPL(channel_iterator_release);
+
+void lib_ring_buffer_iterator_reset(struct lib_ring_buffer *buf)
+{
+	struct channel *chan = buf->backend.chan;
+
+	if (buf->iter.state != ITER_GET_SUBBUF)
+		lib_ring_buffer_put_next_subbuf(buf);
+	buf->iter.state = ITER_GET_SUBBUF;
+	/* Remove from heap (if present). */
+	if (lttng_heap_cherrypick(&chan->iter.heap, buf))
+		list_add(&buf->iter.empty_node, &chan->iter.empty_head);
+	buf->iter.timestamp = 0;
+	buf->iter.header_len = 0;
+	buf->iter.payload_len = 0;
+	buf->iter.consumed = 0;
+	buf->iter.read_offset = 0;
+	buf->iter.data_size = 0;
+	/* Don't reset allocated and read_open */
+}
+
+void channel_iterator_reset(struct channel *chan)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	struct lib_ring_buffer *buf;
+	int cpu;
+
+	/* Empty heap, put into empty_head */
+	while ((buf = lttng_heap_remove(&chan->iter.heap)) != NULL)
+		list_add(&buf->iter.empty_node, &chan->iter.empty_head);
+
+	for_each_channel_cpu(cpu, chan) {
+		buf = channel_get_ring_buffer(config, chan, cpu);
+		lib_ring_buffer_iterator_reset(buf);
+	}
+	/* Don't reset read_open */
+	chan->iter.last_qs = 0;
+	chan->iter.last_timestamp = 0;
+	chan->iter.last_cpu = 0;
+	chan->iter.len_left = 0;
+}
+
+/*
+ * Ring buffer payload extraction read() implementation.
+ */
+static
+ssize_t channel_ring_buffer_file_read(struct file *filp,
+				      char __user *user_buf,
+				      size_t count,
+				      loff_t *ppos,
+				      struct channel *chan,
+				      struct lib_ring_buffer *buf,
+				      int fusionmerge)
+{
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	size_t read_count = 0, read_offset;
+	ssize_t len;
+
+	might_sleep();
+	if (!access_ok(VERIFY_WRITE, user_buf, count))
+		return -EFAULT;
+
+	/* Finish copy of previous record */
+	if (*ppos != 0) {
+		if (read_count < count) {
+			len = chan->iter.len_left;
+			read_offset = *ppos;
+			if (config->alloc == RING_BUFFER_ALLOC_PER_CPU
+			    && fusionmerge)
+				buf = lttng_heap_maximum(&chan->iter.heap);
+			CHAN_WARN_ON(chan, !buf);
+			goto skip_get_next;
+		}
+	}
+
+	while (read_count < count) {
+		size_t copy_len, space_left;
+
+		if (fusionmerge)
+			len = channel_get_next_record(chan, &buf);
+		else
+			len = lib_ring_buffer_get_next_record(chan, buf);
+len_test:
+		if (len < 0) {
+			/*
+			 * Check if buffer is finalized (end of file).
+			 */
+			if (len == -ENODATA) {
+				/* A 0 read_count will tell about end of file */
+				goto nodata;
+			}
+			if (filp->f_flags & O_NONBLOCK) {
+				if (!read_count)
+					read_count = -EAGAIN;
+				goto nodata;
+			} else {
+				int error;
+
+				/*
+				 * No data available at the moment, return what
+				 * we got.
+				 */
+				if (read_count)
+					goto nodata;
+
+				/*
+				 * Wait for returned len to be >= 0 or -ENODATA.
+				 */
+				if (fusionmerge)
+					error = wait_event_interruptible(
+					  chan->read_wait,
+					  ((len = channel_get_next_record(chan,
+						&buf)), len != -EAGAIN));
+				else
+					error = wait_event_interruptible(
+					  buf->read_wait,
+					  ((len = lib_ring_buffer_get_next_record(
+						  chan, buf)), len != -EAGAIN));
+				CHAN_WARN_ON(chan, len == -EBUSY);
+				if (error) {
+					read_count = error;
+					goto nodata;
+				}
+				CHAN_WARN_ON(chan, len < 0 && len != -ENODATA);
+				goto len_test;
+			}
+		}
+		read_offset = buf->iter.read_offset;
+skip_get_next:
+		space_left = count - read_count;
+		if (len <= space_left) {
+			copy_len = len;
+			chan->iter.len_left = 0;
+			*ppos = 0;
+		} else {
+			copy_len = space_left;
+			chan->iter.len_left = len - copy_len;
+			*ppos = read_offset + copy_len;
+		}
+		if (__lib_ring_buffer_copy_to_user(&buf->backend, read_offset,
+					       &user_buf[read_count],
+					       copy_len)) {
+			/*
+			 * Leave the len_left and ppos values at their current
+			 * state, as we currently have a valid event to read.
+			 */
+			return -EFAULT;
+		}
+		read_count += copy_len;
+	};
+	return read_count;
+
+nodata:
+	*ppos = 0;
+	chan->iter.len_left = 0;
+	return read_count;
+}
+
+/**
+ * lib_ring_buffer_file_read - Read buffer record payload.
+ * @filp: file structure pointer.
+ * @buffer: user buffer to read data into.
+ * @count: number of bytes to read.
+ * @ppos: file read position.
+ *
+ * Returns a negative value on error, or the number of bytes read on success.
+ * ppos is used to save the position _within the current record_ between calls
+ * to read().
+ */
+static
+ssize_t lib_ring_buffer_file_read(struct file *filp,
+				  char __user *user_buf,
+			          size_t count,
+			          loff_t *ppos)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct lib_ring_buffer *buf = inode->i_private;
+	struct channel *chan = buf->backend.chan;
+
+	return channel_ring_buffer_file_read(filp, user_buf, count, ppos,
+					     chan, buf, 0);
+}
+
+/**
+ * channel_file_read - Read channel record payload.
+ * @filp: file structure pointer.
+ * @buffer: user buffer to read data into.
+ * @count: number of bytes to read.
+ * @ppos: file read position.
+ *
+ * Returns a negative value on error, or the number of bytes read on success.
+ * ppos is used to save the position _within the current record_ between calls
+ * to read().
+ */
+static
+ssize_t channel_file_read(struct file *filp,
+			  char __user *user_buf,
+			  size_t count,
+			  loff_t *ppos)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct channel *chan = inode->i_private;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+		return channel_ring_buffer_file_read(filp, user_buf, count,
+						     ppos, chan, NULL, 1);
+	else {
+		struct lib_ring_buffer *buf =
+			channel_get_ring_buffer(config, chan, 0);
+		return channel_ring_buffer_file_read(filp, user_buf, count,
+						     ppos, chan, buf, 0);
+	}
+}
+
+static
+int lib_ring_buffer_file_open(struct inode *inode, struct file *file)
+{
+	struct lib_ring_buffer *buf = inode->i_private;
+	int ret;
+
+	ret = lib_ring_buffer_iterator_open(buf);
+	if (ret)
+		return ret;
+
+	file->private_data = buf;
+	ret = nonseekable_open(inode, file);
+	if (ret)
+		goto release_iter;
+	return 0;
+
+release_iter:
+	lib_ring_buffer_iterator_release(buf);
+	return ret;
+}
+
+static
+int lib_ring_buffer_file_release(struct inode *inode, struct file *file)
+{
+	struct lib_ring_buffer *buf = inode->i_private;
+
+	lib_ring_buffer_iterator_release(buf);
+	return 0;
+}
+
+static
+int channel_file_open(struct inode *inode, struct file *file)
+{
+	struct channel *chan = inode->i_private;
+	int ret;
+
+	ret = channel_iterator_open(chan);
+	if (ret)
+		return ret;
+
+	file->private_data = chan;
+	ret = nonseekable_open(inode, file);
+	if (ret)
+		goto release_iter;
+	return 0;
+
+release_iter:
+	channel_iterator_release(chan);
+	return ret;
+}
+
+static
+int channel_file_release(struct inode *inode, struct file *file)
+{
+	struct channel *chan = inode->i_private;
+
+	channel_iterator_release(chan);
+	return 0;
+}
+
+const struct file_operations channel_payload_file_operations = {
+	.owner = THIS_MODULE,
+	.open = channel_file_open,
+	.release = channel_file_release,
+	.read = channel_file_read,
+	.llseek = lib_ring_buffer_no_llseek,
+};
+EXPORT_SYMBOL_GPL(channel_payload_file_operations);
+
+const struct file_operations lib_ring_buffer_payload_file_operations = {
+	.owner = THIS_MODULE,
+	.open = lib_ring_buffer_file_open,
+	.release = lib_ring_buffer_file_release,
+	.read = lib_ring_buffer_file_read,
+	.llseek = lib_ring_buffer_no_llseek,
+};
+EXPORT_SYMBOL_GPL(lib_ring_buffer_payload_file_operations);
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
new file mode 100644
index 0000000..68221ee
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
@@ -0,0 +1,115 @@
+/*
+ * ring_buffer_mmap.c
+ *
+ * Copyright (C) 2002-2005 - Tom Zanussi <zanussi at us.ibm.com>, IBM Corp
+ * Copyright (C) 1999-2005 - Karim Yaghmour <karim at opersys.com>
+ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Re-using content from kernel/relay.c.
+ *
+ * This file is released under the GPL v2.
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+#include "../../wrapper/ringbuffer/vfs.h"
+
+/*
+ * fault() vm_op implementation for ring buffer file mapping.
+ */
+static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct lib_ring_buffer *buf = vma->vm_private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	pgoff_t pgoff = vmf->pgoff;
+	struct page **page;
+	void **virt;
+	unsigned long offset, sb_bindex;
+
+	if (!buf)
+		return VM_FAULT_OOM;
+
+	/*
+	 * Verify that faults are only done on the range of pages owned by the
+	 * reader.
+	 */
+	offset = pgoff << PAGE_SHIFT;
+	sb_bindex = subbuffer_id_get_index(config, buf->backend.buf_rsb.id);
+	if (!(offset >= buf->backend.array[sb_bindex]->mmap_offset
+	      && offset < buf->backend.array[sb_bindex]->mmap_offset +
+			  buf->backend.chan->backend.subbuf_size))
+		return VM_FAULT_SIGBUS;
+	/*
+	 * ring_buffer_read_get_page() gets the page in the current reader's
+	 * pages.
+	 */
+	page = lib_ring_buffer_read_get_page(&buf->backend, offset, &virt);
+	if (!*page)
+		return VM_FAULT_SIGBUS;
+	get_page(*page);
+	vmf->page = *page;
+
+	return 0;
+}
+
+/*
+ * vm_ops for ring buffer file mappings.
+ */
+static const struct vm_operations_struct lib_ring_buffer_mmap_ops = {
+	.fault = lib_ring_buffer_fault,
+};
+
+/**
+ *	lib_ring_buffer_mmap_buf: - mmap channel buffer to process address space
+ *	@buf: ring buffer to map
+ *	@vma: vm_area_struct describing memory to be mapped
+ *
+ *	Returns 0 if ok, negative on error
+ *
+ *	Caller should already have grabbed mmap_sem.
+ */
+static int lib_ring_buffer_mmap_buf(struct lib_ring_buffer *buf,
+				    struct vm_area_struct *vma)
+{
+	unsigned long length = vma->vm_end - vma->vm_start;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned long mmap_buf_len;
+
+	if (config->output != RING_BUFFER_MMAP)
+		return -EINVAL;
+
+	if (!buf)
+		return -EBADF;
+
+	mmap_buf_len = chan->backend.buf_size;
+	if (chan->backend.extra_reader_sb)
+		mmap_buf_len += chan->backend.subbuf_size;
+
+	if (length != mmap_buf_len)
+		return -EINVAL;
+
+	vma->vm_ops = &lib_ring_buffer_mmap_ops;
+	vma->vm_flags |= VM_DONTEXPAND;
+	vma->vm_private_data = buf;
+
+	return 0;
+}
+
+/**
+ *	lib_ring_buffer_mmap - mmap file op
+ *	@filp: the file
+ *	@vma: the vma describing what to map
+ *
+ *	Calls upon lib_ring_buffer_mmap_buf() to map the file into user space.
+ */
+int lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct lib_ring_buffer *buf = filp->private_data;
+	return lib_ring_buffer_mmap_buf(buf, vma);
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_mmap);
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c
new file mode 100644
index 0000000..ded18ba
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c
@@ -0,0 +1,202 @@
+/*
+ * ring_buffer_splice.c
+ *
+ * Copyright (C) 2002-2005 - Tom Zanussi <zanussi at us.ibm.com>, IBM Corp
+ * Copyright (C) 1999-2005 - Karim Yaghmour <karim at opersys.com>
+ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Re-using content from kernel/relay.c.
+ *
+ * This file is released under the GPL v2.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+
+#include "../../wrapper/splice.h"
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+#include "../../wrapper/ringbuffer/vfs.h"
+
+#if 0
+#define printk_dbg(fmt, args...) printk(fmt, args)
+#else
+#define printk_dbg(fmt, args...)
+#endif
+
+loff_t lib_ring_buffer_no_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+/*
+ * Release pages from the buffer so splice pipe_to_file can move them.
+ * Called after the pipe has been populated with buffer pages.
+ */
+static void lib_ring_buffer_pipe_buf_release(struct pipe_inode_info *pipe,
+					     struct pipe_buffer *pbuf)
+{
+	__free_page(pbuf->page);
+}
+
+static const struct pipe_buf_operations ring_buffer_pipe_buf_ops = {
+	.can_merge = 0,
+	.map = generic_pipe_buf_map,
+	.unmap = generic_pipe_buf_unmap,
+	.confirm = generic_pipe_buf_confirm,
+	.release = lib_ring_buffer_pipe_buf_release,
+	.steal = generic_pipe_buf_steal,
+	.get = generic_pipe_buf_get,
+};
+
+/*
+ * Page release operation after splice pipe_to_file ends.
+ */
+static void lib_ring_buffer_page_release(struct splice_pipe_desc *spd,
+					 unsigned int i)
+{
+	__free_page(spd->pages[i]);
+}
+
+/*
+ *	subbuf_splice_actor - splice up to one subbuf's worth of data
+ */
+static int subbuf_splice_actor(struct file *in,
+			       loff_t *ppos,
+			       struct pipe_inode_info *pipe,
+			       size_t len,
+			       unsigned int flags)
+{
+	struct lib_ring_buffer *buf = in->private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	unsigned int poff, subbuf_pages, nr_pages;
+	struct page *pages[PIPE_DEF_BUFFERS];
+	struct partial_page partial[PIPE_DEF_BUFFERS];
+	struct splice_pipe_desc spd = {
+		.pages = pages,
+		.nr_pages = 0,
+		.partial = partial,
+		.flags = flags,
+		.ops = &ring_buffer_pipe_buf_ops,
+		.spd_release = lib_ring_buffer_page_release,
+	};
+	unsigned long consumed_old, roffset;
+	unsigned long bytes_avail;
+
+	/*
+	 * Check that a GET_SUBBUF ioctl has been done before.
+	 */
+	WARN_ON(atomic_long_read(&buf->active_readers) != 1);
+	consumed_old = lib_ring_buffer_get_consumed(config, buf);
+	consumed_old += *ppos;
+
+	/*
+	 * Adjust read len, if longer than what is available.
+	 * Max read size is 1 subbuffer due to get_subbuf/put_subbuf for
+	 * protection.
+	 */
+	bytes_avail = chan->backend.subbuf_size;
+	WARN_ON(bytes_avail > chan->backend.buf_size);
+	len = min_t(size_t, len, bytes_avail);
+	subbuf_pages = bytes_avail >> PAGE_SHIFT;
+	nr_pages = min_t(unsigned int, subbuf_pages, PIPE_DEF_BUFFERS);
+	roffset = consumed_old & PAGE_MASK;
+	poff = consumed_old & ~PAGE_MASK;
+	printk_dbg(KERN_DEBUG "SPLICE actor len %zu pos %zd write_pos %ld\n",
+		   len, (ssize_t)*ppos, lib_ring_buffer_get_offset(config, buf));
+
+	for (; spd.nr_pages < nr_pages; spd.nr_pages++) {
+		unsigned int this_len;
+		struct page **page, *new_page;
+		void **virt;
+
+		if (!len)
+			break;
+		printk_dbg(KERN_DEBUG "SPLICE actor loop len %zu roffset %ld\n",
+			   len, roffset);
+
+		/*
+		 * We have to replace the page we are moving into the splice
+		 * pipe.
+		 */
+		new_page = alloc_pages_node(cpu_to_node(max(buf->backend.cpu,
+							    0)),
+					    GFP_KERNEL | __GFP_ZERO, 0);
+		if (!new_page)
+			break;
+
+		this_len = PAGE_SIZE - poff;
+		page = lib_ring_buffer_read_get_page(&buf->backend, roffset, &virt);
+		spd.pages[spd.nr_pages] = *page;
+		*page = new_page;
+		*virt = page_address(new_page);
+		spd.partial[spd.nr_pages].offset = poff;
+		spd.partial[spd.nr_pages].len = this_len;
+
+		poff = 0;
+		roffset += PAGE_SIZE;
+		len -= this_len;
+	}
+
+	if (!spd.nr_pages)
+		return 0;
+
+	return wrapper_splice_to_pipe(pipe, &spd);
+}
+
+ssize_t lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
+				    struct pipe_inode_info *pipe, size_t len,
+				    unsigned int flags)
+{
+	struct lib_ring_buffer *buf = in->private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	ssize_t spliced;
+	int ret;
+
+	if (config->output != RING_BUFFER_SPLICE)
+		return -EINVAL;
+
+	/*
+	 * We require ppos and length to be page-aligned for performance reasons
+	 * (no page copy). Size is known using the ioctl
+	 * RING_BUFFER_GET_PADDED_SUBBUF_SIZE, which is page-size padded.
+	 * We fail when the ppos or len passed is not page-sized, because splice
+	 * is not allowed to copy more than the length passed as parameter (so
+	 * the ABI does not let us silently copy more than requested to include
+	 * padding).
+	 */
+	if (*ppos != PAGE_ALIGN(*ppos) || len != PAGE_ALIGN(len))
+		return -EINVAL;
+
+	ret = 0;
+	spliced = 0;
+
+	printk_dbg(KERN_DEBUG "SPLICE read len %zu pos %zd\n", len,
+		   (ssize_t)*ppos);
+	while (len && !spliced) {
+		ret = subbuf_splice_actor(in, ppos, pipe, len, flags);
+		printk_dbg(KERN_DEBUG "SPLICE read loop ret %d\n", ret);
+		if (ret < 0)
+			break;
+		else if (!ret) {
+			if (flags & SPLICE_F_NONBLOCK)
+				ret = -EAGAIN;
+			break;
+		}
+
+		*ppos += ret;
+		if (ret > len)
+			len = 0;
+		else
+			len -= ret;
+		spliced += ret;
+	}
+
+	if (spliced)
+		return spliced;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lib_ring_buffer_splice_read);
diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
new file mode 100644
index 0000000..1708ffd
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
@@ -0,0 +1,387 @@
+/*
+ * ring_buffer_vfs.c
+ *
+ * Copyright (C) 2009-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Ring Buffer VFS file operations.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+
+#include "../../wrapper/ringbuffer/backend.h"
+#include "../../wrapper/ringbuffer/frontend.h"
+#include "../../wrapper/ringbuffer/vfs.h"
+#include "../../wrapper/poll.h"
+
+static int put_ulong(unsigned long val, unsigned long arg)
+{
+	return put_user(val, (unsigned long __user *)arg);
+}
+
+#ifdef CONFIG_COMPAT
+static int compat_put_ulong(compat_ulong_t val, unsigned long arg)
+{
+	return put_user(val, (compat_ulong_t __user *)compat_ptr(arg));
+}
+#endif
+
+/**
+ *	lib_ring_buffer_open - ring buffer open file operation
+ *	@inode: opened inode
+ *	@file: opened file
+ *
+ *	Open implementation. Makes sure only one open instance of a buffer is
+ *	done at a given moment.
+ */
+int lib_ring_buffer_open(struct inode *inode, struct file *file)
+{
+	struct lib_ring_buffer *buf = inode->i_private;
+	int ret;
+
+	ret = lib_ring_buffer_open_read(buf);
+	if (ret)
+		return ret;
+
+	file->private_data = buf;
+	ret = nonseekable_open(inode, file);
+	if (ret)
+		goto release_read;
+	return 0;
+
+release_read:
+	lib_ring_buffer_release_read(buf);
+	return ret;
+}
+
+/**
+ *	lib_ring_buffer_release - ring buffer release file operation
+ *	@inode: opened inode
+ *	@file: opened file
+ *
+ *	Release implementation.
+ */
+int lib_ring_buffer_release(struct inode *inode, struct file *file)
+{
+	struct lib_ring_buffer *buf = file->private_data;
+
+	lib_ring_buffer_release_read(buf);
+
+	return 0;
+}
+
+/**
+ *	lib_ring_buffer_poll - ring buffer poll file operation
+ *	@filp: the file
+ *	@wait: poll table
+ *
+ *	Poll implementation.
+ */
+unsigned int lib_ring_buffer_poll(struct file *filp, poll_table *wait)
+{
+	unsigned int mask = 0;
+	struct lib_ring_buffer *buf = filp->private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+	int finalized, disabled;
+
+	if (filp->f_mode & FMODE_READ) {
+		poll_wait_set_exclusive(wait);
+		poll_wait(filp, &buf->read_wait, wait);
+
+		finalized = lib_ring_buffer_is_finalized(config, buf);
+		disabled = lib_ring_buffer_channel_is_disabled(chan);
+
+		/*
+		 * lib_ring_buffer_is_finalized() contains a smp_rmb() ordering
+		 * finalized load before offsets loads.
+		 */
+		WARN_ON(atomic_long_read(&buf->active_readers) != 1);
+retry:
+		if (disabled)
+			return POLLERR;
+
+		if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf), chan)
+		  - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf), chan)
+		  == 0) {
+			if (finalized)
+				return POLLHUP;
+			else {
+				/*
+				 * The memory barriers
+				 * __wait_event()/wake_up_interruptible() take
+				 * care of "raw_spin_is_locked" memory ordering.
+				 */
+				if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock))
+					goto retry;
+				else
+					return 0;
+			}
+		} else {
+			if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf),
+					 chan)
+			  - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf),
+					 chan)
+			  >= chan->backend.buf_size)
+				return POLLPRI | POLLRDBAND;
+			else
+				return POLLIN | POLLRDNORM;
+		}
+	}
+	return mask;
+}
+
+/**
+ *	lib_ring_buffer_ioctl - control ring buffer reader synchronization
+ *
+ *	@filp: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements commands necessary for producer/consumer
+ *	and flight recorder reader interaction :
+ *	RING_BUFFER_GET_NEXT_SUBBUF
+ *		Get the next sub-buffer that can be read. It never blocks.
+ *	RING_BUFFER_PUT_NEXT_SUBBUF
+ *		Release the currently read sub-buffer.
+ *	RING_BUFFER_GET_SUBBUF_SIZE
+ *		returns the size of the current sub-buffer.
+ *	RING_BUFFER_GET_MAX_SUBBUF_SIZE
+ *		returns the maximum size for sub-buffers.
+ *	RING_BUFFER_GET_NUM_SUBBUF
+ *		returns the number of reader-visible sub-buffers in the per cpu
+ *              channel (for mmap).
+ *      RING_BUFFER_GET_MMAP_READ_OFFSET
+ *              returns the offset of the subbuffer belonging to the reader.
+ *              Should only be used for mmap clients.
+ */
+long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct lib_ring_buffer *buf = filp->private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (lib_ring_buffer_channel_is_disabled(chan))
+		return -EIO;
+
+	switch (cmd) {
+	case RING_BUFFER_SNAPSHOT:
+		return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
+					    &buf->prod_snapshot);
+	case RING_BUFFER_SNAPSHOT_GET_CONSUMED:
+		return put_ulong(buf->cons_snapshot, arg);
+	case RING_BUFFER_SNAPSHOT_GET_PRODUCED:
+		return put_ulong(buf->prod_snapshot, arg);
+	case RING_BUFFER_GET_SUBBUF:
+	{
+		unsigned long uconsume;
+		long ret;
+
+		ret = get_user(uconsume, (unsigned long __user *) arg);
+		if (ret)
+			return ret; /* will return -EFAULT */
+		ret = lib_ring_buffer_get_subbuf(buf, uconsume);
+		if (!ret) {
+			/* Set file position to zero at each successful "get" */
+			filp->f_pos = 0;
+		}
+		return ret;
+	}
+	case RING_BUFFER_PUT_SUBBUF:
+		lib_ring_buffer_put_subbuf(buf);
+		return 0;
+
+	case RING_BUFFER_GET_NEXT_SUBBUF:
+	{
+		long ret;
+
+		ret = lib_ring_buffer_get_next_subbuf(buf);
+		if (!ret) {
+			/* Set file position to zero at each successful "get" */
+			filp->f_pos = 0;
+		}
+		return ret;
+	}
+	case RING_BUFFER_PUT_NEXT_SUBBUF:
+		lib_ring_buffer_put_next_subbuf(buf);
+		return 0;
+	case RING_BUFFER_GET_SUBBUF_SIZE:
+		return put_ulong(lib_ring_buffer_get_read_data_size(config, buf),
+				 arg);
+	case RING_BUFFER_GET_PADDED_SUBBUF_SIZE:
+	{
+		unsigned long size;
+
+		size = lib_ring_buffer_get_read_data_size(config, buf);
+		size = PAGE_ALIGN(size);
+		return put_ulong(size, arg);
+	}
+	case RING_BUFFER_GET_MAX_SUBBUF_SIZE:
+		return put_ulong(chan->backend.subbuf_size, arg);
+	case RING_BUFFER_GET_MMAP_LEN:
+	{
+		unsigned long mmap_buf_len;
+
+		if (config->output != RING_BUFFER_MMAP)
+			return -EINVAL;
+		mmap_buf_len = chan->backend.buf_size;
+		if (chan->backend.extra_reader_sb)
+			mmap_buf_len += chan->backend.subbuf_size;
+		if (mmap_buf_len > INT_MAX)
+			return -EFBIG;
+		return put_ulong(mmap_buf_len, arg);
+	}
+	case RING_BUFFER_GET_MMAP_READ_OFFSET:
+	{
+		unsigned long sb_bindex;
+
+		if (config->output != RING_BUFFER_MMAP)
+			return -EINVAL;
+		sb_bindex = subbuffer_id_get_index(config,
+						   buf->backend.buf_rsb.id);
+		return put_ulong(buf->backend.array[sb_bindex]->mmap_offset,
+				 arg);
+	}
+	case RING_BUFFER_FLUSH:
+		lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd,
+				  unsigned long arg)
+{
+	struct lib_ring_buffer *buf = filp->private_data;
+	struct channel *chan = buf->backend.chan;
+	const struct lib_ring_buffer_config *config = chan->backend.config;
+
+	if (lib_ring_buffer_channel_is_disabled(chan))
+		return -EIO;
+
+	switch (cmd) {
+	case RING_BUFFER_SNAPSHOT:
+		return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
+						&buf->prod_snapshot);
+	case RING_BUFFER_SNAPSHOT_GET_CONSUMED:
+		return compat_put_ulong(buf->cons_snapshot, arg);
+	case RING_BUFFER_SNAPSHOT_GET_PRODUCED:
+		return compat_put_ulong(buf->prod_snapshot, arg);
+	case RING_BUFFER_GET_SUBBUF:
+	{
+		__u32 uconsume;
+		unsigned long consume;
+		long ret;
+
+		ret = get_user(uconsume, (__u32 __user *) arg);
+		if (ret)
+			return ret; /* will return -EFAULT */
+		consume = buf->cons_snapshot;
+		consume &= ~0xFFFFFFFFL;
+		consume |= uconsume;
+		ret = lib_ring_buffer_get_subbuf(buf, consume);
+		if (!ret) {
+			/* Set file position to zero at each successful "get" */
+			filp->f_pos = 0;
+		}
+		return ret;
+	}
+	case RING_BUFFER_PUT_SUBBUF:
+		lib_ring_buffer_put_subbuf(buf);
+		return 0;
+
+	case RING_BUFFER_GET_NEXT_SUBBUF:
+	{
+		long ret;
+
+		ret = lib_ring_buffer_get_next_subbuf(buf);
+		if (!ret) {
+			/* Set file position to zero at each successful "get" */
+			filp->f_pos = 0;
+		}
+		return ret;
+	}
+	case RING_BUFFER_PUT_NEXT_SUBBUF:
+		lib_ring_buffer_put_next_subbuf(buf);
+		return 0;
+	case RING_BUFFER_GET_SUBBUF_SIZE:
+	{
+		unsigned long data_size;
+
+		data_size = lib_ring_buffer_get_read_data_size(config, buf);
+		if (data_size > UINT_MAX)
+			return -EFBIG;
+		return put_ulong(data_size, arg);
+	}
+	case RING_BUFFER_GET_PADDED_SUBBUF_SIZE:
+	{
+		unsigned long size;
+
+		size = lib_ring_buffer_get_read_data_size(config, buf);
+		size = PAGE_ALIGN(size);
+		if (size > UINT_MAX)
+			return -EFBIG;
+		return put_ulong(size, arg);
+	}
+	case RING_BUFFER_GET_MAX_SUBBUF_SIZE:
+		if (chan->backend.subbuf_size > UINT_MAX)
+			return -EFBIG;
+		return put_ulong(chan->backend.subbuf_size, arg);
+	case RING_BUFFER_GET_MMAP_LEN:
+	{
+		unsigned long mmap_buf_len;
+
+		if (config->output != RING_BUFFER_MMAP)
+			return -EINVAL;
+		mmap_buf_len = chan->backend.buf_size;
+		if (chan->backend.extra_reader_sb)
+			mmap_buf_len += chan->backend.subbuf_size;
+		if (mmap_buf_len > UINT_MAX)
+			return -EFBIG;
+		return put_ulong(mmap_buf_len, arg);
+	}
+	case RING_BUFFER_GET_MMAP_READ_OFFSET:
+	{
+		unsigned long sb_bindex, read_offset;
+
+		if (config->output != RING_BUFFER_MMAP)
+			return -EINVAL;
+		sb_bindex = subbuffer_id_get_index(config,
+						   buf->backend.buf_rsb.id);
+		read_offset = buf->backend.array[sb_bindex]->mmap_offset;
+		if (read_offset > UINT_MAX)
+			return -EINVAL;
+		return put_ulong(read_offset, arg);
+	}
+	case RING_BUFFER_FLUSH:
+		lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE);
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+#endif
+
+const struct file_operations lib_ring_buffer_file_operations = {
+	.owner = THIS_MODULE,
+	.open = lib_ring_buffer_open,
+	.release = lib_ring_buffer_release,
+	.poll = lib_ring_buffer_poll,
+	.splice_read = lib_ring_buffer_splice_read,
+	.mmap = lib_ring_buffer_mmap,
+	.unlocked_ioctl = lib_ring_buffer_ioctl,
+	.llseek = lib_ring_buffer_no_llseek,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lib_ring_buffer_compat_ioctl,
+#endif
+};
+EXPORT_SYMBOL_GPL(lib_ring_buffer_file_operations);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Ring Buffer Library VFS");
diff --git a/drivers/staging/lttng/lib/ringbuffer/vatomic.h b/drivers/staging/lttng/lib/ringbuffer/vatomic.h
new file mode 100644
index 0000000..b944dd6
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/vatomic.h
@@ -0,0 +1,85 @@
+#ifndef _LINUX_RING_BUFFER_VATOMIC_H
+#define _LINUX_RING_BUFFER_VATOMIC_H
+
+/*
+ * linux/ringbuffer/vatomic.h
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <asm/atomic.h>
+#include <asm/local.h>
+
+/*
+ * Same data type (long) accessed differently depending on configuration.
+ * v field is for non-atomic access (protected by mutual exclusion).
+ * In the fast-path, the ring_buffer_config structure is constant, so the
+ * compiler can statically select the appropriate branch.
+ * local_t is used for per-cpu and per-thread buffers.
+ * atomic_long_t is used for globally shared buffers.
+ */
+union v_atomic {
+	local_t l;
+	atomic_long_t a;
+	long v;
+};
+
+static inline
+long v_read(const struct lib_ring_buffer_config *config, union v_atomic *v_a)
+{
+	if (config->sync == RING_BUFFER_SYNC_PER_CPU)
+		return local_read(&v_a->l);
+	else
+		return atomic_long_read(&v_a->a);
+}
+
+static inline
+void v_set(const struct lib_ring_buffer_config *config, union v_atomic *v_a,
+	   long v)
+{
+	if (config->sync == RING_BUFFER_SYNC_PER_CPU)
+		local_set(&v_a->l, v);
+	else
+		atomic_long_set(&v_a->a, v);
+}
+
+static inline
+void v_add(const struct lib_ring_buffer_config *config, long v, union v_atomic *v_a)
+{
+	if (config->sync == RING_BUFFER_SYNC_PER_CPU)
+		local_add(v, &v_a->l);
+	else
+		atomic_long_add(v, &v_a->a);
+}
+
+static inline
+void v_inc(const struct lib_ring_buffer_config *config, union v_atomic *v_a)
+{
+	if (config->sync == RING_BUFFER_SYNC_PER_CPU)
+		local_inc(&v_a->l);
+	else
+		atomic_long_inc(&v_a->a);
+}
+
+/*
+ * Non-atomic decrement. Only used by reader, apply to reader-owned subbuffer.
+ */
+static inline
+void _v_dec(const struct lib_ring_buffer_config *config, union v_atomic *v_a)
+{
+	--v_a->v;
+}
+
+static inline
+long v_cmpxchg(const struct lib_ring_buffer_config *config, union v_atomic *v_a,
+	       long old, long _new)
+{
+	if (config->sync == RING_BUFFER_SYNC_PER_CPU)
+		return local_cmpxchg(&v_a->l, old, _new);
+	else
+		return atomic_long_cmpxchg(&v_a->a, old, _new);
+}
+
+#endif /* _LINUX_RING_BUFFER_VATOMIC_H */
diff --git a/drivers/staging/lttng/lib/ringbuffer/vfs.h b/drivers/staging/lttng/lib/ringbuffer/vfs.h
new file mode 100644
index 0000000..d073e4c
--- /dev/null
+++ b/drivers/staging/lttng/lib/ringbuffer/vfs.h
@@ -0,0 +1,89 @@
+#ifndef _LINUX_RING_BUFFER_VFS_H
+#define _LINUX_RING_BUFFER_VFS_H
+
+/*
+ * linux/ringbuffer/vfs.h
+ *
+ * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Wait-free ring buffer VFS file operations.
+ *
+ * Author:
+ *	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/fs.h>
+#include <linux/poll.h>
+
+/* VFS API */
+
+extern const struct file_operations lib_ring_buffer_file_operations;
+
+/*
+ * Internal file operations.
+ */
+
+int lib_ring_buffer_open(struct inode *inode, struct file *file);
+int lib_ring_buffer_release(struct inode *inode, struct file *file);
+unsigned int lib_ring_buffer_poll(struct file *filp, poll_table *wait);
+ssize_t lib_ring_buffer_splice_read(struct file *in, loff_t *ppos,
+				    struct pipe_inode_info *pipe, size_t len,
+				    unsigned int flags);
+int lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/* Ring Buffer ioctl() and ioctl numbers */
+long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd,
+				  unsigned long arg);
+#endif
+
+/*
+ * Use RING_BUFFER_GET_NEXT_SUBBUF / RING_BUFFER_PUT_NEXT_SUBBUF to read and
+ * consume sub-buffers sequentially.
+ *
+ * Reading sub-buffers without consuming them can be performed with:
+ *
+ * RING_BUFFER_SNAPSHOT
+ * RING_BUFFER_SNAPSHOT_GET_CONSUMED
+ * RING_BUFFER_SNAPSHOT_GET_PRODUCED
+ *
+ * to get the offset range to consume, and then by passing each sub-buffer
+ * offset to RING_BUFFER_GET_SUBBUF, read the sub-buffer, and then release it
+ * with RING_BUFFER_PUT_SUBBUF.
+ *
+ * Note that the "snapshot" API can be used to read the sub-buffer in reverse
+ * order, which is useful for flight recorder snapshots.
+ */
+
+/* Get a snapshot of the current ring buffer producer and consumer positions */
+#define RING_BUFFER_SNAPSHOT			_IO(0xF6, 0x00)
+/* Get the consumer position (iteration start) */
+#define RING_BUFFER_SNAPSHOT_GET_CONSUMED	_IOR(0xF6, 0x01, unsigned long)
+/* Get the producer position (iteration end) */
+#define RING_BUFFER_SNAPSHOT_GET_PRODUCED	_IOR(0xF6, 0x02, unsigned long)
+/* Get exclusive read access to the specified sub-buffer position */
+#define RING_BUFFER_GET_SUBBUF			_IOW(0xF6, 0x03, unsigned long)
+/* Release exclusive sub-buffer access */
+#define RING_BUFFER_PUT_SUBBUF			_IO(0xF6, 0x04)
+
+/* Get exclusive read access to the next sub-buffer that can be read. */
+#define RING_BUFFER_GET_NEXT_SUBBUF		_IO(0xF6, 0x05)
+/* Release exclusive sub-buffer access, move consumer forward. */
+#define RING_BUFFER_PUT_NEXT_SUBBUF		_IO(0xF6, 0x06)
+/* returns the size of the current sub-buffer, without padding (for mmap). */
+#define RING_BUFFER_GET_SUBBUF_SIZE		_IOR(0xF6, 0x07, unsigned long)
+/* returns the size of the current sub-buffer, with padding (for splice). */
+#define RING_BUFFER_GET_PADDED_SUBBUF_SIZE	_IOR(0xF6, 0x08, unsigned long)
+/* returns the maximum size for sub-buffers. */
+#define RING_BUFFER_GET_MAX_SUBBUF_SIZE		_IOR(0xF6, 0x09, unsigned long)
+/* returns the length to mmap. */
+#define RING_BUFFER_GET_MMAP_LEN		_IOR(0xF6, 0x0A, unsigned long)
+/* returns the offset of the subbuffer belonging to the mmap reader. */
+#define RING_BUFFER_GET_MMAP_READ_OFFSET	_IOR(0xF6, 0x0B, unsigned long)
+/* flush the current sub-buffer */
+#define RING_BUFFER_FLUSH			_IO(0xF6, 0x0C)
+
+#endif /* _LINUX_RING_BUFFER_VFS_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 02/19] lttng lib: portable bitfield read/write header
  2011-11-26 15:03 ` [lttng-dev] [PATCH 01/19] lttng lib: ring buffer Mathieu Desnoyers
@ 2011-11-26 15:03   ` Mathieu Desnoyers
  2011-11-26 15:03     ` [lttng-dev] [PATCH 03/19] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lib/bitfield.h |  400 ++++++++++++++++++++++++++++++++++
 1 files changed, 400 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lib/bitfield.h

diff --git a/drivers/staging/lttng/lib/bitfield.h b/drivers/staging/lttng/lib/bitfield.h
new file mode 100644
index 0000000..861e6dc
--- /dev/null
+++ b/drivers/staging/lttng/lib/bitfield.h
@@ -0,0 +1,400 @@
+#ifndef _BABELTRACE_BITFIELD_H
+#define _BABELTRACE_BITFIELD_H
+
+/*
+ * BabelTrace
+ *
+ * Bitfields read/write functions.
+ *
+ * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+
+#include "../ltt-endian.h"
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
+#define _bt_piecewise_rshift(_v, _shift)				\
+({									\
+	typeof(_v) ___v = (_v);						\
+	typeof(_shift) ___shift = (_shift);				\
+	unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1);	\
+	unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \
+									\
+	for (; sb; sb--)						\
+		___v >>= sizeof(___v) * CHAR_BIT - 1;			\
+	___v >>= final;							\
+})
+
+#define _bt_piecewise_lshift(_v, _shift)				\
+({									\
+	typeof(_v) ___v = (_v);						\
+	typeof(_shift) ___shift = (_shift);				\
+	unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1);	\
+	unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \
+									\
+	for (; sb; sb--)						\
+		___v <<= sizeof(___v) * CHAR_BIT - 1;			\
+	___v <<= final;							\
+})
+
+#define _bt_is_signed_type(type)	(((type)(-1)) < 0)
+
+#define _bt_unsigned_cast(type, v)					\
+({									\
+	(sizeof(v) < sizeof(type)) ?					\
+		((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \
+		(type) (v);						\
+})
+
+/*
+ * bt_bitfield_write - write integer to a bitfield in native endianness
+ *
+ * Save integer to the bitfield, which starts at the "start" bit, has "len"
+ * bits.
+ * The inside of a bitfield is from high bits to low bits.
+ * Uses native endianness.
+ * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
+ * For signed "v", sign-extend v if bitfield is larger than v.
+ *
+ * On little endian, bytes are placed from the less significant to the most
+ * significant. Also, consecutive bitfields are placed from lower bits to higher
+ * bits.
+ *
+ * On big endian, bytes are places from most significant to less significant.
+ * Also, consecutive bitfields are placed from higher to lower bits.
+ */
+
+#define _bt_bitfield_write_le(_ptr, type, _start, _length, _v)		\
+do {									\
+	typeof(_v) __v = (_v);						\
+	type *__ptr = (void *) (_ptr);					\
+	unsigned long __start = (_start), __length = (_length);		\
+	type mask, cmask;						\
+	unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */	\
+	unsigned long start_unit, end_unit, this_unit;			\
+	unsigned long end, cshift; /* cshift is "complement shift" */	\
+									\
+	if (!__length)							\
+		break;							\
+									\
+	end = __start + __length;					\
+	start_unit = __start / ts;					\
+	end_unit = (end + (ts - 1)) / ts;				\
+									\
+	/* Trim v high bits */						\
+	if (__length < sizeof(__v) * CHAR_BIT)				\
+		__v &= ~((~(typeof(__v)) 0) << __length);		\
+									\
+	/* We can now append v with a simple "or", shift it piece-wise */ \
+	this_unit = start_unit;						\
+	if (start_unit == end_unit - 1) {				\
+		mask = ~((~(type) 0) << (__start % ts));		\
+		if (end % ts)						\
+			mask |= (~(type) 0) << (end % ts);		\
+		cmask = (type) __v << (__start % ts);			\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+		break;							\
+	}								\
+	if (__start % ts) {						\
+		cshift = __start % ts;					\
+		mask = ~((~(type) 0) << cshift);			\
+		cmask = (type) __v << cshift;				\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+		__v = _bt_piecewise_rshift(__v, ts - cshift);		\
+		__start += ts - cshift;					\
+		this_unit++;						\
+	}								\
+	for (; this_unit < end_unit - 1; this_unit++) {			\
+		__ptr[this_unit] = (type) __v;				\
+		__v = _bt_piecewise_rshift(__v, ts);			\
+		__start += ts;						\
+	}								\
+	if (end % ts) {							\
+		mask = (~(type) 0) << (end % ts);			\
+		cmask = (type) __v;					\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+	} else								\
+		__ptr[this_unit] = (type) __v;				\
+} while (0)
+
+#define _bt_bitfield_write_be(_ptr, type, _start, _length, _v)		\
+do {									\
+	typeof(_v) __v = (_v);						\
+	type *__ptr = (void *) (_ptr);					\
+	unsigned long __start = (_start), __length = (_length);		\
+	type mask, cmask;						\
+	unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */	\
+	unsigned long start_unit, end_unit, this_unit;			\
+	unsigned long end, cshift; /* cshift is "complement shift" */	\
+									\
+	if (!__length)							\
+		break;							\
+									\
+	end = __start + __length;					\
+	start_unit = __start / ts;					\
+	end_unit = (end + (ts - 1)) / ts;				\
+									\
+	/* Trim v high bits */						\
+	if (__length < sizeof(__v) * CHAR_BIT)				\
+		__v &= ~((~(typeof(__v)) 0) << __length);		\
+									\
+	/* We can now append v with a simple "or", shift it piece-wise */ \
+	this_unit = end_unit - 1;					\
+	if (start_unit == end_unit - 1) {				\
+		mask = ~((~(type) 0) << ((ts - (end % ts)) % ts));	\
+		if (__start % ts)					\
+			mask |= (~((type) 0)) << (ts - (__start % ts));	\
+		cmask = (type) __v << ((ts - (end % ts)) % ts);		\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+		break;							\
+	}								\
+	if (end % ts) {							\
+		cshift = end % ts;					\
+		mask = ~((~(type) 0) << (ts - cshift));			\
+		cmask = (type) __v << (ts - cshift);			\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+		__v = _bt_piecewise_rshift(__v, cshift);		\
+		end -= cshift;						\
+		this_unit--;						\
+	}								\
+	for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
+		__ptr[this_unit] = (type) __v;				\
+		__v = _bt_piecewise_rshift(__v, ts);			\
+		end -= ts;						\
+	}								\
+	if (__start % ts) {						\
+		mask = (~(type) 0) << (ts - (__start % ts));		\
+		cmask = (type) __v;					\
+		cmask &= ~mask;						\
+		__ptr[this_unit] &= mask;				\
+		__ptr[this_unit] |= cmask;				\
+	} else								\
+		__ptr[this_unit] = (type) __v;				\
+} while (0)
+
+/*
+ * bt_bitfield_write - write integer to a bitfield in native endianness
+ * bt_bitfield_write_le - write integer to a bitfield in little endian
+ * bt_bitfield_write_be - write integer to a bitfield in big endian
+ */
+
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+
+#define bt_bitfield_write(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_le(ptr, type, _start, _length, _v)
+
+#define bt_bitfield_write_le(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_le(ptr, type, _start, _length, _v)
+	
+#define bt_bitfield_write_be(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
+
+#elif (__BYTE_ORDER == __BIG_ENDIAN)
+
+#define bt_bitfield_write(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_be(ptr, type, _start, _length, _v)
+
+#define bt_bitfield_write_le(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
+	
+#define bt_bitfield_write_be(ptr, type, _start, _length, _v)		\
+	_bt_bitfield_write_be(ptr, type, _start, _length, _v)
+
+#else /* (BYTE_ORDER == PDP_ENDIAN) */
+
+#error "Byte order not supported"
+
+#endif
+
+#define _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)	\
+do {									\
+	typeof(*(_vptr)) *__vptr = (_vptr);				\
+	typeof(*__vptr) __v;						\
+	type *__ptr = (void *) (_ptr);					\
+	unsigned long __start = (_start), __length = (_length);		\
+	type mask, cmask;						\
+	unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */	\
+	unsigned long start_unit, end_unit, this_unit;			\
+	unsigned long end, cshift; /* cshift is "complement shift" */	\
+									\
+	if (!__length) {						\
+		*__vptr = 0;						\
+		break;							\
+	}								\
+									\
+	end = __start + __length;					\
+	start_unit = __start / ts;					\
+	end_unit = (end + (ts - 1)) / ts;				\
+									\
+	this_unit = end_unit - 1;					\
+	if (_bt_is_signed_type(typeof(__v))				\
+	    && (__ptr[this_unit] & ((type) 1 << ((end % ts ? : ts) - 1)))) \
+		__v = ~(typeof(__v)) 0;					\
+	else								\
+		__v = 0;						\
+	if (start_unit == end_unit - 1) {				\
+		cmask = __ptr[this_unit];				\
+		cmask >>= (__start % ts);				\
+		if ((end - __start) % ts) {				\
+			mask = ~((~(type) 0) << (end - __start));	\
+			cmask &= mask;					\
+		}							\
+		__v = _bt_piecewise_lshift(__v, end - __start);		\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+		*__vptr = __v;						\
+		break;							\
+	}								\
+	if (end % ts) {							\
+		cshift = end % ts;					\
+		mask = ~((~(type) 0) << cshift);			\
+		cmask = __ptr[this_unit];				\
+		cmask &= mask;						\
+		__v = _bt_piecewise_lshift(__v, cshift);		\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+		end -= cshift;						\
+		this_unit--;						\
+	}								\
+	for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
+		__v = _bt_piecewise_lshift(__v, ts);			\
+		__v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+		end -= ts;						\
+	}								\
+	if (__start % ts) {						\
+		mask = ~((~(type) 0) << (ts - (__start % ts)));		\
+		cmask = __ptr[this_unit];				\
+		cmask >>= (__start % ts);				\
+		cmask &= mask;						\
+		__v = _bt_piecewise_lshift(__v, ts - (__start % ts));	\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+	} else {							\
+		__v = _bt_piecewise_lshift(__v, ts);			\
+		__v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+	}								\
+	*__vptr = __v;							\
+} while (0)
+
+#define _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)	\
+do {									\
+	typeof(*(_vptr)) *__vptr = (_vptr);				\
+	typeof(*__vptr) __v;						\
+	type *__ptr = (void *) (_ptr);					\
+	unsigned long __start = (_start), __length = (_length);		\
+	type mask, cmask;						\
+	unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */	\
+	unsigned long start_unit, end_unit, this_unit;			\
+	unsigned long end, cshift; /* cshift is "complement shift" */	\
+									\
+	if (!__length) {						\
+		*__vptr = 0;						\
+		break;							\
+	}								\
+									\
+	end = __start + __length;					\
+	start_unit = __start / ts;					\
+	end_unit = (end + (ts - 1)) / ts;				\
+									\
+	this_unit = start_unit;						\
+	if (_bt_is_signed_type(typeof(__v))				\
+	    && (__ptr[this_unit] & ((type) 1 << (ts - (__start % ts) - 1)))) \
+		__v = ~(typeof(__v)) 0;					\
+	else								\
+		__v = 0;						\
+	if (start_unit == end_unit - 1) {				\
+		cmask = __ptr[this_unit];				\
+		cmask >>= (ts - (end % ts)) % ts;			\
+		if ((end - __start) % ts) {				\
+			mask = ~((~(type) 0) << (end - __start));	\
+			cmask &= mask;					\
+		}							\
+		__v = _bt_piecewise_lshift(__v, end - __start);		\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+		*__vptr = __v;						\
+		break;							\
+	}								\
+	if (__start % ts) {						\
+		cshift = __start % ts;					\
+		mask = ~((~(type) 0) << (ts - cshift));			\
+		cmask = __ptr[this_unit];				\
+		cmask &= mask;						\
+		__v = _bt_piecewise_lshift(__v, ts - cshift);		\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+		__start += ts - cshift;					\
+		this_unit++;						\
+	}								\
+	for (; this_unit < end_unit - 1; this_unit++) {			\
+		__v = _bt_piecewise_lshift(__v, ts);			\
+		__v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+		__start += ts;						\
+	}								\
+	if (end % ts) {							\
+		mask = ~((~(type) 0) << (end % ts));			\
+		cmask = __ptr[this_unit];				\
+		cmask >>= ts - (end % ts);				\
+		cmask &= mask;						\
+		__v = _bt_piecewise_lshift(__v, end % ts);		\
+		__v |= _bt_unsigned_cast(typeof(__v), cmask);		\
+	} else {							\
+		__v = _bt_piecewise_lshift(__v, ts);			\
+		__v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\
+	}								\
+	*__vptr = __v;							\
+} while (0)
+
+/*
+ * bt_bitfield_read - read integer from a bitfield in native endianness
+ * bt_bitfield_read_le - read integer from a bitfield in little endian
+ * bt_bitfield_read_be - read integer from a bitfield in big endian
+ */
+
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+
+#define bt_bitfield_read(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
+
+#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
+	
+#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_be(_ptr, unsigned char, _start, _length, _vptr)
+
+#elif (__BYTE_ORDER == __BIG_ENDIAN)
+
+#define bt_bitfield_read(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
+
+#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_le(_ptr, unsigned char, _start, _length, _vptr)
+	
+#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)		\
+	_bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
+
+#else /* (__BYTE_ORDER == __PDP_ENDIAN) */
+
+#error "Byte order not supported"
+
+#endif
+
+#endif /* _BABELTRACE_BITFIELD_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 03/19] lttng: BUILD_RUNTIME_BUG_ON
  2011-11-26 15:03   ` [lttng-dev] [PATCH 02/19] lttng lib: portable bitfield read/write header Mathieu Desnoyers
@ 2011-11-26 15:03     ` Mathieu Desnoyers
  2011-11-26 15:03       ` [lttng-dev] [PATCH 04/19] lttng: offset alignment header Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lib/bug.h |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lib/bug.h

diff --git a/drivers/staging/lttng/lib/bug.h b/drivers/staging/lttng/lib/bug.h
new file mode 100644
index 0000000..8243cc9
--- /dev/null
+++ b/drivers/staging/lttng/lib/bug.h
@@ -0,0 +1,29 @@
+#ifndef _LTTNG_BUG_H
+#define _LTTNG_BUG_H
+
+/*
+ * lib/bug.h
+ *
+ * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+/**
+ * BUILD_RUNTIME_BUG_ON - check condition at build (if constant) or runtime
+ * @condition: the condition which should be false.
+ *
+ * If the condition is a constant and true, the compiler will generate a build
+ * error. If the condition is not constant, a BUG will be triggered at runtime
+ * if the condition is ever true. If the condition is constant and false, no
+ * code is emitted.
+ */
+#define BUILD_RUNTIME_BUG_ON(condition)				\
+	do {							\
+		if (__builtin_constant_p(condition))		\
+			BUILD_BUG_ON(condition);		\
+		else						\
+			BUG_ON(condition);			\
+	} while (0)
+
+#endif
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 04/19] lttng: offset alignment header
  2011-11-26 15:03     ` [lttng-dev] [PATCH 03/19] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers
@ 2011-11-26 15:03       ` Mathieu Desnoyers
  2011-11-26 15:03         ` [lttng-dev] [PATCH 05/19] lttng libs: add Makefile Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lib/align.h |   61 +++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lib/align.h

diff --git a/drivers/staging/lttng/lib/align.h b/drivers/staging/lttng/lib/align.h
new file mode 100644
index 0000000..0b86100
--- /dev/null
+++ b/drivers/staging/lttng/lib/align.h
@@ -0,0 +1,61 @@
+#ifndef _LTTNG_ALIGN_H
+#define _LTTNG_ALIGN_H
+
+/*
+ * lib/align.h
+ *
+ * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include "bug.h"
+
+#define ALIGN_FLOOR(x, a)	__ALIGN_FLOOR_MASK(x, (typeof(x)) (a) - 1)
+#define __ALIGN_FLOOR_MASK(x, mask)	((x) & ~(mask))
+#define PTR_ALIGN_FLOOR(p, a) \
+			((typeof(p)) ALIGN_FLOOR((unsigned long) (p), a))
+
+/*
+ * Align pointer on natural object alignment.
+ */
+#define object_align(obj)	PTR_ALIGN(obj, __alignof__(*(obj)))
+#define object_align_floor(obj)	PTR_ALIGN_FLOOR(obj, __alignof__(*(obj)))
+
+/**
+ * offset_align - Calculate the offset needed to align an object on its natural
+ *                alignment towards higher addresses.
+ * @align_drift:  object offset from an "alignment"-aligned address.
+ * @alignment:    natural object alignment. Must be non-zero, power of 2.
+ *
+ * Returns the offset that must be added to align towards higher
+ * addresses.
+ */
+#define offset_align(align_drift, alignment)				       \
+	({								       \
+		BUILD_RUNTIME_BUG_ON((alignment) == 0			       \
+				   || ((alignment) & ((alignment) - 1)));      \
+		(((alignment) - (align_drift)) & ((alignment) - 1));	       \
+	})
+
+/**
+ * offset_align_floor - Calculate the offset needed to align an object
+ *                      on its natural alignment towards lower addresses.
+ * @align_drift:  object offset from an "alignment"-aligned address.
+ * @alignment:    natural object alignment. Must be non-zero, power of 2.
+ *
+ * Returns the offset that must be substracted to align towards lower addresses.
+ */
+#define offset_align_floor(align_drift, alignment)			       \
+	({								       \
+		BUILD_RUNTIME_BUG_ON((alignment) == 0			       \
+				   || ((alignment) & ((alignment) - 1)));      \
+		(((align_drift) - (alignment)) & ((alignment) - 1);	       \
+	})
+
+#endif /* __KERNEL__ */
+
+#endif
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 05/19] lttng libs: add Makefile
  2011-11-26 15:03       ` [lttng-dev] [PATCH 04/19] lttng: offset alignment header Mathieu Desnoyers
@ 2011-11-26 15:03         ` Mathieu Desnoyers
  2011-11-26 15:03           ` [lttng-dev] [PATCH 06/19] lttng wrappers Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lib/Makefile |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lib/Makefile

diff --git a/drivers/staging/lttng/lib/Makefile b/drivers/staging/lttng/lib/Makefile
new file mode 100644
index 0000000..e5735ec
--- /dev/null
+++ b/drivers/staging/lttng/lib/Makefile
@@ -0,0 +1,11 @@
+obj-m += lib-ring-buffer.o
+
+lib-ring-buffer-objs := \
+	ringbuffer/ring_buffer_backend.o \
+	ringbuffer/ring_buffer_frontend.o \
+	ringbuffer/ring_buffer_iterator.o \
+	ringbuffer/ring_buffer_vfs.o \
+	ringbuffer/ring_buffer_splice.o \
+	ringbuffer/ring_buffer_mmap.o \
+	prio_heap/lttng_prio_heap.o \
+	../wrapper/splice.o
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 06/19] lttng wrappers
  2011-11-26 15:03         ` [lttng-dev] [PATCH 05/19] lttng libs: add Makefile Mathieu Desnoyers
@ 2011-11-26 15:03           ` Mathieu Desnoyers
  2011-11-26 15:03             ` [lttng-dev] [PATCH 07/19] lttng instrumentation: tracepoint events Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Implement wrappers for compatibility with older kernel versions and
kernels with had the libringbuffer (old) patchset applied.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/wrapper/ftrace.h             |   70 ++++++++++++++++++
 drivers/staging/lttng/wrapper/inline_memcpy.h      |   11 +++
 drivers/staging/lttng/wrapper/kallsyms.h           |   28 +++++++
 drivers/staging/lttng/wrapper/perf.h               |   32 ++++++++
 drivers/staging/lttng/wrapper/poll.h               |   16 ++++
 drivers/staging/lttng/wrapper/ringbuffer/api.h     |    1 +
 drivers/staging/lttng/wrapper/ringbuffer/backend.h |    1 +
 .../lttng/wrapper/ringbuffer/backend_internal.h    |    2 +
 .../lttng/wrapper/ringbuffer/backend_types.h       |    1 +
 drivers/staging/lttng/wrapper/ringbuffer/config.h  |    1 +
 .../staging/lttng/wrapper/ringbuffer/frontend.h    |    1 +
 .../lttng/wrapper/ringbuffer/frontend_api.h        |    1 +
 .../lttng/wrapper/ringbuffer/frontend_internal.h   |    1 +
 .../lttng/wrapper/ringbuffer/frontend_types.h      |    1 +
 .../staging/lttng/wrapper/ringbuffer/iterator.h    |    1 +
 drivers/staging/lttng/wrapper/ringbuffer/nohz.h    |    1 +
 drivers/staging/lttng/wrapper/ringbuffer/vatomic.h |    1 +
 drivers/staging/lttng/wrapper/ringbuffer/vfs.h     |    1 +
 drivers/staging/lttng/wrapper/spinlock.h           |   26 +++++++
 drivers/staging/lttng/wrapper/splice.c             |   46 ++++++++++++
 drivers/staging/lttng/wrapper/splice.h             |   23 ++++++
 drivers/staging/lttng/wrapper/trace-clock.h        |   77 ++++++++++++++++++++
 drivers/staging/lttng/wrapper/uuid.h               |   29 ++++++++
 drivers/staging/lttng/wrapper/vmalloc.h            |   49 +++++++++++++
 24 files changed, 421 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/wrapper/ftrace.h
 create mode 100644 drivers/staging/lttng/wrapper/inline_memcpy.h
 create mode 100644 drivers/staging/lttng/wrapper/kallsyms.h
 create mode 100644 drivers/staging/lttng/wrapper/perf.h
 create mode 100644 drivers/staging/lttng/wrapper/poll.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/api.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend_types.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/config.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/iterator.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/nohz.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/vatomic.h
 create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/vfs.h
 create mode 100644 drivers/staging/lttng/wrapper/spinlock.h
 create mode 100644 drivers/staging/lttng/wrapper/splice.c
 create mode 100644 drivers/staging/lttng/wrapper/splice.h
 create mode 100644 drivers/staging/lttng/wrapper/trace-clock.h
 create mode 100644 drivers/staging/lttng/wrapper/uuid.h
 create mode 100644 drivers/staging/lttng/wrapper/vmalloc.h

diff --git a/drivers/staging/lttng/wrapper/ftrace.h b/drivers/staging/lttng/wrapper/ftrace.h
new file mode 100644
index 0000000..ace33c5
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ftrace.h
@@ -0,0 +1,70 @@
+#ifndef _LTT_WRAPPER_FTRACE_H
+#define _LTT_WRAPPER_FTRACE_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
+ * available, else we need to have a kernel that exports this function to GPL
+ * modules.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/ftrace.h>
+
+#ifdef CONFIG_KALLSYMS
+
+#include <linux/kallsyms.h>
+#include "kallsyms.h"
+
+static inline
+int wrapper_register_ftrace_function_probe(char *glob,
+		struct ftrace_probe_ops *ops, void *data)
+{
+	int (*register_ftrace_function_probe_sym)(char *glob,
+			struct ftrace_probe_ops *ops, void *data);
+
+	register_ftrace_function_probe_sym = (void *) kallsyms_lookup_funcptr("register_ftrace_function_probe");
+	if (register_ftrace_function_probe_sym) {
+		return register_ftrace_function_probe_sym(glob, ops, data);
+	} else {
+		printk(KERN_WARNING "LTTng: register_ftrace_function_probe symbol lookup failed.\n");
+		return -EINVAL;
+	}
+}
+
+static inline
+void wrapper_unregister_ftrace_function_probe(char *glob,
+		struct ftrace_probe_ops *ops, void *data)
+{
+	void (*unregister_ftrace_function_probe_sym)(char *glob,
+			struct ftrace_probe_ops *ops, void *data);
+
+	unregister_ftrace_function_probe_sym = (void *) kallsyms_lookup_funcptr("unregister_ftrace_function_probe");
+	if (unregister_ftrace_function_probe_sym) {
+		unregister_ftrace_function_probe_sym(glob, ops, data);
+	} else {
+		printk(KERN_WARNING "LTTng: unregister_ftrace_function_probe symbol lookup failed.\n");
+		WARN_ON(1);
+	}
+}
+
+#else
+
+static inline
+int wrapper_register_ftrace_function_probe(char *glob,
+		struct ftrace_probe_ops *ops, void *data)
+{
+	return register_ftrace_function_probe(glob, ops, data);
+}
+
+static inline
+void wrapper_unregister_ftrace_function_probe(char *glob,
+		struct ftrace_probe_ops *ops, void *data)
+{
+	return unregister_ftrace_function_probe(glob, ops, data);
+}
+#endif
+
+#endif /* _LTT_WRAPPER_FTRACE_H */
diff --git a/drivers/staging/lttng/wrapper/inline_memcpy.h b/drivers/staging/lttng/wrapper/inline_memcpy.h
new file mode 100644
index 0000000..33150cd
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/inline_memcpy.h
@@ -0,0 +1,11 @@
+/*
+ * wrapper/inline_memcpy.h
+ *
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#if !defined(__HAVE_ARCH_INLINE_MEMCPY) && !defined(inline_memcpy)
+#define inline_memcpy memcpy
+#endif
diff --git a/drivers/staging/lttng/wrapper/kallsyms.h b/drivers/staging/lttng/wrapper/kallsyms.h
new file mode 100644
index 0000000..bb45f38
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/kallsyms.h
@@ -0,0 +1,28 @@
+#ifndef _LTT_WRAPPER_KALLSYMS_H
+#define _LTT_WRAPPER_KALLSYMS_H
+
+/*
+ * Copyright (C) 2011 Avik Sil (avik.sil at linaro.org)
+ *
+ * wrapper around kallsyms_lookup_name. Implements arch-dependent code for
+ * arches where the address of the start of the function body is different
+ * from the pointer which can be used to call the function, e.g. ARM THUMB2.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+static inline
+unsigned long kallsyms_lookup_funcptr(const char *name)
+{
+	unsigned long addr;
+
+	addr = kallsyms_lookup_name(name);
+#ifdef CONFIG_ARM
+#ifdef CONFIG_THUMB2_KERNEL
+	if (addr)
+		addr |= 1; /* set bit 0 in address for thumb mode */
+#endif
+#endif
+	return addr;
+}
+#endif /* _LTT_WRAPPER_KALLSYMS_H */
diff --git a/drivers/staging/lttng/wrapper/perf.h b/drivers/staging/lttng/wrapper/perf.h
new file mode 100644
index 0000000..9a6dbfc
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/perf.h
@@ -0,0 +1,32 @@
+#ifndef _LTT_WRAPPER_PERF_H
+#define _LTT_WRAPPER_PERF_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/perf_event.h>
+
+#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99))
+static inline struct perf_event *
+wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
+				int cpu,
+				struct task_struct *task,
+				perf_overflow_handler_t callback)
+{
+	return perf_event_create_kernel_counter(attr, cpu, task, callback, NULL);
+}
+#else
+static inline struct perf_event *
+wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
+				int cpu,
+				struct task_struct *task,
+				perf_overflow_handler_t callback)
+{
+	return perf_event_create_kernel_counter(attr, cpu, task, callback);
+}
+#endif
+
+#endif /* _LTT_WRAPPER_PERF_H */
diff --git a/drivers/staging/lttng/wrapper/poll.h b/drivers/staging/lttng/wrapper/poll.h
new file mode 100644
index 0000000..080717b
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/poll.h
@@ -0,0 +1,16 @@
+#ifndef _LTTNG_WRAPPER_POLL_H
+#define _LTTNG_WRAPPER_POLL_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/poll.h>
+
+#warning "poll_wait_set_exclusive() is defined as no-op. Thundering herd effect can be noticed with large number of consumer threads."
+
+#define poll_wait_set_exclusive(poll_table)
+
+#endif /* _LTTNG_WRAPPER_POLL_H */
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/api.h b/drivers/staging/lttng/wrapper/ringbuffer/api.h
new file mode 100644
index 0000000..182bee2
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/api.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/api.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend.h b/drivers/staging/lttng/wrapper/ringbuffer/backend.h
new file mode 100644
index 0000000..bfdd39d
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/backend.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/backend.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h b/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h
new file mode 100644
index 0000000..00d45e4
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h
@@ -0,0 +1,2 @@
+#include "../../wrapper/inline_memcpy.h"
+#include "../../lib/ringbuffer/backend_internal.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h b/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h
new file mode 100644
index 0000000..c59effd
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/backend_types.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/config.h b/drivers/staging/lttng/wrapper/ringbuffer/config.h
new file mode 100644
index 0000000..0ce7a9d
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/config.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/config.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend.h
new file mode 100644
index 0000000..7c6c070
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/frontend.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h
new file mode 100644
index 0000000..b03c501
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/frontend_api.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h
new file mode 100644
index 0000000..1899101
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/frontend_internal.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h
new file mode 100644
index 0000000..0c23244
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/frontend_types.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/iterator.h b/drivers/staging/lttng/wrapper/ringbuffer/iterator.h
new file mode 100644
index 0000000..76e9edb
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/iterator.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/iterator.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/nohz.h b/drivers/staging/lttng/wrapper/ringbuffer/nohz.h
new file mode 100644
index 0000000..9fbb84d
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/nohz.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/nohz.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h b/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h
new file mode 100644
index 0000000..d578445
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/vatomic.h"
diff --git a/drivers/staging/lttng/wrapper/ringbuffer/vfs.h b/drivers/staging/lttng/wrapper/ringbuffer/vfs.h
new file mode 100644
index 0000000..f8e9ed9
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/ringbuffer/vfs.h
@@ -0,0 +1 @@
+#include "../../lib/ringbuffer/vfs.h"
diff --git a/drivers/staging/lttng/wrapper/spinlock.h b/drivers/staging/lttng/wrapper/spinlock.h
new file mode 100644
index 0000000..8b1ad99
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/spinlock.h
@@ -0,0 +1,26 @@
+#ifndef _LTT_WRAPPER_SPINLOCK_H
+#define _LTT_WRAPPER_SPINLOCK_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33))
+
+#include <linux/string.h>
+
+#define raw_spin_lock_init(lock)					\
+	do {								\
+		raw_spinlock_t __lock = __RAW_SPIN_LOCK_UNLOCKED;	\
+		memcpy(lock, &__lock, sizeof(lock));			\
+	} while (0)
+
+#define raw_spin_is_locked(lock)	__raw_spin_is_locked(lock)
+
+
+#endif
+#endif /* _LTT_WRAPPER_SPINLOCK_H */
diff --git a/drivers/staging/lttng/wrapper/splice.c b/drivers/staging/lttng/wrapper/splice.c
new file mode 100644
index 0000000..ba224ee
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/splice.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
+ * available, else we need to have a kernel that exports this function to GPL
+ * modules.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifdef CONFIG_KALLSYMS
+
+#include <linux/kallsyms.h>
+#include <linux/fs.h>
+#include <linux/splice.h>
+#include "kallsyms.h"
+
+static
+ssize_t (*splice_to_pipe_sym)(struct pipe_inode_info *pipe,
+			      struct splice_pipe_desc *spd);
+
+ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe,
+			       struct splice_pipe_desc *spd)
+{
+	if (!splice_to_pipe_sym)
+		splice_to_pipe_sym = (void *) kallsyms_lookup_funcptr("splice_to_pipe"); 
+	if (splice_to_pipe_sym) {
+		return splice_to_pipe_sym(pipe, spd);
+	} else {
+		printk(KERN_WARNING "LTTng: splice_to_pipe symbol lookup failed.\n");
+		return -ENOSYS;
+	}
+}
+
+#else
+
+#include <linux/fs.h>
+#include <linux/splice.h>
+
+ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe,
+			       struct splice_pipe_desc *spd)
+{
+	return splice_to_pipe(pipe, spd);
+}
+
+#endif
diff --git a/drivers/staging/lttng/wrapper/splice.h b/drivers/staging/lttng/wrapper/splice.h
new file mode 100644
index 0000000..f75309a
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/splice.h
@@ -0,0 +1,23 @@
+#ifndef _LTT_WRAPPER_SPLICE_H
+#define _LTT_WRAPPER_SPLICE_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
+ * available, else we need to have a kernel that exports this function to GPL
+ * modules.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/splice.h>
+
+ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe,
+			       struct splice_pipe_desc *spd);
+
+#ifndef PIPE_DEF_BUFFERS
+#define PIPE_DEF_BUFFERS 16
+#endif
+
+#endif /* _LTT_WRAPPER_SPLICE_H */
diff --git a/drivers/staging/lttng/wrapper/trace-clock.h b/drivers/staging/lttng/wrapper/trace-clock.h
new file mode 100644
index 0000000..11bef42
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/trace-clock.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * Contains LTTng trace clock mapping to LTTng trace clock or mainline monotonic
+ * clock. This wrapper depends on CONFIG_HIGH_RES_TIMERS=y.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifndef _LTT_TRACE_CLOCK_H
+#define _LTT_TRACE_CLOCK_H
+
+#ifdef CONFIG_HAVE_TRACE_CLOCK
+#include <linux/trace-clock.h>
+#else /* CONFIG_HAVE_TRACE_CLOCK */
+
+#include <linux/hardirq.h>
+#include <linux/ktime.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+
+static inline u64 trace_clock_monotonic_wrapper(void)
+{
+	ktime_t ktime;
+
+	/*
+	 * Refuse to trace from NMIs with this wrapper, because an NMI could
+	 * nest over the xtime write seqlock and deadlock.
+	 */
+	if (in_nmi())
+		return (u64) -EIO;
+
+	ktime = ktime_get();
+	return (u64) ktime.tv64;
+}
+
+static inline u32 trace_clock_read32(void)
+{
+	return (u32) trace_clock_monotonic_wrapper();
+}
+
+static inline u64 trace_clock_read64(void)
+{
+	return (u64) trace_clock_monotonic_wrapper();
+}
+
+static inline u64 trace_clock_frequency(void)
+{
+	return (u64)NSEC_PER_SEC;
+}
+
+static inline u32 trace_clock_freq_scale(void)
+{
+	return 1;
+}
+
+static inline int get_trace_clock(void)
+{
+	printk(KERN_WARNING "LTTng: Using mainline kernel monotonic clock.\n");
+	printk(KERN_WARNING "  * NMIs will not be traced,\n");
+	printk(KERN_WARNING "  * expect significant performance degradation compared to the\n");
+	printk(KERN_WARNING "    LTTng trace clocks.\n");
+	printk(KERN_WARNING "Integration of the LTTng 0.x trace clocks into LTTng 2.0 is planned\n");
+	printk(KERN_WARNING "in a near future.\n");
+
+#warning "LTTng: Using mainline kernel monotonic clock. NMIs will not be traced, and expect significant performance degradation compared to the LTTng trace clocks. Integration of the LTTng 0.x trace clocks into LTTng 2.0 is planned in a near future."
+
+	return 0;
+}
+
+static inline void put_trace_clock(void)
+{
+}
+
+#endif /* CONFIG_HAVE_TRACE_CLOCK */
+
+#endif /* _LTT_TRACE_CLOCK_H */
diff --git a/drivers/staging/lttng/wrapper/uuid.h b/drivers/staging/lttng/wrapper/uuid.h
new file mode 100644
index 0000000..bfa67ff
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/uuid.h
@@ -0,0 +1,29 @@
+#ifndef _LTT_WRAPPER_UUID_H
+#define _LTT_WRAPPER_UUID_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#include <linux/uuid.h>
+#else
+
+#include <linux/random.h>
+
+typedef struct {
+	__u8 b[16];
+} uuid_le;
+
+static inline
+void uuid_le_gen(uuid_le *u)
+{
+	generate_random_uuid(u->b);
+}
+
+#endif
+#endif /* _LTT_WRAPPER_UUID_H */
diff --git a/drivers/staging/lttng/wrapper/vmalloc.h b/drivers/staging/lttng/wrapper/vmalloc.h
new file mode 100644
index 0000000..765f2ad
--- /dev/null
+++ b/drivers/staging/lttng/wrapper/vmalloc.h
@@ -0,0 +1,49 @@
+#ifndef _LTT_WRAPPER_VMALLOC_H
+#define _LTT_WRAPPER_VMALLOC_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com)
+ *
+ * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
+ * available, else we need to have a kernel that exports this function to GPL
+ * modules.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifdef CONFIG_KALLSYMS
+
+#include <linux/kallsyms.h>
+#include "kallsyms.h"
+
+static inline
+void wrapper_vmalloc_sync_all(void)
+{
+	void (*vmalloc_sync_all_sym)(void);
+
+	vmalloc_sync_all_sym = (void *) kallsyms_lookup_funcptr("vmalloc_sync_all");
+	if (vmalloc_sync_all_sym) {
+		vmalloc_sync_all_sym();
+	} else {
+#ifdef CONFIG_X86
+		/*
+		 * Only x86 needs vmalloc_sync_all to make sure LTTng does not
+		 * trigger recursive page faults.
+		 */
+		printk(KERN_WARNING "LTTng: vmalloc_sync_all symbol lookup failed.\n");
+		printk(KERN_WARNING "Page fault handler and NMI tracing might trigger faults.\n");
+#endif
+	}
+}
+#else
+
+#include <linux/vmalloc.h>
+
+static inline
+void wrapper_vmalloc_sync_all(void)
+{
+	return vmalloc_sync_all();
+}
+#endif
+
+#endif /* _LTT_WRAPPER_VMALLOC_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 07/19] lttng instrumentation: tracepoint events
  2011-11-26 15:03           ` [lttng-dev] [PATCH 06/19] lttng wrappers Mathieu Desnoyers
@ 2011-11-26 15:03             ` Mathieu Desnoyers
  2011-11-26 15:03               ` [lttng-dev] [PATCH 08/19] lttng: syscall instrumentation Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Modifications to the in-kernel TRACE_EVENT are needed to generate the
compact event descriptions and the probe code LTTng generates. These
changes could apply to upstream TRACE_EVENT, but requires changing the
in-kernel API.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 .../staging/lttng/instrumentation/events/README    |    7 +
 .../instrumentation/events/lttng-module/block.h    |  626 ++++++++++++++++++++
 .../instrumentation/events/lttng-module/irq.h      |  155 +++++
 .../instrumentation/events/lttng-module/kvm.h      |  312 ++++++++++
 .../instrumentation/events/lttng-module/lttng.h    |   34 ++
 .../instrumentation/events/lttng-module/sched.h    |  400 +++++++++++++
 .../instrumentation/events/lttng-module/syscalls.h |   76 +++
 .../lttng/instrumentation/events/mainline/block.h  |  569 ++++++++++++++++++
 .../lttng/instrumentation/events/mainline/irq.h    |  150 +++++
 .../lttng/instrumentation/events/mainline/kvm.h    |  312 ++++++++++
 .../lttng/instrumentation/events/mainline/sched.h  |  397 +++++++++++++
 .../instrumentation/events/mainline/syscalls.h     |   75 +++
 12 files changed, 3113 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/instrumentation/events/README
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/block.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/irq.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/sched.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/block.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/irq.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/kvm.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/sched.h
 create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/syscalls.h

diff --git a/drivers/staging/lttng/instrumentation/events/README b/drivers/staging/lttng/instrumentation/events/README
new file mode 100644
index 0000000..dad2cbb
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/README
@@ -0,0 +1,7 @@
+The workflow for updating patches from newer kernel:
+
+Diff mainline/ and lttng-module/ directories.
+
+Pull the new headers from mainline kernel to mainline/.
+Copy them into lttng-modules.
+Apply diff. Fix conflicts.
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/block.h b/drivers/staging/lttng/instrumentation/events/lttng-module/block.h
new file mode 100644
index 0000000..42184f3
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/block.h
@@ -0,0 +1,626 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM block
+
+#if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_BLOCK_H
+
+#include <linux/blktrace_api.h>
+#include <linux/blkdev.h>
+#include <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+
+#ifndef _TRACE_BLOCK_DEF_
+#define _TRACE_BLOCK_DEF_
+
+#define __blk_dump_cmd(cmd, len)	"<unknown>"
+
+enum {
+	RWBS_FLAG_WRITE		= (1 << 0),
+	RWBS_FLAG_DISCARD	= (1 << 1),
+	RWBS_FLAG_READ		= (1 << 2),
+	RWBS_FLAG_RAHEAD	= (1 << 3),
+	RWBS_FLAG_SYNC		= (1 << 4),
+	RWBS_FLAG_META		= (1 << 5),
+	RWBS_FLAG_SECURE	= (1 << 6),
+};
+
+#endif /* _TRACE_BLOCK_DEF_ */
+
+#define __print_rwbs_flags(rwbs)		\
+	__print_flags(rwbs, "",			\
+		{ RWBS_FLAG_WRITE, "W" },	\
+		{ RWBS_FLAG_DISCARD, "D" },	\
+		{ RWBS_FLAG_READ, "R" },	\
+		{ RWBS_FLAG_RAHEAD, "A" },	\
+		{ RWBS_FLAG_SYNC, "S" },	\
+		{ RWBS_FLAG_META, "M" },	\
+		{ RWBS_FLAG_SECURE, "E" })
+
+#define blk_fill_rwbs(rwbs, rw, bytes)					      \
+		tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE :	      \
+			( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD :	      \
+			( (bytes) ? RWBS_FLAG_READ :			      \
+			( 0 ))))					      \
+			| ((rw) & REQ_RAHEAD ? RWBS_FLAG_RAHEAD : 0)	      \
+			| ((rw) & REQ_SYNC ? RWBS_FLAG_SYNC : 0)	      \
+			| ((rw) & REQ_META ? RWBS_FLAG_META : 0)	      \
+			| ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0))
+
+DECLARE_EVENT_CLASS(block_rq_with_error,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq),
+
+	TP_STRUCT__entry(
+		__field(  dev_t,	dev			)
+		__field(  sector_t,	sector			)
+		__field(  unsigned int,	nr_sector		)
+		__field(  int,		errors			)
+		__field(  unsigned int,	rwbs			)
+		__dynamic_array_hex( unsigned char,	cmd,
+			(rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+				rq->cmd_len : 0)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, rq->rq_disk ? disk_devt(rq->rq_disk) : 0)
+		tp_assign(sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_pos(rq))
+		tp_assign(nr_sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_sectors(rq))
+		tp_assign(errors, rq->errors)
+		blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq))
+		tp_memcpy_dyn(cmd, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					rq->cmd : NULL);
+	),
+
+	TP_printk("%d,%d %s (%s) %llu + %u [%d]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  __blk_dump_cmd(__get_dynamic_array(cmd),
+				 __get_dynamic_array_len(cmd)),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->errors)
+)
+
+/**
+ * block_rq_abort - abort block operation request
+ * @q: queue containing the block operation request
+ * @rq: block IO operation request
+ *
+ * Called immediately after pending block IO operation request @rq in
+ * queue @q is aborted. The fields in the operation request @rq
+ * can be examined to determine which device and sectors the pending
+ * operation would access.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_abort,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+)
+
+/**
+ * block_rq_requeue - place block IO request back on a queue
+ * @q: queue holding operation
+ * @rq: block IO operation request
+ *
+ * The block operation request @rq is being placed back into queue
+ * @q.  For some reason the request was not completed and needs to be
+ * put back in the queue.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+)
+
+/**
+ * block_rq_complete - block IO operation completed by device driver
+ * @q: queue containing the block operation request
+ * @rq: block operations request
+ *
+ * The block_rq_complete tracepoint event indicates that some portion
+ * of operation request has been completed by the device driver.  If
+ * the @rq->bio is %NULL, then there is absolutely no additional work to
+ * do for the request. If @rq->bio is non-NULL then there is
+ * additional work required to complete the request.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_complete,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+)
+
+DECLARE_EVENT_CLASS(block_rq,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq),
+
+	TP_STRUCT__entry(
+		__field(  dev_t,	dev			)
+		__field(  sector_t,	sector			)
+		__field(  unsigned int,	nr_sector		)
+		__field(  unsigned int,	bytes			)
+		__field(  unsigned int,	rwbs			)
+		__array_text(  char,         comm,   TASK_COMM_LEN   )
+		__dynamic_array_hex( unsigned char,	cmd,
+			(rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+				rq->cmd_len : 0)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, rq->rq_disk ? disk_devt(rq->rq_disk) : 0)
+		tp_assign(sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_pos(rq))
+		tp_assign(nr_sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_sectors(rq))
+		tp_assign(bytes, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					blk_rq_bytes(rq) : 0)
+		blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq))
+		tp_memcpy_dyn(cmd, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					rq->cmd : NULL);
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("%d,%d %s %u (%s) %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  __entry->bytes,
+		  __blk_dump_cmd(__get_dynamic_array(cmd),
+				 __get_dynamic_array_len(cmd)),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+)
+
+/**
+ * block_rq_insert - insert block operation request into queue
+ * @q: target queue
+ * @rq: block IO operation request
+ *
+ * Called immediately before block operation request @rq is inserted
+ * into queue @q.  The fields in the operation request @rq struct can
+ * be examined to determine which device and sectors the pending
+ * operation would access.
+ */
+DEFINE_EVENT(block_rq, block_rq_insert,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+)
+
+/**
+ * block_rq_issue - issue pending block IO request operation to device driver
+ * @q: queue holding operation
+ * @rq: block IO operation operation request
+ *
+ * Called when block operation request @rq from queue @q is sent to a
+ * device driver for processing.
+ */
+DEFINE_EVENT(block_rq, block_rq_issue,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+)
+
+/**
+ * block_bio_bounce - used bounce buffer when processing block operation
+ * @q: queue holding the block operation
+ * @bio: block operation
+ *
+ * A bounce buffer was used to handle the block operation @bio in @q.
+ * This occurs when hardware limitations prevent a direct transfer of
+ * data between the @bio data memory area and the IO device.  Use of a
+ * bounce buffer requires extra copying of data and decreases
+ * performance.
+ */
+TRACE_EVENT(block_bio_bounce,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__field( unsigned int,	rwbs			)
+		__array_text( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, bio->bi_bdev ?
+					  bio->bi_bdev->bd_dev : 0)
+		tp_assign(sector, bio->bi_sector)
+		tp_assign(nr_sector, bio->bi_size >> 9)
+		blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size)
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+)
+
+/**
+ * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
+ * @bio: block operation completed
+ * @error: io error value
+ *
+ * This tracepoint indicates there is no further work to do on this
+ * block IO operation @bio.
+ */
+TRACE_EVENT(block_bio_complete,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int error),
+
+	TP_ARGS(q, bio, error),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned,	nr_sector	)
+		__field( int,		error		)
+		__field( unsigned int,	rwbs		)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, bio->bi_bdev->bd_dev)
+		tp_assign(sector, bio->bi_sector)
+		tp_assign(nr_sector, bio->bi_size >> 9)
+		tp_assign(error, error)
+		blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size)
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%d]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->error)
+)
+
+DECLARE_EVENT_CLASS(block_bio,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__field( unsigned int,	rwbs			)
+		__array_text( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, bio->bi_bdev->bd_dev)
+		tp_assign(sector, bio->bi_sector)
+		tp_assign(nr_sector, bio->bi_size >> 9)
+		blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size)
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+)
+
+/**
+ * block_bio_backmerge - merging block operation to the end of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block request @bio to the end of an existing block request
+ * in queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_backmerge,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+)
+
+/**
+ * block_bio_frontmerge - merging block operation to the beginning of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block IO operation @bio to the beginning of an existing block
+ * operation in queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_frontmerge,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+)
+
+/**
+ * block_bio_queue - putting new block IO operation in queue
+ * @q: queue holding operation
+ * @bio: new block operation
+ *
+ * About to place the block IO operation @bio into queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_queue,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+)
+
+DECLARE_EVENT_CLASS(block_get_rq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__field( unsigned int,	rwbs			)
+		__array_text( char,		comm,	TASK_COMM_LEN	)
+        ),
+
+	TP_fast_assign(
+		tp_assign(dev, bio ? bio->bi_bdev->bd_dev : 0)
+		tp_assign(sector, bio ? bio->bi_sector : 0)
+		tp_assign(nr_sector, bio ? bio->bi_size >> 9 : 0)
+		blk_fill_rwbs(rwbs, bio ? bio->bi_rw : 0,
+			      bio ? bio->bi_size >> 9 : 0)
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+        ),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+)
+
+/**
+ * block_getrq - get a free request entry in queue for block IO operations
+ * @q: queue for operations
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * A request struct for queue @q has been allocated to handle the
+ * block IO operation @bio.
+ */
+DEFINE_EVENT(block_get_rq, block_getrq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw)
+)
+
+/**
+ * block_sleeprq - waiting to get a free request entry in queue for block IO operation
+ * @q: queue for operation
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * In the case where a request struct cannot be provided for queue @q
+ * the process needs to wait for an request struct to become
+ * available.  This tracepoint event is generated each time the
+ * process goes to sleep waiting for request struct become available.
+ */
+DEFINE_EVENT(block_get_rq, block_sleeprq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw)
+)
+
+/**
+ * block_plug - keep operations requests in request queue
+ * @q: request queue to plug
+ *
+ * Plug the request queue @q.  Do not allow block operation requests
+ * to be sent to the device driver. Instead, accumulate requests in
+ * the queue to improve throughput performance of the block device.
+ */
+TRACE_EVENT(block_plug,
+
+	TP_PROTO(struct request_queue *q),
+
+	TP_ARGS(q),
+
+	TP_STRUCT__entry(
+		__array_text( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("[%s]", __entry->comm)
+)
+
+DECLARE_EVENT_CLASS(block_unplug,
+
+	TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
+
+	TP_ARGS(q, depth, explicit),
+
+	TP_STRUCT__entry(
+		__field( int,		nr_rq			)
+		__array_text( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		tp_assign(nr_rq, depth)
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
+)
+
+/**
+ * block_unplug - release of operations requests in request queue
+ * @q: request queue to unplug
+ * @depth: number of requests just added to the queue
+ * @explicit: whether this was an explicit unplug, or one from schedule()
+ *
+ * Unplug request queue @q because device driver is scheduled to work
+ * on elements in the request queue.
+ */
+DEFINE_EVENT(block_unplug, block_unplug,
+
+	TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
+
+	TP_ARGS(q, depth, explicit)
+)
+
+/**
+ * block_split - split a single bio struct into two bio structs
+ * @q: queue containing the bio
+ * @bio: block operation being split
+ * @new_sector: The starting sector for the new bio
+ *
+ * The bio request @bio in request queue @q needs to be split into two
+ * bio requests. The newly created @bio request starts at
+ * @new_sector. This split may be required due to hardware limitation
+ * such as operation crossing device boundaries in a RAID system.
+ */
+TRACE_EVENT(block_split,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio,
+		 unsigned int new_sector),
+
+	TP_ARGS(q, bio, new_sector),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev				)
+		__field( sector_t,	sector				)
+		__field( sector_t,	new_sector			)
+		__field( unsigned int,	rwbs		)
+		__array_text( char,		comm,		TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, bio->bi_bdev->bd_dev)
+		tp_assign(sector, bio->bi_sector)
+		tp_assign(new_sector, new_sector)
+		blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size)
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+	),
+
+	TP_printk("%d,%d %s %llu / %llu [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  (unsigned long long)__entry->new_sector,
+		  __entry->comm)
+)
+
+/**
+ * block_bio_remap - map request for a logical device to the raw device
+ * @q: queue holding the operation
+ * @bio: revised operation
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * An operation for a logical device has been mapped to the
+ * raw block device.
+ */
+TRACE_EVENT(block_bio_remap,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
+		 sector_t from),
+
+	TP_ARGS(q, bio, dev, from),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned int,	nr_sector	)
+		__field( dev_t,		old_dev		)
+		__field( sector_t,	old_sector	)
+		__field( unsigned int,	rwbs		)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, bio->bi_bdev->bd_dev)
+		tp_assign(sector, bio->bi_sector)
+		tp_assign(nr_sector, bio->bi_size >> 9)
+		tp_assign(old_dev, dev)
+		tp_assign(old_sector, from)
+		blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size)
+	),
+
+	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector,
+		  MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+		  (unsigned long long)__entry->old_sector)
+)
+
+/**
+ * block_rq_remap - map request for a block operation request
+ * @q: queue holding the operation
+ * @rq: block IO operation request
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * The block operation request @rq in @q has been remapped.  The block
+ * operation request @rq holds the current information and @from hold
+ * the original sector.
+ */
+TRACE_EVENT(block_rq_remap,
+
+	TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
+		 sector_t from),
+
+	TP_ARGS(q, rq, dev, from),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned int,	nr_sector	)
+		__field( dev_t,		old_dev		)
+		__field( sector_t,	old_sector	)
+		__field( unsigned int,	rwbs		)
+	),
+
+	TP_fast_assign(
+		tp_assign(dev, disk_devt(rq->rq_disk))
+		tp_assign(sector, blk_rq_pos(rq))
+		tp_assign(nr_sector, blk_rq_sectors(rq))
+		tp_assign(old_dev, dev)
+		tp_assign(old_sector, from)
+		blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq))
+	),
+
+	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __print_rwbs_flags(__entry->rwbs),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector,
+		  MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+		  (unsigned long long)__entry->old_sector)
+)
+
+#undef __print_rwbs_flags
+#undef blk_fill_rwbs
+
+#endif /* _TRACE_BLOCK_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h b/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h
new file mode 100644
index 0000000..344015d
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h
@@ -0,0 +1,155 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
+#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IRQ_H
+
+#include <linux/tracepoint.h>
+
+#ifndef _TRACE_IRQ_DEF_
+#define _TRACE_IRQ_DEF_
+
+struct irqaction;
+struct softirq_action;
+
+#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
+#define show_softirq_name(val)				\
+	__print_symbolic(val,				\
+			 softirq_name(HI),		\
+			 softirq_name(TIMER),		\
+			 softirq_name(NET_TX),		\
+			 softirq_name(NET_RX),		\
+			 softirq_name(BLOCK),		\
+			 softirq_name(BLOCK_IOPOLL),	\
+			 softirq_name(TASKLET),		\
+			 softirq_name(SCHED),		\
+			 softirq_name(HRTIMER),		\
+			 softirq_name(RCU))
+
+#endif /* _TRACE_IRQ_DEF_ */
+
+/**
+ * irq_handler_entry - called immediately before the irq action handler
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ *
+ * The struct irqaction pointed to by @action contains various
+ * information about the handler, including the device name,
+ * @action->name, and the device id, @action->dev_id. When used in
+ * conjunction with the irq_handler_exit tracepoint, we can figure
+ * out irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_entry,
+
+	TP_PROTO(int irq, struct irqaction *action),
+
+	TP_ARGS(irq, action),
+
+	TP_STRUCT__entry(
+		__field(	int,	irq		)
+		__string(	name,	action->name	)
+	),
+
+	TP_fast_assign(
+		tp_assign(irq, irq)
+		tp_strcpy(name, action->name)
+	),
+
+	TP_printk("irq=%d name=%s", __entry->irq, __get_str(name))
+)
+
+/**
+ * irq_handler_exit - called immediately after the irq action handler returns
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ * @ret: return value
+ *
+ * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding
+ * @action->handler scuccessully handled this irq. Otherwise, the irq might be
+ * a shared irq line, or the irq was not handled successfully. Can be used in
+ * conjunction with the irq_handler_entry to understand irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_exit,
+
+	TP_PROTO(int irq, struct irqaction *action, int ret),
+
+	TP_ARGS(irq, action, ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	irq	)
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		tp_assign(irq, irq)
+		tp_assign(ret, ret)
+	),
+
+	TP_printk("irq=%d ret=%s",
+		  __entry->irq, __entry->ret ? "handled" : "unhandled")
+)
+
+DECLARE_EVENT_CLASS(softirq,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	vec	)
+	),
+
+	TP_fast_assign(
+		tp_assign(vec, vec_nr)
+	),
+
+	TP_printk("vec=%u [action=%s]", __entry->vec,
+		  show_softirq_name(__entry->vec))
+)
+
+/**
+ * softirq_entry - called immediately before the softirq handler
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_exit tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_entry,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+)
+
+/**
+ * softirq_exit - called immediately after the softirq handler returns
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_exit,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+)
+
+/**
+ * softirq_raise - called immediately when a softirq is raised
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq raise to run latency.
+ */
+DEFINE_EVENT(softirq, softirq_raise,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+)
+
+#endif /*  _TRACE_IRQ_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h b/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h
new file mode 100644
index 0000000..e10455b
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h
@@ -0,0 +1,312 @@
+#if !defined(_TRACE_KVM_MAIN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_MAIN_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x }
+
+#define kvm_trace_exit_reason						\
+	ERSN(UNKNOWN), ERSN(EXCEPTION), ERSN(IO), ERSN(HYPERCALL),	\
+	ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN),	\
+	ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR),	\
+	ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\
+	ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI)
+
+TRACE_EVENT(kvm_userspace_exit,
+	    TP_PROTO(__u32 reason, int errno),
+	    TP_ARGS(reason, errno),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		reason		)
+		__field(	int,		errno		)
+	),
+
+	TP_fast_assign(
+		tp_assign(reason, reason)
+		tp_assign(errno, errno)
+	),
+
+	TP_printk("reason %s (%d)",
+		  __entry->errno < 0 ?
+		  (__entry->errno == -EINTR ? "restart" : "error") :
+		  __print_symbolic(__entry->reason, kvm_trace_exit_reason),
+		  __entry->errno < 0 ? -__entry->errno : __entry->reason)
+)
+
+#if defined(__KVM_HAVE_IOAPIC)
+TRACE_EVENT(kvm_set_irq,
+	TP_PROTO(unsigned int gsi, int level, int irq_source_id),
+	TP_ARGS(gsi, level, irq_source_id),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	gsi		)
+		__field(	int,		level		)
+		__field(	int,		irq_source_id	)
+	),
+
+	TP_fast_assign(
+		tp_assign(gsi, gsi)
+		tp_assign(level, level)
+		tp_assign(irq_source_id, irq_source_id)
+	),
+
+	TP_printk("gsi %u level %d source %d",
+		  __entry->gsi, __entry->level, __entry->irq_source_id)
+)
+
+#define kvm_deliver_mode		\
+	{0x0, "Fixed"},			\
+	{0x1, "LowPrio"},		\
+	{0x2, "SMI"},			\
+	{0x3, "Res3"},			\
+	{0x4, "NMI"},			\
+	{0x5, "INIT"},			\
+	{0x6, "SIPI"},			\
+	{0x7, "ExtINT"}
+
+TRACE_EVENT(kvm_ioapic_set_irq,
+	    TP_PROTO(__u64 e, int pin, bool coalesced),
+	    TP_ARGS(e, pin, coalesced),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		e		)
+		__field(	int,		pin		)
+		__field(	bool,		coalesced	)
+	),
+
+	TP_fast_assign(
+		tp_assign(e, e)
+		tp_assign(pin, pin)
+		tp_assign(coalesced, coalesced)
+	),
+
+	TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s",
+		  __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e,
+		  __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->e & (1<<11)) ? "logical" : "physical",
+		  (__entry->e & (1<<15)) ? "level" : "edge",
+		  (__entry->e & (1<<16)) ? "|masked" : "",
+		  __entry->coalesced ? " (coalesced)" : "")
+)
+
+TRACE_EVENT(kvm_msi_set_irq,
+	    TP_PROTO(__u64 address, __u64 data),
+	    TP_ARGS(address, data),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		address		)
+		__field(	__u64,		data		)
+	),
+
+	TP_fast_assign(
+		tp_assign(address, address)
+		tp_assign(data, data)
+	),
+
+	TP_printk("dst %u vec %x (%s|%s|%s%s)",
+		  (u8)(__entry->address >> 12), (u8)__entry->data,
+		  __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->address & (1<<2)) ? "logical" : "physical",
+		  (__entry->data & (1<<15)) ? "level" : "edge",
+		  (__entry->address & (1<<3)) ? "|rh" : "")
+)
+
+#define kvm_irqchips						\
+	{KVM_IRQCHIP_PIC_MASTER,	"PIC master"},		\
+	{KVM_IRQCHIP_PIC_SLAVE,		"PIC slave"},		\
+	{KVM_IRQCHIP_IOAPIC,		"IOAPIC"}
+
+TRACE_EVENT(kvm_ack_irq,
+	TP_PROTO(unsigned int irqchip, unsigned int pin),
+	TP_ARGS(irqchip, pin),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	irqchip		)
+		__field(	unsigned int,	pin		)
+	),
+
+	TP_fast_assign(
+		tp_assign(irqchip, irqchip)
+		tp_assign(pin, pin)
+	),
+
+	TP_printk("irqchip %s pin %u",
+		  __print_symbolic(__entry->irqchip, kvm_irqchips),
+		 __entry->pin)
+)
+
+
+
+#endif /* defined(__KVM_HAVE_IOAPIC) */
+
+#define KVM_TRACE_MMIO_READ_UNSATISFIED 0
+#define KVM_TRACE_MMIO_READ 1
+#define KVM_TRACE_MMIO_WRITE 2
+
+#define kvm_trace_symbol_mmio \
+	{ KVM_TRACE_MMIO_READ_UNSATISFIED, "unsatisfied-read" }, \
+	{ KVM_TRACE_MMIO_READ, "read" }, \
+	{ KVM_TRACE_MMIO_WRITE, "write" }
+
+TRACE_EVENT(kvm_mmio,
+	TP_PROTO(int type, int len, u64 gpa, u64 val),
+	TP_ARGS(type, len, gpa, val),
+
+	TP_STRUCT__entry(
+		__field(	u32,	type		)
+		__field(	u32,	len		)
+		__field(	u64,	gpa		)
+		__field(	u64,	val		)
+	),
+
+	TP_fast_assign(
+		tp_assign(type, type)
+		tp_assign(len, len)
+		tp_assign(gpa, gpa)
+		tp_assign(val, val)
+	),
+
+	TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx",
+		  __print_symbolic(__entry->type, kvm_trace_symbol_mmio),
+		  __entry->len, __entry->gpa, __entry->val)
+)
+
+#define kvm_fpu_load_symbol	\
+	{0, "unload"},		\
+	{1, "load"}
+
+TRACE_EVENT(kvm_fpu,
+	TP_PROTO(int load),
+	TP_ARGS(load),
+
+	TP_STRUCT__entry(
+		__field(	u32,	        load		)
+	),
+
+	TP_fast_assign(
+		tp_assign(load, load)
+	),
+
+	TP_printk("%s", __print_symbolic(__entry->load, kvm_fpu_load_symbol))
+)
+
+TRACE_EVENT(kvm_age_page,
+	TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref),
+	TP_ARGS(hva, slot, ref),
+
+	TP_STRUCT__entry(
+		__field(	u64,	hva		)
+		__field(	u64,	gfn		)
+		__field(	u8,	referenced	)
+	),
+
+	TP_fast_assign(
+		tp_assign(hva, hva)
+		tp_assign(gfn,
+		  slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT))
+		tp_assign(referenced, ref)
+	),
+
+	TP_printk("hva %llx gfn %llx %s",
+		  __entry->hva, __entry->gfn,
+		  __entry->referenced ? "YOUNG" : "OLD")
+)
+
+#ifdef CONFIG_KVM_ASYNC_PF
+DECLARE_EVENT_CLASS(kvm_async_get_page_class,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn),
+
+	TP_STRUCT__entry(
+		__field(__u64, gva)
+		__field(u64, gfn)
+	),
+
+	TP_fast_assign(
+		tp_assign(gva, gva)
+		tp_assign(gfn, gfn)
+	),
+
+	TP_printk("gva = %#llx, gfn = %#llx", __entry->gva, __entry->gfn)
+)
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_try_async_get_page,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn)
+)
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_async_pf_doublefault,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn)
+)
+
+DECLARE_EVENT_CLASS(kvm_async_pf_nopresent_ready,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva),
+
+	TP_STRUCT__entry(
+		__field(__u64, token)
+		__field(__u64, gva)
+	),
+
+	TP_fast_assign(
+		tp_assign(token, token)
+		tp_assign(gva, gva)
+	),
+
+	TP_printk("token %#llx gva %#llx", __entry->token, __entry->gva)
+
+)
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_not_present,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva)
+)
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_ready,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva)
+)
+
+TRACE_EVENT(
+	kvm_async_pf_completed,
+	TP_PROTO(unsigned long address, struct page *page, u64 gva),
+	TP_ARGS(address, page, gva),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, address)
+		__field(pfn_t, pfn)
+		__field(u64, gva)
+		),
+
+	TP_fast_assign(
+		tp_assign(address, address)
+		tp_assign(pfn, page ? page_to_pfn(page) : 0)
+		tp_assign(gva, gva)
+		),
+
+	TP_printk("gva %#llx address %#lx pfn %#llx",  __entry->gva,
+		  __entry->address, __entry->pfn)
+)
+
+#endif
+
+#endif /* _TRACE_KVM_MAIN_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h b/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h
new file mode 100644
index 0000000..6f3d6d1
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h
@@ -0,0 +1,34 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lttng
+
+#if !defined(_TRACE_LTTNG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_LTTNG_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(lttng_metadata,
+
+	TP_PROTO(const char *str),
+
+	TP_ARGS(str),
+
+	/*
+	 * Not exactly a string: more a sequence of bytes (dynamic
+	 * array) without the length. This is a dummy anyway: we only
+	 * use this declaration to generate an event metadata entry.
+	 */
+	TP_STRUCT__entry(
+		__string(	str,		str	)
+	),
+
+	TP_fast_assign(
+		tp_strcpy(str, str)
+	),
+
+	TP_printk("")
+)
+
+#endif /*  _TRACE_LTTNG_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h b/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h
new file mode 100644
index 0000000..33f6921
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h
@@ -0,0 +1,400 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sched
+
+#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SCHED_H
+
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+#ifndef _TRACE_SCHED_DEF_
+#define _TRACE_SCHED_DEF_
+
+static inline long __trace_sched_switch_state(struct task_struct *p)
+{
+	long state = p->state;
+
+#ifdef CONFIG_PREEMPT
+	/*
+	 * For all intents and purposes a preempted task is a running task.
+	 */
+	if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE)
+		state = TASK_RUNNING;
+#endif
+
+	return state;
+}
+
+#endif /* _TRACE_SCHED_DEF_ */
+
+/*
+ * Tracepoint for calling kthread_stop, performed to end a kthread:
+ */
+TRACE_EVENT(sched_kthread_stop,
+
+	TP_PROTO(struct task_struct *t),
+
+	TP_ARGS(t),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	tid			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, t->comm, TASK_COMM_LEN)
+		tp_assign(tid, t->pid)
+	),
+
+	TP_printk("comm=%s tid=%d", __entry->comm, __entry->tid)
+)
+
+/*
+ * Tracepoint for the return value of the kthread stopping:
+ */
+TRACE_EVENT(sched_kthread_stop_ret,
+
+	TP_PROTO(int ret),
+
+	TP_ARGS(ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		tp_assign(ret, ret)
+	),
+
+	TP_printk("ret=%d", __entry->ret)
+)
+
+/*
+ * Tracepoint for waking up a task:
+ */
+DECLARE_EVENT_CLASS(sched_wakeup_template,
+
+	TP_PROTO(struct task_struct *p, int success),
+
+	TP_ARGS(p, success),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	tid			)
+		__field(	int,	prio			)
+		__field(	int,	success			)
+		__field(	int,	target_cpu		)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, p->comm, TASK_COMM_LEN)
+		tp_assign(tid, p->pid)
+		tp_assign(prio, p->prio)
+		tp_assign(success, success)
+		tp_assign(target_cpu, task_cpu(p))
+	),
+
+	TP_printk("comm=%s tid=%d prio=%d success=%d target_cpu=%03d",
+		  __entry->comm, __entry->tid, __entry->prio,
+		  __entry->success, __entry->target_cpu)
+)
+
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
+	     TP_PROTO(struct task_struct *p, int success),
+	     TP_ARGS(p, success))
+
+/*
+ * Tracepoint for waking up a new task:
+ */
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
+	     TP_PROTO(struct task_struct *p, int success),
+	     TP_ARGS(p, success))
+
+/*
+ * Tracepoint for task switches, performed by the scheduler:
+ */
+TRACE_EVENT(sched_switch,
+
+	TP_PROTO(struct task_struct *prev,
+		 struct task_struct *next),
+
+	TP_ARGS(prev, next),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	prev_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	prev_tid			)
+		__field(	int,	prev_prio			)
+		__field(	long,	prev_state			)
+		__array_text(	char,	next_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	next_tid			)
+		__field(	int,	next_prio			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(next_comm, next->comm, TASK_COMM_LEN)
+		tp_assign(prev_tid, prev->pid)
+		tp_assign(prev_prio, prev->prio - MAX_RT_PRIO)
+		tp_assign(prev_state, __trace_sched_switch_state(prev))
+		tp_memcpy(prev_comm, prev->comm, TASK_COMM_LEN)
+		tp_assign(next_tid, next->pid)
+		tp_assign(next_prio, next->prio - MAX_RT_PRIO)
+	),
+
+	TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_tid=%d next_prio=%d",
+		__entry->prev_comm, __entry->prev_tid, __entry->prev_prio,
+		__entry->prev_state ?
+		  __print_flags(__entry->prev_state, "|",
+				{ 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" },
+				{ 16, "Z" }, { 32, "X" }, { 64, "x" },
+				{ 128, "W" }) : "R",
+		__entry->next_comm, __entry->next_tid, __entry->next_prio)
+)
+
+/*
+ * Tracepoint for a task being migrated:
+ */
+TRACE_EVENT(sched_migrate_task,
+
+	TP_PROTO(struct task_struct *p, int dest_cpu),
+
+	TP_ARGS(p, dest_cpu),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	tid			)
+		__field(	int,	prio			)
+		__field(	int,	orig_cpu		)
+		__field(	int,	dest_cpu		)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, p->comm, TASK_COMM_LEN)
+		tp_assign(tid, p->pid)
+		tp_assign(prio, p->prio - MAX_RT_PRIO)
+		tp_assign(orig_cpu, task_cpu(p))
+		tp_assign(dest_cpu, dest_cpu)
+	),
+
+	TP_printk("comm=%s tid=%d prio=%d orig_cpu=%d dest_cpu=%d",
+		  __entry->comm, __entry->tid, __entry->prio,
+		  __entry->orig_cpu, __entry->dest_cpu)
+)
+
+DECLARE_EVENT_CLASS(sched_process_template,
+
+	TP_PROTO(struct task_struct *p),
+
+	TP_ARGS(p),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	tid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, p->comm, TASK_COMM_LEN)
+		tp_assign(tid, p->pid)
+		tp_assign(prio, p->prio - MAX_RT_PRIO)
+	),
+
+	TP_printk("comm=%s tid=%d prio=%d",
+		  __entry->comm, __entry->tid, __entry->prio)
+)
+
+/*
+ * Tracepoint for freeing a task:
+ */
+DEFINE_EVENT(sched_process_template, sched_process_free,
+	     TP_PROTO(struct task_struct *p),
+	     TP_ARGS(p))
+	     
+
+/*
+ * Tracepoint for a task exiting:
+ */
+DEFINE_EVENT(sched_process_template, sched_process_exit,
+	     TP_PROTO(struct task_struct *p),
+	     TP_ARGS(p))
+
+/*
+ * Tracepoint for waiting on task to unschedule:
+ */
+DEFINE_EVENT(sched_process_template, sched_wait_task,
+	TP_PROTO(struct task_struct *p),
+	TP_ARGS(p))
+
+/*
+ * Tracepoint for a waiting task:
+ */
+TRACE_EVENT(sched_process_wait,
+
+	TP_PROTO(struct pid *pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	tid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, current->comm, TASK_COMM_LEN)
+		tp_assign(tid, pid_nr(pid))
+		tp_assign(prio, current->prio - MAX_RT_PRIO)
+	),
+
+	TP_printk("comm=%s tid=%d prio=%d",
+		  __entry->comm, __entry->tid, __entry->prio)
+)
+
+/*
+ * Tracepoint for do_fork:
+ */
+TRACE_EVENT(sched_process_fork,
+
+	TP_PROTO(struct task_struct *parent, struct task_struct *child),
+
+	TP_ARGS(parent, child),
+
+	TP_STRUCT__entry(
+		__array_text(	char,	parent_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	parent_tid			)
+		__array_text(	char,	child_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	child_tid			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(parent_comm, parent->comm, TASK_COMM_LEN)
+		tp_assign(parent_tid, parent->pid)
+		tp_memcpy(child_comm, child->comm, TASK_COMM_LEN)
+		tp_assign(child_tid, child->pid)
+	),
+
+	TP_printk("comm=%s tid=%d child_comm=%s child_tid=%d",
+		__entry->parent_comm, __entry->parent_tid,
+		__entry->child_comm, __entry->child_tid)
+)
+
+/*
+ * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE
+ *     adding sched_stat support to SCHED_FIFO/RR would be welcome.
+ */
+DECLARE_EVENT_CLASS(sched_stat_template,
+
+	TP_PROTO(struct task_struct *tsk, u64 delay),
+
+	TP_ARGS(tsk, delay),
+
+	TP_STRUCT__entry(
+		__array_text( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	tid			)
+		__field( u64,	delay			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, tsk->comm, TASK_COMM_LEN)
+		tp_assign(tid,  tsk->pid)
+		tp_assign(delay, delay)
+	)
+	TP_perf_assign(
+		__perf_count(delay)
+	),
+
+	TP_printk("comm=%s tid=%d delay=%Lu [ns]",
+			__entry->comm, __entry->tid,
+			(unsigned long long)__entry->delay)
+)
+
+
+/*
+ * Tracepoint for accounting wait time (time the task is runnable
+ * but not actually running due to scheduler contention).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_wait,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay))
+
+/*
+ * Tracepoint for accounting sleep time (time the task is not runnable,
+ * including iowait, see below).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_sleep,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay))
+
+/*
+ * Tracepoint for accounting iowait time (time the task is not runnable
+ * due to waiting on IO to complete).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_iowait,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay))
+
+/*
+ * Tracepoint for accounting runtime (time the task is executing
+ * on a CPU).
+ */
+TRACE_EVENT(sched_stat_runtime,
+
+	TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime),
+
+	TP_ARGS(tsk, runtime, vruntime),
+
+	TP_STRUCT__entry(
+		__array_text( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	tid			)
+		__field( u64,	runtime			)
+		__field( u64,	vruntime			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, tsk->comm, TASK_COMM_LEN)
+		tp_assign(tid, tsk->pid)
+		tp_assign(runtime, runtime)
+		tp_assign(vruntime, vruntime)
+	)
+	TP_perf_assign(
+		__perf_count(runtime)
+	),
+
+	TP_printk("comm=%s tid=%d runtime=%Lu [ns] vruntime=%Lu [ns]",
+			__entry->comm, __entry->tid,
+			(unsigned long long)__entry->runtime,
+			(unsigned long long)__entry->vruntime)
+)
+
+/*
+ * Tracepoint for showing priority inheritance modifying a tasks
+ * priority.
+ */
+TRACE_EVENT(sched_pi_setprio,
+
+	TP_PROTO(struct task_struct *tsk, int newprio),
+
+	TP_ARGS(tsk, newprio),
+
+	TP_STRUCT__entry(
+		__array_text( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	tid			)
+		__field( int,	oldprio			)
+		__field( int,	newprio			)
+	),
+
+	TP_fast_assign(
+		tp_memcpy(comm, tsk->comm, TASK_COMM_LEN)
+		tp_assign(tid, tsk->pid)
+		tp_assign(oldprio, tsk->prio - MAX_RT_PRIO)
+		tp_assign(newprio, newprio - MAX_RT_PRIO)
+	),
+
+	TP_printk("comm=%s tid=%d oldprio=%d newprio=%d",
+			__entry->comm, __entry->tid,
+			__entry->oldprio, __entry->newprio)
+)
+
+#endif /* _TRACE_SCHED_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h b/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h
new file mode 100644
index 0000000..a2bb956
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h
@@ -0,0 +1,76 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM raw_syscalls
+#define TRACE_INCLUDE_FILE syscalls
+
+#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENTS_SYSCALLS_H
+
+#include <linux/tracepoint.h>
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+
+#ifndef _TRACE_SYSCALLS_DEF_
+#define _TRACE_SYSCALLS_DEF_
+
+#include <asm/ptrace.h>
+#include <asm/syscall.h>
+
+#endif /* _TRACE_SYSCALLS_DEF_ */
+
+TRACE_EVENT(sys_enter,
+
+	TP_PROTO(struct pt_regs *regs, long id),
+
+	TP_ARGS(regs, id),
+
+	TP_STRUCT__entry(
+		__field(	long,		id		)
+		__array(	unsigned long,	args,	6	)
+	),
+
+	TP_fast_assign(
+		tp_assign(id, id)
+		{
+			tp_memcpy(args,
+				({
+					unsigned long args_copy[6];
+					syscall_get_arguments(current, regs,
+							0, 6, args_copy);
+					args_copy;
+				}), 6 * sizeof(unsigned long));
+		}
+	),
+
+	TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)",
+		  __entry->id,
+		  __entry->args[0], __entry->args[1], __entry->args[2],
+		  __entry->args[3], __entry->args[4], __entry->args[5])
+)
+
+TRACE_EVENT(sys_exit,
+
+	TP_PROTO(struct pt_regs *regs, long ret),
+
+	TP_ARGS(regs, ret),
+
+	TP_STRUCT__entry(
+		__field(	long,	id	)
+		__field(	long,	ret	)
+	),
+
+	TP_fast_assign(
+		tp_assign(id, syscall_get_nr(current, regs))
+		tp_assign(ret, ret)
+	),
+
+	TP_printk("NR %ld = %ld",
+		  __entry->id, __entry->ret)
+)
+
+#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
+
+#endif /* _TRACE_EVENTS_SYSCALLS_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
diff --git a/drivers/staging/lttng/instrumentation/events/mainline/block.h b/drivers/staging/lttng/instrumentation/events/mainline/block.h
new file mode 100644
index 0000000..bf36654
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/mainline/block.h
@@ -0,0 +1,569 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM block
+
+#if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_BLOCK_H
+
+#include <linux/blktrace_api.h>
+#include <linux/blkdev.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(block_rq_with_error,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq),
+
+	TP_STRUCT__entry(
+		__field(  dev_t,	dev			)
+		__field(  sector_t,	sector			)
+		__field(  unsigned int,	nr_sector		)
+		__field(  int,		errors			)
+		__array(  char,		rwbs,	6		)
+		__dynamic_array( char,	cmd,	blk_cmd_buf_len(rq)	)
+	),
+
+	TP_fast_assign(
+		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->sector    = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_pos(rq);
+		__entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_sectors(rq);
+		__entry->errors    = rq->errors;
+
+		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+		blk_dump_cmd(__get_str(cmd), rq);
+	),
+
+	TP_printk("%d,%d %s (%s) %llu + %u [%d]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __entry->rwbs, __get_str(cmd),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->errors)
+);
+
+/**
+ * block_rq_abort - abort block operation request
+ * @q: queue containing the block operation request
+ * @rq: block IO operation request
+ *
+ * Called immediately after pending block IO operation request @rq in
+ * queue @q is aborted. The fields in the operation request @rq
+ * can be examined to determine which device and sectors the pending
+ * operation would access.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_abort,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+);
+
+/**
+ * block_rq_requeue - place block IO request back on a queue
+ * @q: queue holding operation
+ * @rq: block IO operation request
+ *
+ * The block operation request @rq is being placed back into queue
+ * @q.  For some reason the request was not completed and needs to be
+ * put back in the queue.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+);
+
+/**
+ * block_rq_complete - block IO operation completed by device driver
+ * @q: queue containing the block operation request
+ * @rq: block operations request
+ *
+ * The block_rq_complete tracepoint event indicates that some portion
+ * of operation request has been completed by the device driver.  If
+ * the @rq->bio is %NULL, then there is absolutely no additional work to
+ * do for the request. If @rq->bio is non-NULL then there is
+ * additional work required to complete the request.
+ */
+DEFINE_EVENT(block_rq_with_error, block_rq_complete,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+);
+
+DECLARE_EVENT_CLASS(block_rq,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq),
+
+	TP_STRUCT__entry(
+		__field(  dev_t,	dev			)
+		__field(  sector_t,	sector			)
+		__field(  unsigned int,	nr_sector		)
+		__field(  unsigned int,	bytes			)
+		__array(  char,		rwbs,	6		)
+		__array(  char,         comm,   TASK_COMM_LEN   )
+		__dynamic_array( char,	cmd,	blk_cmd_buf_len(rq)	)
+	),
+
+	TP_fast_assign(
+		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->sector    = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_pos(rq);
+		__entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					0 : blk_rq_sectors(rq);
+		__entry->bytes     = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
+					blk_rq_bytes(rq) : 0;
+
+		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+		blk_dump_cmd(__get_str(cmd), rq);
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("%d,%d %s %u (%s) %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __entry->rwbs, __entry->bytes, __get_str(cmd),
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+);
+
+/**
+ * block_rq_insert - insert block operation request into queue
+ * @q: target queue
+ * @rq: block IO operation request
+ *
+ * Called immediately before block operation request @rq is inserted
+ * into queue @q.  The fields in the operation request @rq struct can
+ * be examined to determine which device and sectors the pending
+ * operation would access.
+ */
+DEFINE_EVENT(block_rq, block_rq_insert,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+);
+
+/**
+ * block_rq_issue - issue pending block IO request operation to device driver
+ * @q: queue holding operation
+ * @rq: block IO operation operation request
+ *
+ * Called when block operation request @rq from queue @q is sent to a
+ * device driver for processing.
+ */
+DEFINE_EVENT(block_rq, block_rq_issue,
+
+	TP_PROTO(struct request_queue *q, struct request *rq),
+
+	TP_ARGS(q, rq)
+);
+
+/**
+ * block_bio_bounce - used bounce buffer when processing block operation
+ * @q: queue holding the block operation
+ * @bio: block operation
+ *
+ * A bounce buffer was used to handle the block operation @bio in @q.
+ * This occurs when hardware limitations prevent a direct transfer of
+ * data between the @bio data memory area and the IO device.  Use of a
+ * bounce buffer requires extra copying of data and decreases
+ * performance.
+ */
+TRACE_EVENT(block_bio_bounce,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__array( char,		rwbs,	6		)
+		__array( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= bio->bi_bdev ?
+					  bio->bi_bdev->bd_dev : 0;
+		__entry->sector		= bio->bi_sector;
+		__entry->nr_sector	= bio->bi_size >> 9;
+		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+);
+
+/**
+ * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
+ * @bio: block operation completed
+ * @error: io error value
+ *
+ * This tracepoint indicates there is no further work to do on this
+ * block IO operation @bio.
+ */
+TRACE_EVENT(block_bio_complete,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int error),
+
+	TP_ARGS(q, bio, error),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned,	nr_sector	)
+		__field( int,		error		)
+		__array( char,		rwbs,	6	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= bio->bi_bdev->bd_dev;
+		__entry->sector		= bio->bi_sector;
+		__entry->nr_sector	= bio->bi_size >> 9;
+		__entry->error		= error;
+		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%d]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->error)
+);
+
+DECLARE_EVENT_CLASS(block_bio,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__array( char,		rwbs,	6		)
+		__array( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= bio->bi_bdev->bd_dev;
+		__entry->sector		= bio->bi_sector;
+		__entry->nr_sector	= bio->bi_size >> 9;
+		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+);
+
+/**
+ * block_bio_backmerge - merging block operation to the end of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block request @bio to the end of an existing block request
+ * in queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_backmerge,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+);
+
+/**
+ * block_bio_frontmerge - merging block operation to the beginning of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block IO operation @bio to the beginning of an existing block
+ * operation in queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_frontmerge,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+);
+
+/**
+ * block_bio_queue - putting new block IO operation in queue
+ * @q: queue holding operation
+ * @bio: new block operation
+ *
+ * About to place the block IO operation @bio into queue @q.
+ */
+DEFINE_EVENT(block_bio, block_bio_queue,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+
+	TP_ARGS(q, bio)
+);
+
+DECLARE_EVENT_CLASS(block_get_rq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev			)
+		__field( sector_t,	sector			)
+		__field( unsigned int,	nr_sector		)
+		__array( char,		rwbs,	6		)
+		__array( char,		comm,	TASK_COMM_LEN	)
+        ),
+
+	TP_fast_assign(
+		__entry->dev		= bio ? bio->bi_bdev->bd_dev : 0;
+		__entry->sector		= bio ? bio->bi_sector : 0;
+		__entry->nr_sector	= bio ? bio->bi_size >> 9 : 0;
+		blk_fill_rwbs(__entry->rwbs,
+			      bio ? bio->bi_rw : 0, __entry->nr_sector);
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+        ),
+
+	TP_printk("%d,%d %s %llu + %u [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector, __entry->comm)
+);
+
+/**
+ * block_getrq - get a free request entry in queue for block IO operations
+ * @q: queue for operations
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * A request struct for queue @q has been allocated to handle the
+ * block IO operation @bio.
+ */
+DEFINE_EVENT(block_get_rq, block_getrq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw)
+);
+
+/**
+ * block_sleeprq - waiting to get a free request entry in queue for block IO operation
+ * @q: queue for operation
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * In the case where a request struct cannot be provided for queue @q
+ * the process needs to wait for an request struct to become
+ * available.  This tracepoint event is generated each time the
+ * process goes to sleep waiting for request struct become available.
+ */
+DEFINE_EVENT(block_get_rq, block_sleeprq,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+
+	TP_ARGS(q, bio, rw)
+);
+
+/**
+ * block_plug - keep operations requests in request queue
+ * @q: request queue to plug
+ *
+ * Plug the request queue @q.  Do not allow block operation requests
+ * to be sent to the device driver. Instead, accumulate requests in
+ * the queue to improve throughput performance of the block device.
+ */
+TRACE_EVENT(block_plug,
+
+	TP_PROTO(struct request_queue *q),
+
+	TP_ARGS(q),
+
+	TP_STRUCT__entry(
+		__array( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("[%s]", __entry->comm)
+);
+
+DECLARE_EVENT_CLASS(block_unplug,
+
+	TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
+
+	TP_ARGS(q, depth, explicit),
+
+	TP_STRUCT__entry(
+		__field( int,		nr_rq			)
+		__array( char,		comm,	TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		__entry->nr_rq = depth;
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
+);
+
+/**
+ * block_unplug - release of operations requests in request queue
+ * @q: request queue to unplug
+ * @depth: number of requests just added to the queue
+ * @explicit: whether this was an explicit unplug, or one from schedule()
+ *
+ * Unplug request queue @q because device driver is scheduled to work
+ * on elements in the request queue.
+ */
+DEFINE_EVENT(block_unplug, block_unplug,
+
+	TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit),
+
+	TP_ARGS(q, depth, explicit)
+);
+
+/**
+ * block_split - split a single bio struct into two bio structs
+ * @q: queue containing the bio
+ * @bio: block operation being split
+ * @new_sector: The starting sector for the new bio
+ *
+ * The bio request @bio in request queue @q needs to be split into two
+ * bio requests. The newly created @bio request starts at
+ * @new_sector. This split may be required due to hardware limitation
+ * such as operation crossing device boundaries in a RAID system.
+ */
+TRACE_EVENT(block_split,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio,
+		 unsigned int new_sector),
+
+	TP_ARGS(q, bio, new_sector),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev				)
+		__field( sector_t,	sector				)
+		__field( sector_t,	new_sector			)
+		__array( char,		rwbs,		6		)
+		__array( char,		comm,		TASK_COMM_LEN	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= bio->bi_bdev->bd_dev;
+		__entry->sector		= bio->bi_sector;
+		__entry->new_sector	= new_sector;
+		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+	),
+
+	TP_printk("%d,%d %s %llu / %llu [%s]",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  (unsigned long long)__entry->new_sector,
+		  __entry->comm)
+);
+
+/**
+ * block_bio_remap - map request for a logical device to the raw device
+ * @q: queue holding the operation
+ * @bio: revised operation
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * An operation for a logical device has been mapped to the
+ * raw block device.
+ */
+TRACE_EVENT(block_bio_remap,
+
+	TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
+		 sector_t from),
+
+	TP_ARGS(q, bio, dev, from),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned int,	nr_sector	)
+		__field( dev_t,		old_dev		)
+		__field( sector_t,	old_sector	)
+		__array( char,		rwbs,	6	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= bio->bi_bdev->bd_dev;
+		__entry->sector		= bio->bi_sector;
+		__entry->nr_sector	= bio->bi_size >> 9;
+		__entry->old_dev	= dev;
+		__entry->old_sector	= from;
+		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
+	),
+
+	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector,
+		  MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+		  (unsigned long long)__entry->old_sector)
+);
+
+/**
+ * block_rq_remap - map request for a block operation request
+ * @q: queue holding the operation
+ * @rq: block IO operation request
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * The block operation request @rq in @q has been remapped.  The block
+ * operation request @rq holds the current information and @from hold
+ * the original sector.
+ */
+TRACE_EVENT(block_rq_remap,
+
+	TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
+		 sector_t from),
+
+	TP_ARGS(q, rq, dev, from),
+
+	TP_STRUCT__entry(
+		__field( dev_t,		dev		)
+		__field( sector_t,	sector		)
+		__field( unsigned int,	nr_sector	)
+		__field( dev_t,		old_dev		)
+		__field( sector_t,	old_sector	)
+		__array( char,		rwbs,	6	)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= disk_devt(rq->rq_disk);
+		__entry->sector		= blk_rq_pos(rq);
+		__entry->nr_sector	= blk_rq_sectors(rq);
+		__entry->old_dev	= dev;
+		__entry->old_sector	= from;
+		blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+	),
+
+	TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
+		  (unsigned long long)__entry->sector,
+		  __entry->nr_sector,
+		  MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
+		  (unsigned long long)__entry->old_sector)
+);
+
+#endif /* _TRACE_BLOCK_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
diff --git a/drivers/staging/lttng/instrumentation/events/mainline/irq.h b/drivers/staging/lttng/instrumentation/events/mainline/irq.h
new file mode 100644
index 0000000..1c09820
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/mainline/irq.h
@@ -0,0 +1,150 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
+#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IRQ_H
+
+#include <linux/tracepoint.h>
+
+struct irqaction;
+struct softirq_action;
+
+#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
+#define show_softirq_name(val)				\
+	__print_symbolic(val,				\
+			 softirq_name(HI),		\
+			 softirq_name(TIMER),		\
+			 softirq_name(NET_TX),		\
+			 softirq_name(NET_RX),		\
+			 softirq_name(BLOCK),		\
+			 softirq_name(BLOCK_IOPOLL),	\
+			 softirq_name(TASKLET),		\
+			 softirq_name(SCHED),		\
+			 softirq_name(HRTIMER),		\
+			 softirq_name(RCU))
+
+/**
+ * irq_handler_entry - called immediately before the irq action handler
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ *
+ * The struct irqaction pointed to by @action contains various
+ * information about the handler, including the device name,
+ * @action->name, and the device id, @action->dev_id. When used in
+ * conjunction with the irq_handler_exit tracepoint, we can figure
+ * out irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_entry,
+
+	TP_PROTO(int irq, struct irqaction *action),
+
+	TP_ARGS(irq, action),
+
+	TP_STRUCT__entry(
+		__field(	int,	irq		)
+		__string(	name,	action->name	)
+	),
+
+	TP_fast_assign(
+		__entry->irq = irq;
+		__assign_str(name, action->name);
+	),
+
+	TP_printk("irq=%d name=%s", __entry->irq, __get_str(name))
+);
+
+/**
+ * irq_handler_exit - called immediately after the irq action handler returns
+ * @irq: irq number
+ * @action: pointer to struct irqaction
+ * @ret: return value
+ *
+ * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding
+ * @action->handler scuccessully handled this irq. Otherwise, the irq might be
+ * a shared irq line, or the irq was not handled successfully. Can be used in
+ * conjunction with the irq_handler_entry to understand irq handler latencies.
+ */
+TRACE_EVENT(irq_handler_exit,
+
+	TP_PROTO(int irq, struct irqaction *action, int ret),
+
+	TP_ARGS(irq, action, ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	irq	)
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		__entry->irq	= irq;
+		__entry->ret	= ret;
+	),
+
+	TP_printk("irq=%d ret=%s",
+		  __entry->irq, __entry->ret ? "handled" : "unhandled")
+);
+
+DECLARE_EVENT_CLASS(softirq,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	vec	)
+	),
+
+	TP_fast_assign(
+		__entry->vec = vec_nr;
+	),
+
+	TP_printk("vec=%u [action=%s]", __entry->vec,
+		  show_softirq_name(__entry->vec))
+);
+
+/**
+ * softirq_entry - called immediately before the softirq handler
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_exit tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_entry,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+);
+
+/**
+ * softirq_exit - called immediately after the softirq handler returns
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_exit,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+);
+
+/**
+ * softirq_raise - called immediately when a softirq is raised
+ * @vec_nr:  softirq vector number
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq raise to run latency.
+ */
+DEFINE_EVENT(softirq, softirq_raise,
+
+	TP_PROTO(unsigned int vec_nr),
+
+	TP_ARGS(vec_nr)
+);
+
+#endif /*  _TRACE_IRQ_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/staging/lttng/instrumentation/events/mainline/kvm.h b/drivers/staging/lttng/instrumentation/events/mainline/kvm.h
new file mode 100644
index 0000000..46e3cd8
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/mainline/kvm.h
@@ -0,0 +1,312 @@
+#if !defined(_TRACE_KVM_MAIN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_MAIN_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x }
+
+#define kvm_trace_exit_reason						\
+	ERSN(UNKNOWN), ERSN(EXCEPTION), ERSN(IO), ERSN(HYPERCALL),	\
+	ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN),	\
+	ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR),	\
+	ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\
+	ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI)
+
+TRACE_EVENT(kvm_userspace_exit,
+	    TP_PROTO(__u32 reason, int errno),
+	    TP_ARGS(reason, errno),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		reason		)
+		__field(	int,		errno		)
+	),
+
+	TP_fast_assign(
+		__entry->reason		= reason;
+		__entry->errno		= errno;
+	),
+
+	TP_printk("reason %s (%d)",
+		  __entry->errno < 0 ?
+		  (__entry->errno == -EINTR ? "restart" : "error") :
+		  __print_symbolic(__entry->reason, kvm_trace_exit_reason),
+		  __entry->errno < 0 ? -__entry->errno : __entry->reason)
+);
+
+#if defined(__KVM_HAVE_IOAPIC)
+TRACE_EVENT(kvm_set_irq,
+	TP_PROTO(unsigned int gsi, int level, int irq_source_id),
+	TP_ARGS(gsi, level, irq_source_id),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	gsi		)
+		__field(	int,		level		)
+		__field(	int,		irq_source_id	)
+	),
+
+	TP_fast_assign(
+		__entry->gsi		= gsi;
+		__entry->level		= level;
+		__entry->irq_source_id	= irq_source_id;
+	),
+
+	TP_printk("gsi %u level %d source %d",
+		  __entry->gsi, __entry->level, __entry->irq_source_id)
+);
+
+#define kvm_deliver_mode		\
+	{0x0, "Fixed"},			\
+	{0x1, "LowPrio"},		\
+	{0x2, "SMI"},			\
+	{0x3, "Res3"},			\
+	{0x4, "NMI"},			\
+	{0x5, "INIT"},			\
+	{0x6, "SIPI"},			\
+	{0x7, "ExtINT"}
+
+TRACE_EVENT(kvm_ioapic_set_irq,
+	    TP_PROTO(__u64 e, int pin, bool coalesced),
+	    TP_ARGS(e, pin, coalesced),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		e		)
+		__field(	int,		pin		)
+		__field(	bool,		coalesced	)
+	),
+
+	TP_fast_assign(
+		__entry->e		= e;
+		__entry->pin		= pin;
+		__entry->coalesced	= coalesced;
+	),
+
+	TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s",
+		  __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e,
+		  __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->e & (1<<11)) ? "logical" : "physical",
+		  (__entry->e & (1<<15)) ? "level" : "edge",
+		  (__entry->e & (1<<16)) ? "|masked" : "",
+		  __entry->coalesced ? " (coalesced)" : "")
+);
+
+TRACE_EVENT(kvm_msi_set_irq,
+	    TP_PROTO(__u64 address, __u64 data),
+	    TP_ARGS(address, data),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		address		)
+		__field(	__u64,		data		)
+	),
+
+	TP_fast_assign(
+		__entry->address	= address;
+		__entry->data		= data;
+	),
+
+	TP_printk("dst %u vec %x (%s|%s|%s%s)",
+		  (u8)(__entry->address >> 12), (u8)__entry->data,
+		  __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->address & (1<<2)) ? "logical" : "physical",
+		  (__entry->data & (1<<15)) ? "level" : "edge",
+		  (__entry->address & (1<<3)) ? "|rh" : "")
+);
+
+#define kvm_irqchips						\
+	{KVM_IRQCHIP_PIC_MASTER,	"PIC master"},		\
+	{KVM_IRQCHIP_PIC_SLAVE,		"PIC slave"},		\
+	{KVM_IRQCHIP_IOAPIC,		"IOAPIC"}
+
+TRACE_EVENT(kvm_ack_irq,
+	TP_PROTO(unsigned int irqchip, unsigned int pin),
+	TP_ARGS(irqchip, pin),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	irqchip		)
+		__field(	unsigned int,	pin		)
+	),
+
+	TP_fast_assign(
+		__entry->irqchip	= irqchip;
+		__entry->pin		= pin;
+	),
+
+	TP_printk("irqchip %s pin %u",
+		  __print_symbolic(__entry->irqchip, kvm_irqchips),
+		 __entry->pin)
+);
+
+
+
+#endif /* defined(__KVM_HAVE_IOAPIC) */
+
+#define KVM_TRACE_MMIO_READ_UNSATISFIED 0
+#define KVM_TRACE_MMIO_READ 1
+#define KVM_TRACE_MMIO_WRITE 2
+
+#define kvm_trace_symbol_mmio \
+	{ KVM_TRACE_MMIO_READ_UNSATISFIED, "unsatisfied-read" }, \
+	{ KVM_TRACE_MMIO_READ, "read" }, \
+	{ KVM_TRACE_MMIO_WRITE, "write" }
+
+TRACE_EVENT(kvm_mmio,
+	TP_PROTO(int type, int len, u64 gpa, u64 val),
+	TP_ARGS(type, len, gpa, val),
+
+	TP_STRUCT__entry(
+		__field(	u32,	type		)
+		__field(	u32,	len		)
+		__field(	u64,	gpa		)
+		__field(	u64,	val		)
+	),
+
+	TP_fast_assign(
+		__entry->type		= type;
+		__entry->len		= len;
+		__entry->gpa		= gpa;
+		__entry->val		= val;
+	),
+
+	TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx",
+		  __print_symbolic(__entry->type, kvm_trace_symbol_mmio),
+		  __entry->len, __entry->gpa, __entry->val)
+);
+
+#define kvm_fpu_load_symbol	\
+	{0, "unload"},		\
+	{1, "load"}
+
+TRACE_EVENT(kvm_fpu,
+	TP_PROTO(int load),
+	TP_ARGS(load),
+
+	TP_STRUCT__entry(
+		__field(	u32,	        load		)
+	),
+
+	TP_fast_assign(
+		__entry->load		= load;
+	),
+
+	TP_printk("%s", __print_symbolic(__entry->load, kvm_fpu_load_symbol))
+);
+
+TRACE_EVENT(kvm_age_page,
+	TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref),
+	TP_ARGS(hva, slot, ref),
+
+	TP_STRUCT__entry(
+		__field(	u64,	hva		)
+		__field(	u64,	gfn		)
+		__field(	u8,	referenced	)
+	),
+
+	TP_fast_assign(
+		__entry->hva		= hva;
+		__entry->gfn		=
+		  slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT);
+		__entry->referenced	= ref;
+	),
+
+	TP_printk("hva %llx gfn %llx %s",
+		  __entry->hva, __entry->gfn,
+		  __entry->referenced ? "YOUNG" : "OLD")
+);
+
+#ifdef CONFIG_KVM_ASYNC_PF
+DECLARE_EVENT_CLASS(kvm_async_get_page_class,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn),
+
+	TP_STRUCT__entry(
+		__field(__u64, gva)
+		__field(u64, gfn)
+	),
+
+	TP_fast_assign(
+		__entry->gva = gva;
+		__entry->gfn = gfn;
+	),
+
+	TP_printk("gva = %#llx, gfn = %#llx", __entry->gva, __entry->gfn)
+);
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_try_async_get_page,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn)
+);
+
+DEFINE_EVENT(kvm_async_get_page_class, kvm_async_pf_doublefault,
+
+	TP_PROTO(u64 gva, u64 gfn),
+
+	TP_ARGS(gva, gfn)
+);
+
+DECLARE_EVENT_CLASS(kvm_async_pf_nopresent_ready,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva),
+
+	TP_STRUCT__entry(
+		__field(__u64, token)
+		__field(__u64, gva)
+	),
+
+	TP_fast_assign(
+		__entry->token = token;
+		__entry->gva = gva;
+	),
+
+	TP_printk("token %#llx gva %#llx", __entry->token, __entry->gva)
+
+);
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_not_present,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva)
+);
+
+DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_ready,
+
+	TP_PROTO(u64 token, u64 gva),
+
+	TP_ARGS(token, gva)
+);
+
+TRACE_EVENT(
+	kvm_async_pf_completed,
+	TP_PROTO(unsigned long address, struct page *page, u64 gva),
+	TP_ARGS(address, page, gva),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, address)
+		__field(pfn_t, pfn)
+		__field(u64, gva)
+		),
+
+	TP_fast_assign(
+		__entry->address = address;
+		__entry->pfn = page ? page_to_pfn(page) : 0;
+		__entry->gva = gva;
+		),
+
+	TP_printk("gva %#llx address %#lx pfn %#llx",  __entry->gva,
+		  __entry->address, __entry->pfn)
+);
+
+#endif
+
+#endif /* _TRACE_KVM_MAIN_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/staging/lttng/instrumentation/events/mainline/sched.h b/drivers/staging/lttng/instrumentation/events/mainline/sched.h
new file mode 100644
index 0000000..f633478
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/mainline/sched.h
@@ -0,0 +1,397 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sched
+
+#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SCHED_H
+
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Tracepoint for calling kthread_stop, performed to end a kthread:
+ */
+TRACE_EVENT(sched_kthread_stop,
+
+	TP_PROTO(struct task_struct *t),
+
+	TP_ARGS(t),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
+		__entry->pid	= t->pid;
+	),
+
+	TP_printk("comm=%s pid=%d", __entry->comm, __entry->pid)
+);
+
+/*
+ * Tracepoint for the return value of the kthread stopping:
+ */
+TRACE_EVENT(sched_kthread_stop_ret,
+
+	TP_PROTO(int ret),
+
+	TP_ARGS(ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		__entry->ret	= ret;
+	),
+
+	TP_printk("ret=%d", __entry->ret)
+);
+
+/*
+ * Tracepoint for waking up a task:
+ */
+DECLARE_EVENT_CLASS(sched_wakeup_template,
+
+	TP_PROTO(struct task_struct *p, int success),
+
+	TP_ARGS(p, success),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	success			)
+		__field(	int,	target_cpu		)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->success	= success;
+		__entry->target_cpu	= task_cpu(p);
+	),
+
+	TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d",
+		  __entry->comm, __entry->pid, __entry->prio,
+		  __entry->success, __entry->target_cpu)
+);
+
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
+	     TP_PROTO(struct task_struct *p, int success),
+	     TP_ARGS(p, success));
+
+/*
+ * Tracepoint for waking up a new task:
+ */
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
+	     TP_PROTO(struct task_struct *p, int success),
+	     TP_ARGS(p, success));
+
+#ifdef CREATE_TRACE_POINTS
+static inline long __trace_sched_switch_state(struct task_struct *p)
+{
+	long state = p->state;
+
+#ifdef CONFIG_PREEMPT
+	/*
+	 * For all intents and purposes a preempted task is a running task.
+	 */
+	if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE)
+		state = TASK_RUNNING;
+#endif
+
+	return state;
+}
+#endif
+
+/*
+ * Tracepoint for task switches, performed by the scheduler:
+ */
+TRACE_EVENT(sched_switch,
+
+	TP_PROTO(struct task_struct *prev,
+		 struct task_struct *next),
+
+	TP_ARGS(prev, next),
+
+	TP_STRUCT__entry(
+		__array(	char,	prev_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	prev_pid			)
+		__field(	int,	prev_prio			)
+		__field(	long,	prev_state			)
+		__array(	char,	next_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	next_pid			)
+		__field(	int,	next_prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+		__entry->prev_pid	= prev->pid;
+		__entry->prev_prio	= prev->prio;
+		__entry->prev_state	= __trace_sched_switch_state(prev);
+		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+		__entry->next_pid	= next->pid;
+		__entry->next_prio	= next->prio;
+	),
+
+	TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d next_prio=%d",
+		__entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+		__entry->prev_state ?
+		  __print_flags(__entry->prev_state, "|",
+				{ 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" },
+				{ 16, "Z" }, { 32, "X" }, { 64, "x" },
+				{ 128, "W" }) : "R",
+		__entry->next_comm, __entry->next_pid, __entry->next_prio)
+);
+
+/*
+ * Tracepoint for a task being migrated:
+ */
+TRACE_EVENT(sched_migrate_task,
+
+	TP_PROTO(struct task_struct *p, int dest_cpu),
+
+	TP_ARGS(p, dest_cpu),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	orig_cpu		)
+		__field(	int,	dest_cpu		)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->orig_cpu	= task_cpu(p);
+		__entry->dest_cpu	= dest_cpu;
+	),
+
+	TP_printk("comm=%s pid=%d prio=%d orig_cpu=%d dest_cpu=%d",
+		  __entry->comm, __entry->pid, __entry->prio,
+		  __entry->orig_cpu, __entry->dest_cpu)
+);
+
+DECLARE_EVENT_CLASS(sched_process_template,
+
+	TP_PROTO(struct task_struct *p),
+
+	TP_ARGS(p),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+	),
+
+	TP_printk("comm=%s pid=%d prio=%d",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for freeing a task:
+ */
+DEFINE_EVENT(sched_process_template, sched_process_free,
+	     TP_PROTO(struct task_struct *p),
+	     TP_ARGS(p));
+	     
+
+/*
+ * Tracepoint for a task exiting:
+ */
+DEFINE_EVENT(sched_process_template, sched_process_exit,
+	     TP_PROTO(struct task_struct *p),
+	     TP_ARGS(p));
+
+/*
+ * Tracepoint for waiting on task to unschedule:
+ */
+DEFINE_EVENT(sched_process_template, sched_wait_task,
+	TP_PROTO(struct task_struct *p),
+	TP_ARGS(p));
+
+/*
+ * Tracepoint for a waiting task:
+ */
+TRACE_EVENT(sched_process_wait,
+
+	TP_PROTO(struct pid *pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		__entry->pid		= pid_nr(pid);
+		__entry->prio		= current->prio;
+	),
+
+	TP_printk("comm=%s pid=%d prio=%d",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for do_fork:
+ */
+TRACE_EVENT(sched_process_fork,
+
+	TP_PROTO(struct task_struct *parent, struct task_struct *child),
+
+	TP_ARGS(parent, child),
+
+	TP_STRUCT__entry(
+		__array(	char,	parent_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	parent_pid			)
+		__array(	char,	child_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	child_pid			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN);
+		__entry->parent_pid	= parent->pid;
+		memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN);
+		__entry->child_pid	= child->pid;
+	),
+
+	TP_printk("comm=%s pid=%d child_comm=%s child_pid=%d",
+		__entry->parent_comm, __entry->parent_pid,
+		__entry->child_comm, __entry->child_pid)
+);
+
+/*
+ * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE
+ *     adding sched_stat support to SCHED_FIFO/RR would be welcome.
+ */
+DECLARE_EVENT_CLASS(sched_stat_template,
+
+	TP_PROTO(struct task_struct *tsk, u64 delay),
+
+	TP_ARGS(tsk, delay),
+
+	TP_STRUCT__entry(
+		__array( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	pid			)
+		__field( u64,	delay			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+		__entry->pid	= tsk->pid;
+		__entry->delay	= delay;
+	)
+	TP_perf_assign(
+		__perf_count(delay);
+	),
+
+	TP_printk("comm=%s pid=%d delay=%Lu [ns]",
+			__entry->comm, __entry->pid,
+			(unsigned long long)__entry->delay)
+);
+
+
+/*
+ * Tracepoint for accounting wait time (time the task is runnable
+ * but not actually running due to scheduler contention).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_wait,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay));
+
+/*
+ * Tracepoint for accounting sleep time (time the task is not runnable,
+ * including iowait, see below).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_sleep,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay));
+
+/*
+ * Tracepoint for accounting iowait time (time the task is not runnable
+ * due to waiting on IO to complete).
+ */
+DEFINE_EVENT(sched_stat_template, sched_stat_iowait,
+	     TP_PROTO(struct task_struct *tsk, u64 delay),
+	     TP_ARGS(tsk, delay));
+
+/*
+ * Tracepoint for accounting runtime (time the task is executing
+ * on a CPU).
+ */
+TRACE_EVENT(sched_stat_runtime,
+
+	TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime),
+
+	TP_ARGS(tsk, runtime, vruntime),
+
+	TP_STRUCT__entry(
+		__array( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	pid			)
+		__field( u64,	runtime			)
+		__field( u64,	vruntime			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+		__entry->pid		= tsk->pid;
+		__entry->runtime	= runtime;
+		__entry->vruntime	= vruntime;
+	)
+	TP_perf_assign(
+		__perf_count(runtime);
+	),
+
+	TP_printk("comm=%s pid=%d runtime=%Lu [ns] vruntime=%Lu [ns]",
+			__entry->comm, __entry->pid,
+			(unsigned long long)__entry->runtime,
+			(unsigned long long)__entry->vruntime)
+);
+
+/*
+ * Tracepoint for showing priority inheritance modifying a tasks
+ * priority.
+ */
+TRACE_EVENT(sched_pi_setprio,
+
+	TP_PROTO(struct task_struct *tsk, int newprio),
+
+	TP_ARGS(tsk, newprio),
+
+	TP_STRUCT__entry(
+		__array( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	pid			)
+		__field( int,	oldprio			)
+		__field( int,	newprio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+		__entry->pid		= tsk->pid;
+		__entry->oldprio	= tsk->prio;
+		__entry->newprio	= newprio;
+	),
+
+	TP_printk("comm=%s pid=%d oldprio=%d newprio=%d",
+			__entry->comm, __entry->pid,
+			__entry->oldprio, __entry->newprio)
+);
+
+#endif /* _TRACE_SCHED_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h b/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h
new file mode 100644
index 0000000..5a4c04a
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h
@@ -0,0 +1,75 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM raw_syscalls
+#define TRACE_INCLUDE_FILE syscalls
+
+#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENTS_SYSCALLS_H
+
+#include <linux/tracepoint.h>
+
+#include <asm/ptrace.h>
+#include <asm/syscall.h>
+
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+
+extern void syscall_regfunc(void);
+extern void syscall_unregfunc(void);
+
+TRACE_EVENT_FN(sys_enter,
+
+	TP_PROTO(struct pt_regs *regs, long id),
+
+	TP_ARGS(regs, id),
+
+	TP_STRUCT__entry(
+		__field(	long,		id		)
+		__array(	unsigned long,	args,	6	)
+	),
+
+	TP_fast_assign(
+		__entry->id	= id;
+		syscall_get_arguments(current, regs, 0, 6, __entry->args);
+	),
+
+	TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)",
+		  __entry->id,
+		  __entry->args[0], __entry->args[1], __entry->args[2],
+		  __entry->args[3], __entry->args[4], __entry->args[5]),
+
+	syscall_regfunc, syscall_unregfunc
+);
+
+TRACE_EVENT_FLAGS(sys_enter, TRACE_EVENT_FL_CAP_ANY)
+
+TRACE_EVENT_FN(sys_exit,
+
+	TP_PROTO(struct pt_regs *regs, long ret),
+
+	TP_ARGS(regs, ret),
+
+	TP_STRUCT__entry(
+		__field(	long,	id	)
+		__field(	long,	ret	)
+	),
+
+	TP_fast_assign(
+		__entry->id	= syscall_get_nr(current, regs);
+		__entry->ret	= ret;
+	),
+
+	TP_printk("NR %ld = %ld",
+		  __entry->id, __entry->ret),
+
+	syscall_regfunc, syscall_unregfunc
+);
+
+TRACE_EVENT_FLAGS(sys_exit, TRACE_EVENT_FL_CAP_ANY)
+
+#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */
+
+#endif /* _TRACE_EVENTS_SYSCALLS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 08/19] lttng: syscall instrumentation
  2011-11-26 15:03             ` [lttng-dev] [PATCH 07/19] lttng instrumentation: tracepoint events Mathieu Desnoyers
@ 2011-11-26 15:03               ` Mathieu Desnoyers
  2011-11-26 15:03                 ` [lttng-dev] [PATCH 09/19] lttng: lib ring buffer clients Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


x86-32 and x86-64 system call instrumentation, along with the
lttng-syscalls-generate-headers.sh script that generates the headers
from the system call list. See README for details.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 .../syscalls/3.0.4/x86-64-syscalls-3.0.4           |  263 +++
 .../syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6   |  291 +++
 .../staging/lttng/instrumentation/syscalls/README  |   18 +
 .../syscalls/headers/compat_syscalls_integers.h    |    3 +
 .../syscalls/headers/compat_syscalls_pointers.h    |    3 +
 .../syscalls/headers/syscalls_integers.h           |    9 +
 .../syscalls/headers/syscalls_integers_override.h  |   13 +
 .../syscalls/headers/syscalls_pointers.h           |    9 +
 .../syscalls/headers/syscalls_unknown.h            |   55 +
 .../headers/x86-32-syscalls-3.1.0-rc6_integers.h   | 1161 ++++++++++
 .../x86-32-syscalls-3.1.0-rc6_integers_override.h  |   38 +
 .../headers/x86-32-syscalls-3.1.0-rc6_pointers.h   | 2230 ++++++++++++++++++++
 .../x86-32-syscalls-3.1.0-rc6_pointers_override.h  |   17 +
 .../headers/x86-64-syscalls-3.0.4_integers.h       | 1011 +++++++++
 .../headers/x86-64-syscalls-3.0.4_pointers.h       | 2074 ++++++++++++++++++
 .../x86-64-syscalls-3.0.4_pointers_override.h      |    5 +
 .../syscalls/lttng-syscalls-extractor/Makefile     |    1 +
 .../lttng-syscalls-extractor.c                     |   85 +
 .../syscalls/lttng-syscalls-generate-headers.sh    |  272 +++
 19 files changed, 7558 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/README
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c
 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh

diff --git a/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 b/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4
new file mode 100644
index 0000000..b229472
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4
@@ -0,0 +1,263 @@
+syscall sys_read nr 0 nbargs 3 types: (unsigned int, char *, size_t) args: (fd, buf, count)
+syscall sys_write nr 1 nbargs 3 types: (unsigned int, const char *, size_t) args: (fd, buf, count)
+syscall sys_open nr 2 nbargs 3 types: (const char *, int, int) args: (filename, flags, mode)
+syscall sys_close nr 3 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_newstat nr 4 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf)
+syscall sys_newfstat nr 5 nbargs 2 types: (unsigned int, struct stat *) args: (fd, statbuf)
+syscall sys_newlstat nr 6 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf)
+syscall sys_poll nr 7 nbargs 3 types: (struct pollfd *, unsigned int, long) args: (ufds, nfds, timeout_msecs)
+syscall sys_lseek nr 8 nbargs 3 types: (unsigned int, off_t, unsigned int) args: (fd, offset, origin)
+syscall sys_mmap nr 9 nbargs 6 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, len, prot, flags, fd, off)
+syscall sys_mprotect nr 10 nbargs 3 types: (unsigned long, size_t, unsigned long) args: (start, len, prot)
+syscall sys_munmap nr 11 nbargs 2 types: (unsigned long, size_t) args: (addr, len)
+syscall sys_brk nr 12 nbargs 1 types: (unsigned long) args: (brk)
+syscall sys_rt_sigaction nr 13 nbargs 4 types: (int, const struct sigaction *, struct sigaction *, size_t) args: (sig, act, oact, sigsetsize)
+syscall sys_rt_sigprocmask nr 14 nbargs 4 types: (int, sigset_t *, sigset_t *, size_t) args: (how, nset, oset, sigsetsize)
+syscall sys_ioctl nr 16 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg)
+syscall sys_readv nr 19 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen)
+syscall sys_writev nr 20 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen)
+syscall sys_access nr 21 nbargs 2 types: (const char *, int) args: (filename, mode)
+syscall sys_pipe nr 22 nbargs 1 types: (int *) args: (fildes)
+syscall sys_select nr 23 nbargs 5 types: (int, fd_set *, fd_set *, fd_set *, struct timeval *) args: (n, inp, outp, exp, tvp)
+syscall sys_sched_yield nr 24 nbargs 0 types: () args: ()
+syscall sys_mremap nr 25 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, old_len, new_len, flags, new_addr)
+syscall sys_msync nr 26 nbargs 3 types: (unsigned long, size_t, int) args: (start, len, flags)
+syscall sys_mincore nr 27 nbargs 3 types: (unsigned long, size_t, unsigned char *) args: (start, len, vec)
+syscall sys_madvise nr 28 nbargs 3 types: (unsigned long, size_t, int) args: (start, len_in, behavior)
+syscall sys_shmget nr 29 nbargs 3 types: (key_t, size_t, int) args: (key, size, shmflg)
+syscall sys_shmat nr 30 nbargs 3 types: (int, char *, int) args: (shmid, shmaddr, shmflg)
+syscall sys_shmctl nr 31 nbargs 3 types: (int, int, struct shmid_ds *) args: (shmid, cmd, buf)
+syscall sys_dup nr 32 nbargs 1 types: (unsigned int) args: (fildes)
+syscall sys_dup2 nr 33 nbargs 2 types: (unsigned int, unsigned int) args: (oldfd, newfd)
+syscall sys_pause nr 34 nbargs 0 types: () args: ()
+syscall sys_nanosleep nr 35 nbargs 2 types: (struct timespec *, struct timespec *) args: (rqtp, rmtp)
+syscall sys_getitimer nr 36 nbargs 2 types: (int, struct itimerval *) args: (which, value)
+syscall sys_alarm nr 37 nbargs 1 types: (unsigned int) args: (seconds)
+syscall sys_setitimer nr 38 nbargs 3 types: (int, struct itimerval *, struct itimerval *) args: (which, value, ovalue)
+syscall sys_getpid nr 39 nbargs 0 types: () args: ()
+syscall sys_sendfile64 nr 40 nbargs 4 types: (int, int, loff_t *, size_t) args: (out_fd, in_fd, offset, count)
+syscall sys_socket nr 41 nbargs 3 types: (int, int, int) args: (family, type, protocol)
+syscall sys_connect nr 42 nbargs 3 types: (int, struct sockaddr *, int) args: (fd, uservaddr, addrlen)
+syscall sys_accept nr 43 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, upeer_sockaddr, upeer_addrlen)
+syscall sys_sendto nr 44 nbargs 6 types: (int, void *, size_t, unsigned, struct sockaddr *, int) args: (fd, buff, len, flags, addr, addr_len)
+syscall sys_recvfrom nr 45 nbargs 6 types: (int, void *, size_t, unsigned, struct sockaddr *, int *) args: (fd, ubuf, size, flags, addr, addr_len)
+syscall sys_sendmsg nr 46 nbargs 3 types: (int, struct msghdr *, unsigned) args: (fd, msg, flags)
+syscall sys_recvmsg nr 47 nbargs 3 types: (int, struct msghdr *, unsigned int) args: (fd, msg, flags)
+syscall sys_shutdown nr 48 nbargs 2 types: (int, int) args: (fd, how)
+syscall sys_bind nr 49 nbargs 3 types: (int, struct sockaddr *, int) args: (fd, umyaddr, addrlen)
+syscall sys_listen nr 50 nbargs 2 types: (int, int) args: (fd, backlog)
+syscall sys_getsockname nr 51 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, usockaddr, usockaddr_len)
+syscall sys_getpeername nr 52 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, usockaddr, usockaddr_len)
+syscall sys_socketpair nr 53 nbargs 4 types: (int, int, int, int *) args: (family, type, protocol, usockvec)
+syscall sys_setsockopt nr 54 nbargs 5 types: (int, int, int, char *, int) args: (fd, level, optname, optval, optlen)
+syscall sys_getsockopt nr 55 nbargs 5 types: (int, int, int, char *, int *) args: (fd, level, optname, optval, optlen)
+syscall sys_exit nr 60 nbargs 1 types: (int) args: (error_code)
+syscall sys_wait4 nr 61 nbargs 4 types: (pid_t, int *, int, struct rusage *) args: (upid, stat_addr, options, ru)
+syscall sys_kill nr 62 nbargs 2 types: (pid_t, int) args: (pid, sig)
+syscall sys_newuname nr 63 nbargs 1 types: (struct new_utsname *) args: (name)
+syscall sys_semget nr 64 nbargs 3 types: (key_t, int, int) args: (key, nsems, semflg)
+syscall sys_semop nr 65 nbargs 3 types: (int, struct sembuf *, unsigned) args: (semid, tsops, nsops)
+syscall sys_shmdt nr 67 nbargs 1 types: (char *) args: (shmaddr)
+syscall sys_msgget nr 68 nbargs 2 types: (key_t, int) args: (key, msgflg)
+syscall sys_msgsnd nr 69 nbargs 4 types: (int, struct msgbuf *, size_t, int) args: (msqid, msgp, msgsz, msgflg)
+syscall sys_msgrcv nr 70 nbargs 5 types: (int, struct msgbuf *, size_t, long, int) args: (msqid, msgp, msgsz, msgtyp, msgflg)
+syscall sys_msgctl nr 71 nbargs 3 types: (int, int, struct msqid_ds *) args: (msqid, cmd, buf)
+syscall sys_fcntl nr 72 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg)
+syscall sys_flock nr 73 nbargs 2 types: (unsigned int, unsigned int) args: (fd, cmd)
+syscall sys_fsync nr 74 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_fdatasync nr 75 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_truncate nr 76 nbargs 2 types: (const char *, long) args: (path, length)
+syscall sys_ftruncate nr 77 nbargs 2 types: (unsigned int, unsigned long) args: (fd, length)
+syscall sys_getdents nr 78 nbargs 3 types: (unsigned int, struct linux_dirent *, unsigned int) args: (fd, dirent, count)
+syscall sys_getcwd nr 79 nbargs 2 types: (char *, unsigned long) args: (buf, size)
+syscall sys_chdir nr 80 nbargs 1 types: (const char *) args: (filename)
+syscall sys_fchdir nr 81 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_rename nr 82 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_mkdir nr 83 nbargs 2 types: (const char *, int) args: (pathname, mode)
+syscall sys_rmdir nr 84 nbargs 1 types: (const char *) args: (pathname)
+syscall sys_creat nr 85 nbargs 2 types: (const char *, int) args: (pathname, mode)
+syscall sys_link nr 86 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_unlink nr 87 nbargs 1 types: (const char *) args: (pathname)
+syscall sys_symlink nr 88 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_readlink nr 89 nbargs 3 types: (const char *, char *, int) args: (path, buf, bufsiz)
+syscall sys_chmod nr 90 nbargs 2 types: (const char *, mode_t) args: (filename, mode)
+syscall sys_fchmod nr 91 nbargs 2 types: (unsigned int, mode_t) args: (fd, mode)
+syscall sys_chown nr 92 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group)
+syscall sys_fchown nr 93 nbargs 3 types: (unsigned int, uid_t, gid_t) args: (fd, user, group)
+syscall sys_lchown nr 94 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group)
+syscall sys_umask nr 95 nbargs 1 types: (int) args: (mask)
+syscall sys_gettimeofday nr 96 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz)
+syscall sys_getrlimit nr 97 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim)
+syscall sys_getrusage nr 98 nbargs 2 types: (int, struct rusage *) args: (who, ru)
+syscall sys_sysinfo nr 99 nbargs 1 types: (struct sysinfo *) args: (info)
+syscall sys_times nr 100 nbargs 1 types: (struct tms *) args: (tbuf)
+syscall sys_ptrace nr 101 nbargs 4 types: (long, long, unsigned long, unsigned long) args: (request, pid, addr, data)
+syscall sys_getuid nr 102 nbargs 0 types: () args: ()
+syscall sys_syslog nr 103 nbargs 3 types: (int, char *, int) args: (type, buf, len)
+syscall sys_getgid nr 104 nbargs 0 types: () args: ()
+syscall sys_setuid nr 105 nbargs 1 types: (uid_t) args: (uid)
+syscall sys_setgid nr 106 nbargs 1 types: (gid_t) args: (gid)
+syscall sys_geteuid nr 107 nbargs 0 types: () args: ()
+syscall sys_getegid nr 108 nbargs 0 types: () args: ()
+syscall sys_setpgid nr 109 nbargs 2 types: (pid_t, pid_t) args: (pid, pgid)
+syscall sys_getppid nr 110 nbargs 0 types: () args: ()
+syscall sys_getpgrp nr 111 nbargs 0 types: () args: ()
+syscall sys_setsid nr 112 nbargs 0 types: () args: ()
+syscall sys_setreuid nr 113 nbargs 2 types: (uid_t, uid_t) args: (ruid, euid)
+syscall sys_setregid nr 114 nbargs 2 types: (gid_t, gid_t) args: (rgid, egid)
+syscall sys_getgroups nr 115 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist)
+syscall sys_setgroups nr 116 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist)
+syscall sys_setresuid nr 117 nbargs 3 types: (uid_t, uid_t, uid_t) args: (ruid, euid, suid)
+syscall sys_getresuid nr 118 nbargs 3 types: (uid_t *, uid_t *, uid_t *) args: (ruid, euid, suid)
+syscall sys_setresgid nr 119 nbargs 3 types: (gid_t, gid_t, gid_t) args: (rgid, egid, sgid)
+syscall sys_getresgid nr 120 nbargs 3 types: (gid_t *, gid_t *, gid_t *) args: (rgid, egid, sgid)
+syscall sys_getpgid nr 121 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_setfsuid nr 122 nbargs 1 types: (uid_t) args: (uid)
+syscall sys_setfsgid nr 123 nbargs 1 types: (gid_t) args: (gid)
+syscall sys_getsid nr 124 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_capget nr 125 nbargs 2 types: (cap_user_header_t, cap_user_data_t) args: (header, dataptr)
+syscall sys_capset nr 126 nbargs 2 types: (cap_user_header_t, const cap_user_data_t) args: (header, data)
+syscall sys_rt_sigpending nr 127 nbargs 2 types: (sigset_t *, size_t) args: (set, sigsetsize)
+syscall sys_rt_sigtimedwait nr 128 nbargs 4 types: (const sigset_t *, siginfo_t *, const struct timespec *, size_t) args: (uthese, uinfo, uts, sigsetsize)
+syscall sys_rt_sigqueueinfo nr 129 nbargs 3 types: (pid_t, int, siginfo_t *) args: (pid, sig, uinfo)
+syscall sys_rt_sigsuspend nr 130 nbargs 2 types: (sigset_t *, size_t) args: (unewset, sigsetsize)
+syscall sys_utime nr 132 nbargs 2 types: (char *, struct utimbuf *) args: (filename, times)
+syscall sys_mknod nr 133 nbargs 3 types: (const char *, int, unsigned) args: (filename, mode, dev)
+syscall sys_personality nr 135 nbargs 1 types: (unsigned int) args: (personality)
+syscall sys_ustat nr 136 nbargs 2 types: (unsigned, struct ustat *) args: (dev, ubuf)
+syscall sys_statfs nr 137 nbargs 2 types: (const char *, struct statfs *) args: (pathname, buf)
+syscall sys_fstatfs nr 138 nbargs 2 types: (unsigned int, struct statfs *) args: (fd, buf)
+syscall sys_sysfs nr 139 nbargs 3 types: (int, unsigned long, unsigned long) args: (option, arg1, arg2)
+syscall sys_getpriority nr 140 nbargs 2 types: (int, int) args: (which, who)
+syscall sys_setpriority nr 141 nbargs 3 types: (int, int, int) args: (which, who, niceval)
+syscall sys_sched_setparam nr 142 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param)
+syscall sys_sched_getparam nr 143 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param)
+syscall sys_sched_setscheduler nr 144 nbargs 3 types: (pid_t, int, struct sched_param *) args: (pid, policy, param)
+syscall sys_sched_getscheduler nr 145 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_sched_get_priority_max nr 146 nbargs 1 types: (int) args: (policy)
+syscall sys_sched_get_priority_min nr 147 nbargs 1 types: (int) args: (policy)
+syscall sys_sched_rr_get_interval nr 148 nbargs 2 types: (pid_t, struct timespec *) args: (pid, interval)
+syscall sys_mlock nr 149 nbargs 2 types: (unsigned long, size_t) args: (start, len)
+syscall sys_munlock nr 150 nbargs 2 types: (unsigned long, size_t) args: (start, len)
+syscall sys_mlockall nr 151 nbargs 1 types: (int) args: (flags)
+syscall sys_munlockall nr 152 nbargs 0 types: () args: ()
+syscall sys_vhangup nr 153 nbargs 0 types: () args: ()
+syscall sys_pivot_root nr 155 nbargs 2 types: (const char *, const char *) args: (new_root, put_old)
+syscall sys_sysctl nr 156 nbargs 1 types: (struct __sysctl_args *) args: (args)
+syscall sys_prctl nr 157 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5)
+syscall sys_adjtimex nr 159 nbargs 1 types: (struct timex *) args: (txc_p)
+syscall sys_setrlimit nr 160 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim)
+syscall sys_chroot nr 161 nbargs 1 types: (const char *) args: (filename)
+syscall sys_sync nr 162 nbargs 0 types: () args: ()
+syscall sys_settimeofday nr 164 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz)
+syscall sys_mount nr 165 nbargs 5 types: (char *, char *, char *, unsigned long, void *) args: (dev_name, dir_name, type, flags, data)
+syscall sys_umount nr 166 nbargs 2 types: (char *, int) args: (name, flags)
+syscall sys_swapon nr 167 nbargs 2 types: (const char *, int) args: (specialfile, swap_flags)
+syscall sys_swapoff nr 168 nbargs 1 types: (const char *) args: (specialfile)
+syscall sys_reboot nr 169 nbargs 4 types: (int, int, unsigned int, void *) args: (magic1, magic2, cmd, arg)
+syscall sys_sethostname nr 170 nbargs 2 types: (char *, int) args: (name, len)
+syscall sys_setdomainname nr 171 nbargs 2 types: (char *, int) args: (name, len)
+syscall sys_init_module nr 175 nbargs 3 types: (void *, unsigned long, const char *) args: (umod, len, uargs)
+syscall sys_delete_module nr 176 nbargs 2 types: (const char *, unsigned int) args: (name_user, flags)
+syscall sys_nfsservctl nr 180 nbargs 3 types: (int, struct nfsctl_arg *, void *) args: (cmd, arg, res)
+syscall sys_gettid nr 186 nbargs 0 types: () args: ()
+syscall sys_setxattr nr 188 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags)
+syscall sys_lsetxattr nr 189 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags)
+syscall sys_fsetxattr nr 190 nbargs 5 types: (int, const char *, const void *, size_t, int) args: (fd, name, value, size, flags)
+syscall sys_getxattr nr 191 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size)
+syscall sys_lgetxattr nr 192 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size)
+syscall sys_fgetxattr nr 193 nbargs 4 types: (int, const char *, void *, size_t) args: (fd, name, value, size)
+syscall sys_listxattr nr 194 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size)
+syscall sys_llistxattr nr 195 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size)
+syscall sys_flistxattr nr 196 nbargs 3 types: (int, char *, size_t) args: (fd, list, size)
+syscall sys_removexattr nr 197 nbargs 2 types: (const char *, const char *) args: (pathname, name)
+syscall sys_lremovexattr nr 198 nbargs 2 types: (const char *, const char *) args: (pathname, name)
+syscall sys_fremovexattr nr 199 nbargs 2 types: (int, const char *) args: (fd, name)
+syscall sys_tkill nr 200 nbargs 2 types: (pid_t, int) args: (pid, sig)
+syscall sys_time nr 201 nbargs 1 types: (time_t *) args: (tloc)
+syscall sys_futex nr 202 nbargs 6 types: (u32 *, int, u32, struct timespec *, u32 *, u32) args: (uaddr, op, val, utime, uaddr2, val3)
+syscall sys_sched_setaffinity nr 203 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr)
+syscall sys_sched_getaffinity nr 204 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr)
+syscall sys_io_setup nr 206 nbargs 2 types: (unsigned, aio_context_t *) args: (nr_events, ctxp)
+syscall sys_io_destroy nr 207 nbargs 1 types: (aio_context_t) args: (ctx)
+syscall sys_io_getevents nr 208 nbargs 5 types: (aio_context_t, long, long, struct io_event *, struct timespec *) args: (ctx_id, min_nr, nr, events, timeout)
+syscall sys_io_submit nr 209 nbargs 3 types: (aio_context_t, long, struct iocb * *) args: (ctx_id, nr, iocbpp)
+syscall sys_io_cancel nr 210 nbargs 3 types: (aio_context_t, struct iocb *, struct io_event *) args: (ctx_id, iocb, result)
+syscall sys_epoll_create nr 213 nbargs 1 types: (int) args: (size)
+syscall sys_remap_file_pages nr 216 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (start, size, prot, pgoff, flags)
+syscall sys_getdents64 nr 217 nbargs 3 types: (unsigned int, struct linux_dirent64 *, unsigned int) args: (fd, dirent, count)
+syscall sys_set_tid_address nr 218 nbargs 1 types: (int *) args: (tidptr)
+syscall sys_restart_syscall nr 219 nbargs 0 types: () args: ()
+syscall sys_semtimedop nr 220 nbargs 4 types: (int, struct sembuf *, unsigned, const struct timespec *) args: (semid, tsops, nsops, timeout)
+syscall sys_timer_create nr 222 nbargs 3 types: (const clockid_t, struct sigevent *, timer_t *) args: (which_clock, timer_event_spec, created_timer_id)
+syscall sys_timer_settime nr 223 nbargs 4 types: (timer_t, int, const struct itimerspec *, struct itimerspec *) args: (timer_id, flags, new_setting, old_setting)
+syscall sys_timer_gettime nr 224 nbargs 2 types: (timer_t, struct itimerspec *) args: (timer_id, setting)
+syscall sys_timer_getoverrun nr 225 nbargs 1 types: (timer_t) args: (timer_id)
+syscall sys_timer_delete nr 226 nbargs 1 types: (timer_t) args: (timer_id)
+syscall sys_clock_settime nr 227 nbargs 2 types: (const clockid_t, const struct timespec *) args: (which_clock, tp)
+syscall sys_clock_gettime nr 228 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp)
+syscall sys_clock_getres nr 229 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp)
+syscall sys_clock_nanosleep nr 230 nbargs 4 types: (const clockid_t, int, const struct timespec *, struct timespec *) args: (which_clock, flags, rqtp, rmtp)
+syscall sys_exit_group nr 231 nbargs 1 types: (int) args: (error_code)
+syscall sys_epoll_wait nr 232 nbargs 4 types: (int, struct epoll_event *, int, int) args: (epfd, events, maxevents, timeout)
+syscall sys_epoll_ctl nr 233 nbargs 4 types: (int, int, int, struct epoll_event *) args: (epfd, op, fd, event)
+syscall sys_tgkill nr 234 nbargs 3 types: (pid_t, pid_t, int) args: (tgid, pid, sig)
+syscall sys_utimes nr 235 nbargs 2 types: (char *, struct timeval *) args: (filename, utimes)
+syscall sys_mq_open nr 240 nbargs 4 types: (const char *, int, mode_t, struct mq_attr *) args: (u_name, oflag, mode, u_attr)
+syscall sys_mq_unlink nr 241 nbargs 1 types: (const char *) args: (u_name)
+syscall sys_mq_timedsend nr 242 nbargs 5 types: (mqd_t, const char *, size_t, unsigned int, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout)
+syscall sys_mq_timedreceive nr 243 nbargs 5 types: (mqd_t, char *, size_t, unsigned int *, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout)
+syscall sys_mq_notify nr 244 nbargs 2 types: (mqd_t, const struct sigevent *) args: (mqdes, u_notification)
+syscall sys_mq_getsetattr nr 245 nbargs 3 types: (mqd_t, const struct mq_attr *, struct mq_attr *) args: (mqdes, u_mqstat, u_omqstat)
+syscall sys_kexec_load nr 246 nbargs 4 types: (unsigned long, unsigned long, struct kexec_segment *, unsigned long) args: (entry, nr_segments, segments, flags)
+syscall sys_waitid nr 247 nbargs 5 types: (int, pid_t, struct siginfo *, int, struct rusage *) args: (which, upid, infop, options, ru)
+syscall sys_ioprio_set nr 251 nbargs 3 types: (int, int, int) args: (which, who, ioprio)
+syscall sys_ioprio_get nr 252 nbargs 2 types: (int, int) args: (which, who)
+syscall sys_inotify_init nr 253 nbargs 0 types: () args: ()
+syscall sys_inotify_add_watch nr 254 nbargs 3 types: (int, const char *, u32) args: (fd, pathname, mask)
+syscall sys_inotify_rm_watch nr 255 nbargs 2 types: (int, __s32) args: (fd, wd)
+syscall sys_openat nr 257 nbargs 4 types: (int, const char *, int, int) args: (dfd, filename, flags, mode)
+syscall sys_mkdirat nr 258 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, mode)
+syscall sys_mknodat nr 259 nbargs 4 types: (int, const char *, int, unsigned) args: (dfd, filename, mode, dev)
+syscall sys_fchownat nr 260 nbargs 5 types: (int, const char *, uid_t, gid_t, int) args: (dfd, filename, user, group, flag)
+syscall sys_futimesat nr 261 nbargs 3 types: (int, const char *, struct timeval *) args: (dfd, filename, utimes)
+syscall sys_newfstatat nr 262 nbargs 4 types: (int, const char *, struct stat *, int) args: (dfd, filename, statbuf, flag)
+syscall sys_unlinkat nr 263 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, flag)
+syscall sys_renameat nr 264 nbargs 4 types: (int, const char *, int, const char *) args: (olddfd, oldname, newdfd, newname)
+syscall sys_linkat nr 265 nbargs 5 types: (int, const char *, int, const char *, int) args: (olddfd, oldname, newdfd, newname, flags)
+syscall sys_symlinkat nr 266 nbargs 3 types: (const char *, int, const char *) args: (oldname, newdfd, newname)
+syscall sys_readlinkat nr 267 nbargs 4 types: (int, const char *, char *, int) args: (dfd, pathname, buf, bufsiz)
+syscall sys_fchmodat nr 268 nbargs 3 types: (int, const char *, mode_t) args: (dfd, filename, mode)
+syscall sys_faccessat nr 269 nbargs 3 types: (int, const char *, int) args: (dfd, filename, mode)
+syscall sys_pselect6 nr 270 nbargs 6 types: (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *) args: (n, inp, outp, exp, tsp, sig)
+syscall sys_ppoll nr 271 nbargs 5 types: (struct pollfd *, unsigned int, struct timespec *, const sigset_t *, size_t) args: (ufds, nfds, tsp, sigmask, sigsetsize)
+syscall sys_unshare nr 272 nbargs 1 types: (unsigned long) args: (unshare_flags)
+syscall sys_set_robust_list nr 273 nbargs 2 types: (struct robust_list_head *, size_t) args: (head, len)
+syscall sys_get_robust_list nr 274 nbargs 3 types: (int, struct robust_list_head * *, size_t *) args: (pid, head_ptr, len_ptr)
+syscall sys_splice nr 275 nbargs 6 types: (int, loff_t *, int, loff_t *, size_t, unsigned int) args: (fd_in, off_in, fd_out, off_out, len, flags)
+syscall sys_tee nr 276 nbargs 4 types: (int, int, size_t, unsigned int) args: (fdin, fdout, len, flags)
+syscall sys_vmsplice nr 278 nbargs 4 types: (int, const struct iovec *, unsigned long, unsigned int) args: (fd, iov, nr_segs, flags)
+syscall sys_utimensat nr 280 nbargs 4 types: (int, const char *, struct timespec *, int) args: (dfd, filename, utimes, flags)
+syscall sys_epoll_pwait nr 281 nbargs 6 types: (int, struct epoll_event *, int, int, const sigset_t *, size_t) args: (epfd, events, maxevents, timeout, sigmask, sigsetsize)
+syscall sys_signalfd nr 282 nbargs 3 types: (int, sigset_t *, size_t) args: (ufd, user_mask, sizemask)
+syscall sys_timerfd_create nr 283 nbargs 2 types: (int, int) args: (clockid, flags)
+syscall sys_eventfd nr 284 nbargs 1 types: (unsigned int) args: (count)
+syscall sys_timerfd_settime nr 286 nbargs 4 types: (int, int, const struct itimerspec *, struct itimerspec *) args: (ufd, flags, utmr, otmr)
+syscall sys_timerfd_gettime nr 287 nbargs 2 types: (int, struct itimerspec *) args: (ufd, otmr)
+syscall sys_accept4 nr 288 nbargs 4 types: (int, struct sockaddr *, int *, int) args: (fd, upeer_sockaddr, upeer_addrlen, flags)
+syscall sys_signalfd4 nr 289 nbargs 4 types: (int, sigset_t *, size_t, int) args: (ufd, user_mask, sizemask, flags)
+syscall sys_eventfd2 nr 290 nbargs 2 types: (unsigned int, int) args: (count, flags)
+syscall sys_epoll_create1 nr 291 nbargs 1 types: (int) args: (flags)
+syscall sys_dup3 nr 292 nbargs 3 types: (unsigned int, unsigned int, int) args: (oldfd, newfd, flags)
+syscall sys_pipe2 nr 293 nbargs 2 types: (int *, int) args: (fildes, flags)
+syscall sys_inotify_init1 nr 294 nbargs 1 types: (int) args: (flags)
+syscall sys_preadv nr 295 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h)
+syscall sys_pwritev nr 296 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h)
+syscall sys_rt_tgsigqueueinfo nr 297 nbargs 4 types: (pid_t, pid_t, int, siginfo_t *) args: (tgid, pid, sig, uinfo)
+syscall sys_perf_event_open nr 298 nbargs 5 types: (struct perf_event_attr *, pid_t, int, int, unsigned long) args: (attr_uptr, pid, cpu, group_fd, flags)
+syscall sys_recvmmsg nr 299 nbargs 5 types: (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *) args: (fd, mmsg, vlen, flags, timeout)
+syscall sys_prlimit64 nr 302 nbargs 4 types: (pid_t, unsigned int, const struct rlimit64 *, struct rlimit64 *) args: (pid, resource, new_rlim, old_rlim)
+syscall sys_clock_adjtime nr 305 nbargs 2 types: (const clockid_t, struct timex *) args: (which_clock, utx)
+syscall sys_syncfs nr 306 nbargs 1 types: (int) args: (fd)
+syscall sys_sendmmsg nr 307 nbargs 4 types: (int, struct mmsghdr *, unsigned int, unsigned int) args: (fd, mmsg, vlen, flags)
+syscall sys_setns nr 308 nbargs 2 types: (int, int) args: (fd, nstype)
diff --git a/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 b/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6
new file mode 100644
index 0000000..130c1e3
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6
@@ -0,0 +1,291 @@
+syscall sys_restart_syscall nr 0 nbargs 0 types: () args: ()
+syscall sys_exit nr 1 nbargs 1 types: (int) args: (error_code)
+syscall sys_read nr 3 nbargs 3 types: (unsigned int, char *, size_t) args: (fd, buf, count)
+syscall sys_write nr 4 nbargs 3 types: (unsigned int, const char *, size_t) args: (fd, buf, count)
+syscall sys_open nr 5 nbargs 3 types: (const char *, int, int) args: (filename, flags, mode)
+syscall sys_close nr 6 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_waitpid nr 7 nbargs 3 types: (pid_t, int *, int) args: (pid, stat_addr, options)
+syscall sys_creat nr 8 nbargs 2 types: (const char *, int) args: (pathname, mode)
+syscall sys_link nr 9 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_unlink nr 10 nbargs 1 types: (const char *) args: (pathname)
+syscall sys_chdir nr 12 nbargs 1 types: (const char *) args: (filename)
+syscall sys_time nr 13 nbargs 1 types: (time_t *) args: (tloc)
+syscall sys_mknod nr 14 nbargs 3 types: (const char *, int, unsigned) args: (filename, mode, dev)
+syscall sys_chmod nr 15 nbargs 2 types: (const char *, mode_t) args: (filename, mode)
+syscall sys_lchown16 nr 16 nbargs 3 types: (const char *, old_uid_t, old_gid_t) args: (filename, user, group)
+syscall sys_stat nr 18 nbargs 2 types: (const char *, struct __old_kernel_stat *) args: (filename, statbuf)
+syscall sys_lseek nr 19 nbargs 3 types: (unsigned int, off_t, unsigned int) args: (fd, offset, origin)
+syscall sys_getpid nr 20 nbargs 0 types: () args: ()
+syscall sys_mount nr 21 nbargs 5 types: (char *, char *, char *, unsigned long, void *) args: (dev_name, dir_name, type, flags, data)
+syscall sys_oldumount nr 22 nbargs 1 types: (char *) args: (name)
+syscall sys_setuid16 nr 23 nbargs 1 types: (old_uid_t) args: (uid)
+syscall sys_getuid16 nr 24 nbargs 0 types: () args: ()
+syscall sys_stime nr 25 nbargs 1 types: (time_t *) args: (tptr)
+syscall sys_ptrace nr 26 nbargs 4 types: (long, long, unsigned long, unsigned long) args: (request, pid, addr, data)
+syscall sys_alarm nr 27 nbargs 1 types: (unsigned int) args: (seconds)
+syscall sys_fstat nr 28 nbargs 2 types: (unsigned int, struct __old_kernel_stat *) args: (fd, statbuf)
+syscall sys_pause nr 29 nbargs 0 types: () args: ()
+syscall sys_utime nr 30 nbargs 2 types: (char *, struct utimbuf *) args: (filename, times)
+syscall sys_access nr 33 nbargs 2 types: (const char *, int) args: (filename, mode)
+syscall sys_nice nr 34 nbargs 1 types: (int) args: (increment)
+syscall sys_sync nr 36 nbargs 0 types: () args: ()
+syscall sys_kill nr 37 nbargs 2 types: (pid_t, int) args: (pid, sig)
+syscall sys_rename nr 38 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_mkdir nr 39 nbargs 2 types: (const char *, int) args: (pathname, mode)
+syscall sys_rmdir nr 40 nbargs 1 types: (const char *) args: (pathname)
+syscall sys_dup nr 41 nbargs 1 types: (unsigned int) args: (fildes)
+syscall sys_pipe nr 42 nbargs 1 types: (int *) args: (fildes)
+syscall sys_times nr 43 nbargs 1 types: (struct tms *) args: (tbuf)
+syscall sys_brk nr 45 nbargs 1 types: (unsigned long) args: (brk)
+syscall sys_setgid16 nr 46 nbargs 1 types: (old_gid_t) args: (gid)
+syscall sys_getgid16 nr 47 nbargs 0 types: () args: ()
+syscall sys_signal nr 48 nbargs 2 types: (int, __sighandler_t) args: (sig, handler)
+syscall sys_geteuid16 nr 49 nbargs 0 types: () args: ()
+syscall sys_getegid16 nr 50 nbargs 0 types: () args: ()
+syscall sys_acct nr 51 nbargs 1 types: (const char *) args: (name)
+syscall sys_umount nr 52 nbargs 2 types: (char *, int) args: (name, flags)
+syscall sys_ioctl nr 54 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg)
+syscall sys_fcntl nr 55 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg)
+syscall sys_setpgid nr 57 nbargs 2 types: (pid_t, pid_t) args: (pid, pgid)
+syscall sys_olduname nr 59 nbargs 1 types: (struct oldold_utsname *) args: (name)
+syscall sys_umask nr 60 nbargs 1 types: (int) args: (mask)
+syscall sys_chroot nr 61 nbargs 1 types: (const char *) args: (filename)
+syscall sys_ustat nr 62 nbargs 2 types: (unsigned, struct ustat *) args: (dev, ubuf)
+syscall sys_dup2 nr 63 nbargs 2 types: (unsigned int, unsigned int) args: (oldfd, newfd)
+syscall sys_getppid nr 64 nbargs 0 types: () args: ()
+syscall sys_getpgrp nr 65 nbargs 0 types: () args: ()
+syscall sys_setsid nr 66 nbargs 0 types: () args: ()
+syscall sys_sgetmask nr 68 nbargs 0 types: () args: ()
+syscall sys_ssetmask nr 69 nbargs 1 types: (int) args: (newmask)
+syscall sys_setreuid16 nr 70 nbargs 2 types: (old_uid_t, old_uid_t) args: (ruid, euid)
+syscall sys_setregid16 nr 71 nbargs 2 types: (old_gid_t, old_gid_t) args: (rgid, egid)
+syscall sys_sigpending nr 73 nbargs 1 types: (old_sigset_t *) args: (set)
+syscall sys_sethostname nr 74 nbargs 2 types: (char *, int) args: (name, len)
+syscall sys_setrlimit nr 75 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim)
+syscall sys_old_getrlimit nr 76 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim)
+syscall sys_getrusage nr 77 nbargs 2 types: (int, struct rusage *) args: (who, ru)
+syscall sys_gettimeofday nr 78 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz)
+syscall sys_settimeofday nr 79 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz)
+syscall sys_getgroups16 nr 80 nbargs 2 types: (int, old_gid_t *) args: (gidsetsize, grouplist)
+syscall sys_setgroups16 nr 81 nbargs 2 types: (int, old_gid_t *) args: (gidsetsize, grouplist)
+syscall sys_old_select nr 82 nbargs 1 types: (struct sel_arg_struct *) args: (arg)
+syscall sys_symlink nr 83 nbargs 2 types: (const char *, const char *) args: (oldname, newname)
+syscall sys_lstat nr 84 nbargs 2 types: (const char *, struct __old_kernel_stat *) args: (filename, statbuf)
+syscall sys_readlink nr 85 nbargs 3 types: (const char *, char *, int) args: (path, buf, bufsiz)
+syscall sys_uselib nr 86 nbargs 1 types: (const char *) args: (library)
+syscall sys_swapon nr 87 nbargs 2 types: (const char *, int) args: (specialfile, swap_flags)
+syscall sys_reboot nr 88 nbargs 4 types: (int, int, unsigned int, void *) args: (magic1, magic2, cmd, arg)
+syscall sys_old_readdir nr 89 nbargs 3 types: (unsigned int, struct old_linux_dirent *, unsigned int) args: (fd, dirent, count)
+syscall sys_old_mmap nr 90 nbargs 1 types: (struct mmap_arg_struct *) args: (arg)
+syscall sys_munmap nr 91 nbargs 2 types: (unsigned long, size_t) args: (addr, len)
+syscall sys_truncate nr 92 nbargs 2 types: (const char *, long) args: (path, length)
+syscall sys_ftruncate nr 93 nbargs 2 types: (unsigned int, unsigned long) args: (fd, length)
+syscall sys_fchmod nr 94 nbargs 2 types: (unsigned int, mode_t) args: (fd, mode)
+syscall sys_fchown16 nr 95 nbargs 3 types: (unsigned int, old_uid_t, old_gid_t) args: (fd, user, group)
+syscall sys_getpriority nr 96 nbargs 2 types: (int, int) args: (which, who)
+syscall sys_setpriority nr 97 nbargs 3 types: (int, int, int) args: (which, who, niceval)
+syscall sys_statfs nr 99 nbargs 2 types: (const char *, struct statfs *) args: (pathname, buf)
+syscall sys_fstatfs nr 100 nbargs 2 types: (unsigned int, struct statfs *) args: (fd, buf)
+syscall sys_socketcall nr 102 nbargs 2 types: (int, unsigned long *) args: (call, args)
+syscall sys_syslog nr 103 nbargs 3 types: (int, char *, int) args: (type, buf, len)
+syscall sys_setitimer nr 104 nbargs 3 types: (int, struct itimerval *, struct itimerval *) args: (which, value, ovalue)
+syscall sys_getitimer nr 105 nbargs 2 types: (int, struct itimerval *) args: (which, value)
+syscall sys_newstat nr 106 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf)
+syscall sys_newlstat nr 107 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf)
+syscall sys_newfstat nr 108 nbargs 2 types: (unsigned int, struct stat *) args: (fd, statbuf)
+syscall sys_uname nr 109 nbargs 1 types: (struct old_utsname *) args: (name)
+syscall sys_vhangup nr 111 nbargs 0 types: () args: ()
+syscall sys_wait4 nr 114 nbargs 4 types: (pid_t, int *, int, struct rusage *) args: (upid, stat_addr, options, ru)
+syscall sys_swapoff nr 115 nbargs 1 types: (const char *) args: (specialfile)
+syscall sys_sysinfo nr 116 nbargs 1 types: (struct sysinfo *) args: (info)
+syscall sys_ipc nr 117 nbargs 6 types: (unsigned int, int, unsigned long, unsigned long, void *, long) args: (call, first, second, third, ptr, fifth)
+syscall sys_fsync nr 118 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_setdomainname nr 121 nbargs 2 types: (char *, int) args: (name, len)
+syscall sys_newuname nr 122 nbargs 1 types: (struct new_utsname *) args: (name)
+syscall sys_adjtimex nr 124 nbargs 1 types: (struct timex *) args: (txc_p)
+syscall sys_mprotect nr 125 nbargs 3 types: (unsigned long, size_t, unsigned long) args: (start, len, prot)
+syscall sys_sigprocmask nr 126 nbargs 3 types: (int, old_sigset_t *, old_sigset_t *) args: (how, nset, oset)
+syscall sys_init_module nr 128 nbargs 3 types: (void *, unsigned long, const char *) args: (umod, len, uargs)
+syscall sys_delete_module nr 129 nbargs 2 types: (const char *, unsigned int) args: (name_user, flags)
+syscall sys_quotactl nr 131 nbargs 4 types: (unsigned int, const char *, qid_t, void *) args: (cmd, special, id, addr)
+syscall sys_getpgid nr 132 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_fchdir nr 133 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_bdflush nr 134 nbargs 2 types: (int, long) args: (func, data)
+syscall sys_sysfs nr 135 nbargs 3 types: (int, unsigned long, unsigned long) args: (option, arg1, arg2)
+syscall sys_personality nr 136 nbargs 1 types: (unsigned int) args: (personality)
+syscall sys_setfsuid16 nr 138 nbargs 1 types: (old_uid_t) args: (uid)
+syscall sys_setfsgid16 nr 139 nbargs 1 types: (old_gid_t) args: (gid)
+syscall sys_llseek nr 140 nbargs 5 types: (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int) args: (fd, offset_high, offset_low, result, origin)
+syscall sys_getdents nr 141 nbargs 3 types: (unsigned int, struct linux_dirent *, unsigned int) args: (fd, dirent, count)
+syscall sys_select nr 142 nbargs 5 types: (int, fd_set *, fd_set *, fd_set *, struct timeval *) args: (n, inp, outp, exp, tvp)
+syscall sys_flock nr 143 nbargs 2 types: (unsigned int, unsigned int) args: (fd, cmd)
+syscall sys_msync nr 144 nbargs 3 types: (unsigned long, size_t, int) args: (start, len, flags)
+syscall sys_readv nr 145 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen)
+syscall sys_writev nr 146 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen)
+syscall sys_getsid nr 147 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_fdatasync nr 148 nbargs 1 types: (unsigned int) args: (fd)
+syscall sys_sysctl nr 149 nbargs 1 types: (struct __sysctl_args *) args: (args)
+syscall sys_mlock nr 150 nbargs 2 types: (unsigned long, size_t) args: (start, len)
+syscall sys_munlock nr 151 nbargs 2 types: (unsigned long, size_t) args: (start, len)
+syscall sys_mlockall nr 152 nbargs 1 types: (int) args: (flags)
+syscall sys_munlockall nr 153 nbargs 0 types: () args: ()
+syscall sys_sched_setparam nr 154 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param)
+syscall sys_sched_getparam nr 155 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param)
+syscall sys_sched_setscheduler nr 156 nbargs 3 types: (pid_t, int, struct sched_param *) args: (pid, policy, param)
+syscall sys_sched_getscheduler nr 157 nbargs 1 types: (pid_t) args: (pid)
+syscall sys_sched_yield nr 158 nbargs 0 types: () args: ()
+syscall sys_sched_get_priority_max nr 159 nbargs 1 types: (int) args: (policy)
+syscall sys_sched_get_priority_min nr 160 nbargs 1 types: (int) args: (policy)
+syscall sys_sched_rr_get_interval nr 161 nbargs 2 types: (pid_t, struct timespec *) args: (pid, interval)
+syscall sys_nanosleep nr 162 nbargs 2 types: (struct timespec *, struct timespec *) args: (rqtp, rmtp)
+syscall sys_mremap nr 163 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, old_len, new_len, flags, new_addr)
+syscall sys_setresuid16 nr 164 nbargs 3 types: (old_uid_t, old_uid_t, old_uid_t) args: (ruid, euid, suid)
+syscall sys_getresuid16 nr 165 nbargs 3 types: (old_uid_t *, old_uid_t *, old_uid_t *) args: (ruid, euid, suid)
+syscall sys_poll nr 168 nbargs 3 types: (struct pollfd *, unsigned int, long) args: (ufds, nfds, timeout_msecs)
+syscall sys_setresgid16 nr 170 nbargs 3 types: (old_gid_t, old_gid_t, old_gid_t) args: (rgid, egid, sgid)
+syscall sys_getresgid16 nr 171 nbargs 3 types: (old_gid_t *, old_gid_t *, old_gid_t *) args: (rgid, egid, sgid)
+syscall sys_prctl nr 172 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5)
+syscall sys_rt_sigaction nr 174 nbargs 4 types: (int, const struct sigaction *, struct sigaction *, size_t) args: (sig, act, oact, sigsetsize)
+syscall sys_rt_sigprocmask nr 175 nbargs 4 types: (int, sigset_t *, sigset_t *, size_t) args: (how, nset, oset, sigsetsize)
+syscall sys_rt_sigpending nr 176 nbargs 2 types: (sigset_t *, size_t) args: (set, sigsetsize)
+syscall sys_rt_sigtimedwait nr 177 nbargs 4 types: (const sigset_t *, siginfo_t *, const struct timespec *, size_t) args: (uthese, uinfo, uts, sigsetsize)
+syscall sys_rt_sigqueueinfo nr 178 nbargs 3 types: (pid_t, int, siginfo_t *) args: (pid, sig, uinfo)
+syscall sys_rt_sigsuspend nr 179 nbargs 2 types: (sigset_t *, size_t) args: (unewset, sigsetsize)
+syscall sys_chown16 nr 182 nbargs 3 types: (const char *, old_uid_t, old_gid_t) args: (filename, user, group)
+syscall sys_getcwd nr 183 nbargs 2 types: (char *, unsigned long) args: (buf, size)
+syscall sys_capget nr 184 nbargs 2 types: (cap_user_header_t, cap_user_data_t) args: (header, dataptr)
+syscall sys_capset nr 185 nbargs 2 types: (cap_user_header_t, const cap_user_data_t) args: (header, data)
+syscall sys_sendfile nr 187 nbargs 4 types: (int, int, off_t *, size_t) args: (out_fd, in_fd, offset, count)
+syscall sys_getrlimit nr 191 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim)
+syscall sys_mmap_pgoff nr 192 nbargs 6 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, len, prot, flags, fd, pgoff)
+syscall sys_stat64 nr 195 nbargs 2 types: (const char *, struct stat64 *) args: (filename, statbuf)
+syscall sys_lstat64 nr 196 nbargs 2 types: (const char *, struct stat64 *) args: (filename, statbuf)
+syscall sys_fstat64 nr 197 nbargs 2 types: (unsigned long, struct stat64 *) args: (fd, statbuf)
+syscall sys_lchown nr 198 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group)
+syscall sys_getuid nr 199 nbargs 0 types: () args: ()
+syscall sys_getgid nr 200 nbargs 0 types: () args: ()
+syscall sys_geteuid nr 201 nbargs 0 types: () args: ()
+syscall sys_getegid nr 202 nbargs 0 types: () args: ()
+syscall sys_setreuid nr 203 nbargs 2 types: (uid_t, uid_t) args: (ruid, euid)
+syscall sys_setregid nr 204 nbargs 2 types: (gid_t, gid_t) args: (rgid, egid)
+syscall sys_getgroups nr 205 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist)
+syscall sys_setgroups nr 206 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist)
+syscall sys_fchown nr 207 nbargs 3 types: (unsigned int, uid_t, gid_t) args: (fd, user, group)
+syscall sys_setresuid nr 208 nbargs 3 types: (uid_t, uid_t, uid_t) args: (ruid, euid, suid)
+syscall sys_getresuid nr 209 nbargs 3 types: (uid_t *, uid_t *, uid_t *) args: (ruid, euid, suid)
+syscall sys_setresgid nr 210 nbargs 3 types: (gid_t, gid_t, gid_t) args: (rgid, egid, sgid)
+syscall sys_getresgid nr 211 nbargs 3 types: (gid_t *, gid_t *, gid_t *) args: (rgid, egid, sgid)
+syscall sys_chown nr 212 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group)
+syscall sys_setuid nr 213 nbargs 1 types: (uid_t) args: (uid)
+syscall sys_setgid nr 214 nbargs 1 types: (gid_t) args: (gid)
+syscall sys_setfsuid nr 215 nbargs 1 types: (uid_t) args: (uid)
+syscall sys_setfsgid nr 216 nbargs 1 types: (gid_t) args: (gid)
+syscall sys_pivot_root nr 217 nbargs 2 types: (const char *, const char *) args: (new_root, put_old)
+syscall sys_mincore nr 218 nbargs 3 types: (unsigned long, size_t, unsigned char *) args: (start, len, vec)
+syscall sys_madvise nr 219 nbargs 3 types: (unsigned long, size_t, int) args: (start, len_in, behavior)
+syscall sys_getdents64 nr 220 nbargs 3 types: (unsigned int, struct linux_dirent64 *, unsigned int) args: (fd, dirent, count)
+syscall sys_fcntl64 nr 221 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg)
+syscall sys_gettid nr 224 nbargs 0 types: () args: ()
+syscall sys_setxattr nr 226 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags)
+syscall sys_lsetxattr nr 227 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags)
+syscall sys_fsetxattr nr 228 nbargs 5 types: (int, const char *, const void *, size_t, int) args: (fd, name, value, size, flags)
+syscall sys_getxattr nr 229 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size)
+syscall sys_lgetxattr nr 230 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size)
+syscall sys_fgetxattr nr 231 nbargs 4 types: (int, const char *, void *, size_t) args: (fd, name, value, size)
+syscall sys_listxattr nr 232 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size)
+syscall sys_llistxattr nr 233 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size)
+syscall sys_flistxattr nr 234 nbargs 3 types: (int, char *, size_t) args: (fd, list, size)
+syscall sys_removexattr nr 235 nbargs 2 types: (const char *, const char *) args: (pathname, name)
+syscall sys_lremovexattr nr 236 nbargs 2 types: (const char *, const char *) args: (pathname, name)
+syscall sys_fremovexattr nr 237 nbargs 2 types: (int, const char *) args: (fd, name)
+syscall sys_tkill nr 238 nbargs 2 types: (pid_t, int) args: (pid, sig)
+syscall sys_sendfile64 nr 239 nbargs 4 types: (int, int, loff_t *, size_t) args: (out_fd, in_fd, offset, count)
+syscall sys_futex nr 240 nbargs 6 types: (u32 *, int, u32, struct timespec *, u32 *, u32) args: (uaddr, op, val, utime, uaddr2, val3)
+syscall sys_sched_setaffinity nr 241 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr)
+syscall sys_sched_getaffinity nr 242 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr)
+syscall sys_io_setup nr 245 nbargs 2 types: (unsigned, aio_context_t *) args: (nr_events, ctxp)
+syscall sys_io_destroy nr 246 nbargs 1 types: (aio_context_t) args: (ctx)
+syscall sys_io_getevents nr 247 nbargs 5 types: (aio_context_t, long, long, struct io_event *, struct timespec *) args: (ctx_id, min_nr, nr, events, timeout)
+syscall sys_io_submit nr 248 nbargs 3 types: (aio_context_t, long, struct iocb * *) args: (ctx_id, nr, iocbpp)
+syscall sys_io_cancel nr 249 nbargs 3 types: (aio_context_t, struct iocb *, struct io_event *) args: (ctx_id, iocb, result)
+syscall sys_exit_group nr 252 nbargs 1 types: (int) args: (error_code)
+syscall sys_epoll_create nr 254 nbargs 1 types: (int) args: (size)
+syscall sys_epoll_ctl nr 255 nbargs 4 types: (int, int, int, struct epoll_event *) args: (epfd, op, fd, event)
+syscall sys_epoll_wait nr 256 nbargs 4 types: (int, struct epoll_event *, int, int) args: (epfd, events, maxevents, timeout)
+syscall sys_remap_file_pages nr 257 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (start, size, prot, pgoff, flags)
+syscall sys_set_tid_address nr 258 nbargs 1 types: (int *) args: (tidptr)
+syscall sys_timer_create nr 259 nbargs 3 types: (const clockid_t, struct sigevent *, timer_t *) args: (which_clock, timer_event_spec, created_timer_id)
+syscall sys_timer_settime nr 260 nbargs 4 types: (timer_t, int, const struct itimerspec *, struct itimerspec *) args: (timer_id, flags, new_setting, old_setting)
+syscall sys_timer_gettime nr 261 nbargs 2 types: (timer_t, struct itimerspec *) args: (timer_id, setting)
+syscall sys_timer_getoverrun nr 262 nbargs 1 types: (timer_t) args: (timer_id)
+syscall sys_timer_delete nr 263 nbargs 1 types: (timer_t) args: (timer_id)
+syscall sys_clock_settime nr 264 nbargs 2 types: (const clockid_t, const struct timespec *) args: (which_clock, tp)
+syscall sys_clock_gettime nr 265 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp)
+syscall sys_clock_getres nr 266 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp)
+syscall sys_clock_nanosleep nr 267 nbargs 4 types: (const clockid_t, int, const struct timespec *, struct timespec *) args: (which_clock, flags, rqtp, rmtp)
+syscall sys_statfs64 nr 268 nbargs 3 types: (const char *, size_t, struct statfs64 *) args: (pathname, sz, buf)
+syscall sys_fstatfs64 nr 269 nbargs 3 types: (unsigned int, size_t, struct statfs64 *) args: (fd, sz, buf)
+syscall sys_tgkill nr 270 nbargs 3 types: (pid_t, pid_t, int) args: (tgid, pid, sig)
+syscall sys_utimes nr 271 nbargs 2 types: (char *, struct timeval *) args: (filename, utimes)
+syscall sys_mq_open nr 277 nbargs 4 types: (const char *, int, mode_t, struct mq_attr *) args: (u_name, oflag, mode, u_attr)
+syscall sys_mq_unlink nr 278 nbargs 1 types: (const char *) args: (u_name)
+syscall sys_mq_timedsend nr 279 nbargs 5 types: (mqd_t, const char *, size_t, unsigned int, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout)
+syscall sys_mq_timedreceive nr 280 nbargs 5 types: (mqd_t, char *, size_t, unsigned int *, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout)
+syscall sys_mq_notify nr 281 nbargs 2 types: (mqd_t, const struct sigevent *) args: (mqdes, u_notification)
+syscall sys_mq_getsetattr nr 282 nbargs 3 types: (mqd_t, const struct mq_attr *, struct mq_attr *) args: (mqdes, u_mqstat, u_omqstat)
+syscall sys_kexec_load nr 283 nbargs 4 types: (unsigned long, unsigned long, struct kexec_segment *, unsigned long) args: (entry, nr_segments, segments, flags)
+syscall sys_waitid nr 284 nbargs 5 types: (int, pid_t, struct siginfo *, int, struct rusage *) args: (which, upid, infop, options, ru)
+syscall sys_add_key nr 286 nbargs 5 types: (const char *, const char *, const void *, size_t, key_serial_t) args: (_type, _description, _payload, plen, ringid)
+syscall sys_request_key nr 287 nbargs 4 types: (const char *, const char *, const char *, key_serial_t) args: (_type, _description, _callout_info, destringid)
+syscall sys_keyctl nr 288 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5)
+syscall sys_ioprio_set nr 289 nbargs 3 types: (int, int, int) args: (which, who, ioprio)
+syscall sys_ioprio_get nr 290 nbargs 2 types: (int, int) args: (which, who)
+syscall sys_inotify_init nr 291 nbargs 0 types: () args: ()
+syscall sys_inotify_add_watch nr 292 nbargs 3 types: (int, const char *, u32) args: (fd, pathname, mask)
+syscall sys_inotify_rm_watch nr 293 nbargs 2 types: (int, __s32) args: (fd, wd)
+syscall sys_openat nr 295 nbargs 4 types: (int, const char *, int, int) args: (dfd, filename, flags, mode)
+syscall sys_mkdirat nr 296 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, mode)
+syscall sys_mknodat nr 297 nbargs 4 types: (int, const char *, int, unsigned) args: (dfd, filename, mode, dev)
+syscall sys_fchownat nr 298 nbargs 5 types: (int, const char *, uid_t, gid_t, int) args: (dfd, filename, user, group, flag)
+syscall sys_futimesat nr 299 nbargs 3 types: (int, const char *, struct timeval *) args: (dfd, filename, utimes)
+syscall sys_fstatat64 nr 300 nbargs 4 types: (int, const char *, struct stat64 *, int) args: (dfd, filename, statbuf, flag)
+syscall sys_unlinkat nr 301 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, flag)
+syscall sys_renameat nr 302 nbargs 4 types: (int, const char *, int, const char *) args: (olddfd, oldname, newdfd, newname)
+syscall sys_linkat nr 303 nbargs 5 types: (int, const char *, int, const char *, int) args: (olddfd, oldname, newdfd, newname, flags)
+syscall sys_symlinkat nr 304 nbargs 3 types: (const char *, int, const char *) args: (oldname, newdfd, newname)
+syscall sys_readlinkat nr 305 nbargs 4 types: (int, const char *, char *, int) args: (dfd, pathname, buf, bufsiz)
+syscall sys_fchmodat nr 306 nbargs 3 types: (int, const char *, mode_t) args: (dfd, filename, mode)
+syscall sys_faccessat nr 307 nbargs 3 types: (int, const char *, int) args: (dfd, filename, mode)
+syscall sys_pselect6 nr 308 nbargs 6 types: (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *) args: (n, inp, outp, exp, tsp, sig)
+syscall sys_ppoll nr 309 nbargs 5 types: (struct pollfd *, unsigned int, struct timespec *, const sigset_t *, size_t) args: (ufds, nfds, tsp, sigmask, sigsetsize)
+syscall sys_unshare nr 310 nbargs 1 types: (unsigned long) args: (unshare_flags)
+syscall sys_set_robust_list nr 311 nbargs 2 types: (struct robust_list_head *, size_t) args: (head, len)
+syscall sys_get_robust_list nr 312 nbargs 3 types: (int, struct robust_list_head * *, size_t *) args: (pid, head_ptr, len_ptr)
+syscall sys_splice nr 313 nbargs 6 types: (int, loff_t *, int, loff_t *, size_t, unsigned int) args: (fd_in, off_in, fd_out, off_out, len, flags)
+syscall sys_tee nr 315 nbargs 4 types: (int, int, size_t, unsigned int) args: (fdin, fdout, len, flags)
+syscall sys_vmsplice nr 316 nbargs 4 types: (int, const struct iovec *, unsigned long, unsigned int) args: (fd, iov, nr_segs, flags)
+syscall sys_getcpu nr 318 nbargs 3 types: (unsigned *, unsigned *, struct getcpu_cache *) args: (cpup, nodep, unused)
+syscall sys_epoll_pwait nr 319 nbargs 6 types: (int, struct epoll_event *, int, int, const sigset_t *, size_t) args: (epfd, events, maxevents, timeout, sigmask, sigsetsize)
+syscall sys_utimensat nr 320 nbargs 4 types: (int, const char *, struct timespec *, int) args: (dfd, filename, utimes, flags)
+syscall sys_signalfd nr 321 nbargs 3 types: (int, sigset_t *, size_t) args: (ufd, user_mask, sizemask)
+syscall sys_timerfd_create nr 322 nbargs 2 types: (int, int) args: (clockid, flags)
+syscall sys_eventfd nr 323 nbargs 1 types: (unsigned int) args: (count)
+syscall sys_timerfd_settime nr 325 nbargs 4 types: (int, int, const struct itimerspec *, struct itimerspec *) args: (ufd, flags, utmr, otmr)
+syscall sys_timerfd_gettime nr 326 nbargs 2 types: (int, struct itimerspec *) args: (ufd, otmr)
+syscall sys_signalfd4 nr 327 nbargs 4 types: (int, sigset_t *, size_t, int) args: (ufd, user_mask, sizemask, flags)
+syscall sys_eventfd2 nr 328 nbargs 2 types: (unsigned int, int) args: (count, flags)
+syscall sys_epoll_create1 nr 329 nbargs 1 types: (int) args: (flags)
+syscall sys_dup3 nr 330 nbargs 3 types: (unsigned int, unsigned int, int) args: (oldfd, newfd, flags)
+syscall sys_pipe2 nr 331 nbargs 2 types: (int *, int) args: (fildes, flags)
+syscall sys_inotify_init1 nr 332 nbargs 1 types: (int) args: (flags)
+syscall sys_preadv nr 333 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h)
+syscall sys_pwritev nr 334 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h)
+syscall sys_rt_tgsigqueueinfo nr 335 nbargs 4 types: (pid_t, pid_t, int, siginfo_t *) args: (tgid, pid, sig, uinfo)
+syscall sys_perf_event_open nr 336 nbargs 5 types: (struct perf_event_attr *, pid_t, int, int, unsigned long) args: (attr_uptr, pid, cpu, group_fd, flags)
+syscall sys_recvmmsg nr 337 nbargs 5 types: (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *) args: (fd, mmsg, vlen, flags, timeout)
+syscall sys_fanotify_init nr 338 nbargs 2 types: (unsigned int, unsigned int) args: (flags, event_f_flags)
+syscall sys_prlimit64 nr 340 nbargs 4 types: (pid_t, unsigned int, const struct rlimit64 *, struct rlimit64 *) args: (pid, resource, new_rlim, old_rlim)
+syscall sys_clock_adjtime nr 343 nbargs 2 types: (const clockid_t, struct timex *) args: (which_clock, utx)
+syscall sys_syncfs nr 344 nbargs 1 types: (int) args: (fd)
+syscall sys_sendmmsg nr 345 nbargs 4 types: (int, struct mmsghdr *, unsigned int, unsigned int) args: (fd, mmsg, vlen, flags)
+syscall sys_setns nr 346 nbargs 2 types: (int, int) args: (fd, nstype)
diff --git a/drivers/staging/lttng/instrumentation/syscalls/README b/drivers/staging/lttng/instrumentation/syscalls/README
new file mode 100644
index 0000000..6c235e1
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/README
@@ -0,0 +1,18 @@
+LTTng system call tracing
+
+1) lttng-syscall-extractor
+
+You need to build a kernel with CONFIG_FTRACE_SYSCALLS=y and
+CONFIG_KALLSYMS_ALL=y for extraction. Apply the linker patch to get your
+kernel to keep the system call metadata after boot.  Then build and load
+the LTTng syscall extractor module. The module will fail to load (this
+is expected). See the dmesg output for system call metadata.
+
+2) Generate system call TRACE_EVENT().
+
+Take the dmesg metadata and feed it to lttng-syscalls-generate-headers.sh, e.g.,
+from the instrumentation/syscalls directory. See the script header for
+usage example.
+
+After these are created, we just need to follow the new system call additions,
+no need to regenerate the whole thing, since system calls are only appended to.
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h
new file mode 100644
index 0000000..1c6e4f2
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h
@@ -0,0 +1,3 @@
+#ifdef CONFIG_X86_64
+//#include "x86-32-syscalls-3.1.0-rc6_integers.h"
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h
new file mode 100644
index 0000000..a84423c
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h
@@ -0,0 +1,3 @@
+#ifdef CONFIG_X86_64
+#include "x86-32-syscalls-3.1.0-rc6_pointers.h"
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h
new file mode 100644
index 0000000..a4a3b37
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h
@@ -0,0 +1,9 @@
+#include "syscalls_integers_override.h"
+
+#ifdef CONFIG_X86_64
+#include "x86-64-syscalls-3.0.4_integers.h"
+#endif
+
+#ifdef CONFIG_X86_32
+#include "x86-32-syscalls-3.1.0-rc6_integers.h"
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h
new file mode 100644
index 0000000..2d358bb
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h
@@ -0,0 +1,13 @@
+#define OVERRIDE_sys_mmap
+
+#ifndef CREATE_SYSCALL_TABLE
+
+SC_TRACE_EVENT(sys_mmap,
+	TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off),
+	TP_ARGS(addr, len, prot, flags, fd, off),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len) __field(int, prot) __field(int, flags) __field(int, fd) __field(off_t, offset)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(offset, off)),
+	TP_printk()
+)
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h
new file mode 100644
index 0000000..5f18034
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h
@@ -0,0 +1,9 @@
+#include "syscalls_pointers_override.h"
+
+#ifdef CONFIG_X86_64
+#include "x86-64-syscalls-3.0.4_pointers.h"
+#endif
+
+#ifdef CONFIG_X86_32
+#include "x86-32-syscalls-3.1.0-rc6_pointers.h"
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h
new file mode 100644
index 0000000..e69de29
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h
new file mode 100644
index 0000000..4582d03
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h
@@ -0,0 +1,55 @@
+#if !defined(_TRACE_SYSCALLS_UNKNOWN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_UNKNOWN_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+
+#define UNKNOWN_SYSCALL_NRARGS	6
+
+TRACE_EVENT(sys_unknown,
+	TP_PROTO(unsigned int id, unsigned long *args),
+	TP_ARGS(id, args),
+	TP_STRUCT__entry(
+		__field(unsigned int, id)
+		__array(unsigned long, args, UNKNOWN_SYSCALL_NRARGS)
+	),
+	TP_fast_assign(
+		tp_assign(id, id)
+		tp_memcpy(args, args, UNKNOWN_SYSCALL_NRARGS * sizeof(*args))
+	),
+	TP_printk()
+)
+TRACE_EVENT(compat_sys_unknown,
+	TP_PROTO(unsigned int id, unsigned long *args),
+	TP_ARGS(id, args),
+	TP_STRUCT__entry(
+		__field(unsigned int, id)
+		__array(unsigned long, args, UNKNOWN_SYSCALL_NRARGS)
+	),
+	TP_fast_assign(
+		tp_assign(id, id)
+		tp_memcpy(args, args, UNKNOWN_SYSCALL_NRARGS * sizeof(*args))
+	),
+	TP_printk()
+)
+/* 
+ * This is going to hook on sys_exit in the kernel.
+ * We change the name so we don't clash with the sys_exit syscall entry
+ * event.
+ */
+TRACE_EVENT(exit_syscall,
+	TP_PROTO(struct pt_regs *regs, long ret),
+	TP_ARGS(regs, ret),
+	TP_STRUCT__entry(
+		__field(long, ret)
+	),
+	TP_fast_assign(
+		tp_assign(ret, ret)
+	),
+	TP_printk()
+)
+
+#endif /*  _TRACE_SYSCALLS_UNKNOWN_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h
new file mode 100644
index 0000000..4825562
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h
@@ -0,0 +1,1161 @@
+/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */
+#ifndef CREATE_SYSCALL_TABLE
+
+#if !defined(_TRACE_SYSCALLS_INTEGERS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_INTEGERS_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+#include "x86-32-syscalls-3.1.0-rc6_integers_override.h"
+
+SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,
+	TP_STRUCT__entry(),
+	TP_fast_assign(),
+	TP_printk()
+)
+#ifndef OVERRIDE_sys_restart_syscall
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall)
+#endif
+#ifndef OVERRIDE_sys_getpid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid)
+#endif
+#ifndef OVERRIDE_sys_getuid16
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid16)
+#endif
+#ifndef OVERRIDE_sys_pause
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause)
+#endif
+#ifndef OVERRIDE_sys_sync
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync)
+#endif
+#ifndef OVERRIDE_sys_getgid16
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid16)
+#endif
+#ifndef OVERRIDE_sys_geteuid16
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid16)
+#endif
+#ifndef OVERRIDE_sys_getegid16
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid16)
+#endif
+#ifndef OVERRIDE_sys_getppid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid)
+#endif
+#ifndef OVERRIDE_sys_getpgrp
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp)
+#endif
+#ifndef OVERRIDE_sys_setsid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid)
+#endif
+#ifndef OVERRIDE_sys_sgetmask
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sgetmask)
+#endif
+#ifndef OVERRIDE_sys_vhangup
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup)
+#endif
+#ifndef OVERRIDE_sys_munlockall
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall)
+#endif
+#ifndef OVERRIDE_sys_sched_yield
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield)
+#endif
+#ifndef OVERRIDE_sys_getuid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid)
+#endif
+#ifndef OVERRIDE_sys_getgid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid)
+#endif
+#ifndef OVERRIDE_sys_geteuid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid)
+#endif
+#ifndef OVERRIDE_sys_getegid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid)
+#endif
+#ifndef OVERRIDE_sys_gettid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid)
+#endif
+#ifndef OVERRIDE_sys_inotify_init
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init)
+#endif
+#ifndef OVERRIDE_sys_exit
+SC_TRACE_EVENT(sys_exit,
+	TP_PROTO(int error_code),
+	TP_ARGS(error_code),
+	TP_STRUCT__entry(__field(int, error_code)),
+	TP_fast_assign(tp_assign(error_code, error_code)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_close
+SC_TRACE_EVENT(sys_close,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setuid16
+SC_TRACE_EVENT(sys_setuid16,
+	TP_PROTO(old_uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(old_uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_alarm
+SC_TRACE_EVENT(sys_alarm,
+	TP_PROTO(unsigned int seconds),
+	TP_ARGS(seconds),
+	TP_STRUCT__entry(__field(unsigned int, seconds)),
+	TP_fast_assign(tp_assign(seconds, seconds)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_nice
+SC_TRACE_EVENT(sys_nice,
+	TP_PROTO(int increment),
+	TP_ARGS(increment),
+	TP_STRUCT__entry(__field(int, increment)),
+	TP_fast_assign(tp_assign(increment, increment)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup
+SC_TRACE_EVENT(sys_dup,
+	TP_PROTO(unsigned int fildes),
+	TP_ARGS(fildes),
+	TP_STRUCT__entry(__field(unsigned int, fildes)),
+	TP_fast_assign(tp_assign(fildes, fildes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_brk
+SC_TRACE_EVENT(sys_brk,
+	TP_PROTO(unsigned long brk),
+	TP_ARGS(brk),
+	TP_STRUCT__entry(__field(unsigned long, brk)),
+	TP_fast_assign(tp_assign(brk, brk)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgid16
+SC_TRACE_EVENT(sys_setgid16,
+	TP_PROTO(old_gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(old_gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_umask
+SC_TRACE_EVENT(sys_umask,
+	TP_PROTO(int mask),
+	TP_ARGS(mask),
+	TP_STRUCT__entry(__field(int, mask)),
+	TP_fast_assign(tp_assign(mask, mask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ssetmask
+SC_TRACE_EVENT(sys_ssetmask,
+	TP_PROTO(int newmask),
+	TP_ARGS(newmask),
+	TP_STRUCT__entry(__field(int, newmask)),
+	TP_fast_assign(tp_assign(newmask, newmask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fsync
+SC_TRACE_EVENT(sys_fsync,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getpgid
+SC_TRACE_EVENT(sys_getpgid,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchdir
+SC_TRACE_EVENT(sys_fchdir,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_personality
+SC_TRACE_EVENT(sys_personality,
+	TP_PROTO(unsigned int personality),
+	TP_ARGS(personality),
+	TP_STRUCT__entry(__field(unsigned int, personality)),
+	TP_fast_assign(tp_assign(personality, personality)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsuid16
+SC_TRACE_EVENT(sys_setfsuid16,
+	TP_PROTO(old_uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(old_uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsgid16
+SC_TRACE_EVENT(sys_setfsgid16,
+	TP_PROTO(old_gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(old_gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getsid
+SC_TRACE_EVENT(sys_getsid,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fdatasync
+SC_TRACE_EVENT(sys_fdatasync,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mlockall
+SC_TRACE_EVENT(sys_mlockall,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getscheduler
+SC_TRACE_EVENT(sys_sched_getscheduler,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_get_priority_max
+SC_TRACE_EVENT(sys_sched_get_priority_max,
+	TP_PROTO(int policy),
+	TP_ARGS(policy),
+	TP_STRUCT__entry(__field(int, policy)),
+	TP_fast_assign(tp_assign(policy, policy)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_get_priority_min
+SC_TRACE_EVENT(sys_sched_get_priority_min,
+	TP_PROTO(int policy),
+	TP_ARGS(policy),
+	TP_STRUCT__entry(__field(int, policy)),
+	TP_fast_assign(tp_assign(policy, policy)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setuid
+SC_TRACE_EVENT(sys_setuid,
+	TP_PROTO(uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgid
+SC_TRACE_EVENT(sys_setgid,
+	TP_PROTO(gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsuid
+SC_TRACE_EVENT(sys_setfsuid,
+	TP_PROTO(uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsgid
+SC_TRACE_EVENT(sys_setfsgid,
+	TP_PROTO(gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_destroy
+SC_TRACE_EVENT(sys_io_destroy,
+	TP_PROTO(aio_context_t ctx),
+	TP_ARGS(ctx),
+	TP_STRUCT__entry(__field(aio_context_t, ctx)),
+	TP_fast_assign(tp_assign(ctx, ctx)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_exit_group
+SC_TRACE_EVENT(sys_exit_group,
+	TP_PROTO(int error_code),
+	TP_ARGS(error_code),
+	TP_STRUCT__entry(__field(int, error_code)),
+	TP_fast_assign(tp_assign(error_code, error_code)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_create
+SC_TRACE_EVENT(sys_epoll_create,
+	TP_PROTO(int size),
+	TP_ARGS(size),
+	TP_STRUCT__entry(__field(int, size)),
+	TP_fast_assign(tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_getoverrun
+SC_TRACE_EVENT(sys_timer_getoverrun,
+	TP_PROTO(timer_t timer_id),
+	TP_ARGS(timer_id),
+	TP_STRUCT__entry(__field(timer_t, timer_id)),
+	TP_fast_assign(tp_assign(timer_id, timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_delete
+SC_TRACE_EVENT(sys_timer_delete,
+	TP_PROTO(timer_t timer_id),
+	TP_ARGS(timer_id),
+	TP_STRUCT__entry(__field(timer_t, timer_id)),
+	TP_fast_assign(tp_assign(timer_id, timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_unshare
+SC_TRACE_EVENT(sys_unshare,
+	TP_PROTO(unsigned long unshare_flags),
+	TP_ARGS(unshare_flags),
+	TP_STRUCT__entry(__field(unsigned long, unshare_flags)),
+	TP_fast_assign(tp_assign(unshare_flags, unshare_flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_eventfd
+SC_TRACE_EVENT(sys_eventfd,
+	TP_PROTO(unsigned int count),
+	TP_ARGS(count),
+	TP_STRUCT__entry(__field(unsigned int, count)),
+	TP_fast_assign(tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_create1
+SC_TRACE_EVENT(sys_epoll_create1,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_init1
+SC_TRACE_EVENT(sys_inotify_init1,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_syncfs
+SC_TRACE_EVENT(sys_syncfs,
+	TP_PROTO(int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_kill
+SC_TRACE_EVENT(sys_kill,
+	TP_PROTO(pid_t pid, int sig),
+	TP_ARGS(pid, sig),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_signal
+SC_TRACE_EVENT(sys_signal,
+	TP_PROTO(int sig, __sighandler_t handler),
+	TP_ARGS(sig, handler),
+	TP_STRUCT__entry(__field(int, sig) __field(__sighandler_t, handler)),
+	TP_fast_assign(tp_assign(sig, sig) tp_assign(handler, handler)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setpgid
+SC_TRACE_EVENT(sys_setpgid,
+	TP_PROTO(pid_t pid, pid_t pgid),
+	TP_ARGS(pid, pgid),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(pid_t, pgid)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(pgid, pgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup2
+SC_TRACE_EVENT(sys_dup2,
+	TP_PROTO(unsigned int oldfd, unsigned int newfd),
+	TP_ARGS(oldfd, newfd),
+	TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd)),
+	TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setreuid16
+SC_TRACE_EVENT(sys_setreuid16,
+	TP_PROTO(old_uid_t ruid, old_uid_t euid),
+	TP_ARGS(ruid, euid),
+	TP_STRUCT__entry(__field(old_uid_t, ruid) __field(old_uid_t, euid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setregid16
+SC_TRACE_EVENT(sys_setregid16,
+	TP_PROTO(old_gid_t rgid, old_gid_t egid),
+	TP_ARGS(rgid, egid),
+	TP_STRUCT__entry(__field(old_gid_t, rgid) __field(old_gid_t, egid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_munmap
+SC_TRACE_EVENT(sys_munmap,
+	TP_PROTO(unsigned long addr, size_t len),
+	TP_ARGS(addr, len),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ftruncate
+SC_TRACE_EVENT(sys_ftruncate,
+	TP_PROTO(unsigned int fd, unsigned long length),
+	TP_ARGS(fd, length),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, length)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(length, length)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchmod
+SC_TRACE_EVENT(sys_fchmod,
+	TP_PROTO(unsigned int fd, mode_t mode),
+	TP_ARGS(fd, mode),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(mode_t, mode)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getpriority
+SC_TRACE_EVENT(sys_getpriority,
+	TP_PROTO(int which, int who),
+	TP_ARGS(which, who),
+	TP_STRUCT__entry(__field(int, which) __field(int, who)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_bdflush
+SC_TRACE_EVENT(sys_bdflush,
+	TP_PROTO(int func, long data),
+	TP_ARGS(func, data),
+	TP_STRUCT__entry(__field(int, func) __field(long, data)),
+	TP_fast_assign(tp_assign(func, func) tp_assign(data, data)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_flock
+SC_TRACE_EVENT(sys_flock,
+	TP_PROTO(unsigned int fd, unsigned int cmd),
+	TP_ARGS(fd, cmd),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mlock
+SC_TRACE_EVENT(sys_mlock,
+	TP_PROTO(unsigned long start, size_t len),
+	TP_ARGS(start, len),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_munlock
+SC_TRACE_EVENT(sys_munlock,
+	TP_PROTO(unsigned long start, size_t len),
+	TP_ARGS(start, len),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setreuid
+SC_TRACE_EVENT(sys_setreuid,
+	TP_PROTO(uid_t ruid, uid_t euid),
+	TP_ARGS(ruid, euid),
+	TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setregid
+SC_TRACE_EVENT(sys_setregid,
+	TP_PROTO(gid_t rgid, gid_t egid),
+	TP_ARGS(rgid, egid),
+	TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tkill
+SC_TRACE_EVENT(sys_tkill,
+	TP_PROTO(pid_t pid, int sig),
+	TP_ARGS(pid, sig),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioprio_get
+SC_TRACE_EVENT(sys_ioprio_get,
+	TP_PROTO(int which, int who),
+	TP_ARGS(which, who),
+	TP_STRUCT__entry(__field(int, which) __field(int, who)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_rm_watch
+SC_TRACE_EVENT(sys_inotify_rm_watch,
+	TP_PROTO(int fd, __s32 wd),
+	TP_ARGS(fd, wd),
+	TP_STRUCT__entry(__field(int, fd) __field(__s32, wd)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(wd, wd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_create
+SC_TRACE_EVENT(sys_timerfd_create,
+	TP_PROTO(int clockid, int flags),
+	TP_ARGS(clockid, flags),
+	TP_STRUCT__entry(__field(int, clockid) __field(int, flags)),
+	TP_fast_assign(tp_assign(clockid, clockid) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_eventfd2
+SC_TRACE_EVENT(sys_eventfd2,
+	TP_PROTO(unsigned int count, int flags),
+	TP_ARGS(count, flags),
+	TP_STRUCT__entry(__field(unsigned int, count) __field(int, flags)),
+	TP_fast_assign(tp_assign(count, count) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fanotify_init
+SC_TRACE_EVENT(sys_fanotify_init,
+	TP_PROTO(unsigned int flags, unsigned int event_f_flags),
+	TP_ARGS(flags, event_f_flags),
+	TP_STRUCT__entry(__field(unsigned int, flags) __field(unsigned int, event_f_flags)),
+	TP_fast_assign(tp_assign(flags, flags) tp_assign(event_f_flags, event_f_flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setns
+SC_TRACE_EVENT(sys_setns,
+	TP_PROTO(int fd, int nstype),
+	TP_ARGS(fd, nstype),
+	TP_STRUCT__entry(__field(int, fd) __field(int, nstype)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(nstype, nstype)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lseek
+SC_TRACE_EVENT(sys_lseek,
+	TP_PROTO(unsigned int fd, off_t offset, unsigned int origin),
+	TP_ARGS(fd, offset, origin),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(off_t, offset) __field(unsigned int, origin)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(offset, offset) tp_assign(origin, origin)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioctl
+SC_TRACE_EVENT(sys_ioctl,
+	TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg),
+	TP_ARGS(fd, cmd, arg),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fcntl
+SC_TRACE_EVENT(sys_fcntl,
+	TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg),
+	TP_ARGS(fd, cmd, arg),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchown16
+SC_TRACE_EVENT(sys_fchown16,
+	TP_PROTO(unsigned int fd, old_uid_t user, old_gid_t group),
+	TP_ARGS(fd, user, group),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(old_uid_t, user) __field(old_gid_t, group)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setpriority
+SC_TRACE_EVENT(sys_setpriority,
+	TP_PROTO(int which, int who, int niceval),
+	TP_ARGS(which, who, niceval),
+	TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, niceval)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(niceval, niceval)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mprotect
+SC_TRACE_EVENT(sys_mprotect,
+	TP_PROTO(unsigned long start, size_t len, unsigned long prot),
+	TP_ARGS(start, len, prot),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(unsigned long, prot)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(prot, prot)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysfs
+SC_TRACE_EVENT(sys_sysfs,
+	TP_PROTO(int option, unsigned long arg1, unsigned long arg2),
+	TP_ARGS(option, arg1, arg2),
+	TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg1) __field(unsigned long, arg2)),
+	TP_fast_assign(tp_assign(option, option) tp_assign(arg1, arg1) tp_assign(arg2, arg2)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msync
+SC_TRACE_EVENT(sys_msync,
+	TP_PROTO(unsigned long start, size_t len, int flags),
+	TP_ARGS(start, len, flags),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(int, flags)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresuid16
+SC_TRACE_EVENT(sys_setresuid16,
+	TP_PROTO(old_uid_t ruid, old_uid_t euid, old_uid_t suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field(old_uid_t, ruid) __field(old_uid_t, euid) __field(old_uid_t, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresgid16
+SC_TRACE_EVENT(sys_setresgid16,
+	TP_PROTO(old_gid_t rgid, old_gid_t egid, old_gid_t sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field(old_gid_t, rgid) __field(old_gid_t, egid) __field(old_gid_t, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchown
+SC_TRACE_EVENT(sys_fchown,
+	TP_PROTO(unsigned int fd, uid_t user, gid_t group),
+	TP_ARGS(fd, user, group),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresuid
+SC_TRACE_EVENT(sys_setresuid,
+	TP_PROTO(uid_t ruid, uid_t euid, uid_t suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid) __field(uid_t, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresgid
+SC_TRACE_EVENT(sys_setresgid,
+	TP_PROTO(gid_t rgid, gid_t egid, gid_t sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid) __field(gid_t, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_madvise
+SC_TRACE_EVENT(sys_madvise,
+	TP_PROTO(unsigned long start, size_t len_in, int behavior),
+	TP_ARGS(start, len_in, behavior),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len_in) __field(int, behavior)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len_in, len_in) tp_assign(behavior, behavior)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fcntl64
+SC_TRACE_EVENT(sys_fcntl64,
+	TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg),
+	TP_ARGS(fd, cmd, arg),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tgkill
+SC_TRACE_EVENT(sys_tgkill,
+	TP_PROTO(pid_t tgid, pid_t pid, int sig),
+	TP_ARGS(tgid, pid, sig),
+	TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioprio_set
+SC_TRACE_EVENT(sys_ioprio_set,
+	TP_PROTO(int which, int who, int ioprio),
+	TP_ARGS(which, who, ioprio),
+	TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, ioprio)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(ioprio, ioprio)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup3
+SC_TRACE_EVENT(sys_dup3,
+	TP_PROTO(unsigned int oldfd, unsigned int newfd, int flags),
+	TP_ARGS(oldfd, newfd, flags),
+	TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd) __field(int, flags)),
+	TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ptrace
+SC_TRACE_EVENT(sys_ptrace,
+	TP_PROTO(long request, long pid, unsigned long addr, unsigned long data),
+	TP_ARGS(request, pid, addr, data),
+	TP_STRUCT__entry(__field(long, request) __field(long, pid) __field_hex(unsigned long, addr) __field(unsigned long, data)),
+	TP_fast_assign(tp_assign(request, request) tp_assign(pid, pid) tp_assign(addr, addr) tp_assign(data, data)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tee
+SC_TRACE_EVENT(sys_tee,
+	TP_PROTO(int fdin, int fdout, size_t len, unsigned int flags),
+	TP_ARGS(fdin, fdout, len, flags),
+	TP_STRUCT__entry(__field(int, fdin) __field(int, fdout) __field(size_t, len) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fdin, fdin) tp_assign(fdout, fdout) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mremap
+SC_TRACE_EVENT(sys_mremap,
+	TP_PROTO(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr),
+	TP_ARGS(addr, old_len, new_len, flags, new_addr),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, old_len) __field(unsigned long, new_len) __field(unsigned long, flags) __field_hex(unsigned long, new_addr)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(old_len, old_len) tp_assign(new_len, new_len) tp_assign(flags, flags) tp_assign(new_addr, new_addr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_prctl
+SC_TRACE_EVENT(sys_prctl,
+	TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5),
+	TP_ARGS(option, arg2, arg3, arg4, arg5),
+	TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)),
+	TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_remap_file_pages
+SC_TRACE_EVENT(sys_remap_file_pages,
+	TP_PROTO(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags),
+	TP_ARGS(start, size, prot, pgoff, flags),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, size) __field(unsigned long, prot) __field(unsigned long, pgoff) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(size, size) tp_assign(prot, prot) tp_assign(pgoff, pgoff) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_keyctl
+SC_TRACE_EVENT(sys_keyctl,
+	TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5),
+	TP_ARGS(option, arg2, arg3, arg4, arg5),
+	TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)),
+	TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mmap_pgoff
+SC_TRACE_EVENT(sys_mmap_pgoff,
+	TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff),
+	TP_ARGS(addr, len, prot, flags, fd, pgoff),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, prot) __field(unsigned long, flags) __field(unsigned long, fd) __field(unsigned long, pgoff)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(pgoff, pgoff)),
+	TP_printk()
+)
+#endif
+
+#endif /*  _TRACE_SYSCALLS_INTEGERS_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
+#else /* CREATE_SYSCALL_TABLE */
+
+#include "x86-32-syscalls-3.1.0-rc6_integers_override.h"
+
+#ifndef OVERRIDE_TABLE_sys_restart_syscall
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 0, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 20, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getuid16
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid16, 24, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pause
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 29, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sync
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 36, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgid16
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid16, 47, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_geteuid16
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid16, 49, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getegid16
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid16, 50, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getppid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 64, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpgrp
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 65, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setsid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 66, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sgetmask
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sgetmask, 68, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_vhangup
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 111, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munlockall
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 153, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_yield
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 158, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getuid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 199, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 200, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_geteuid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 201, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getegid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 202, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_gettid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 224, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_init
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 291, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_exit
+TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 1, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_close
+TRACE_SYSCALL_TABLE(sys_close, sys_close, 6, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lseek
+TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 19, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setuid16
+TRACE_SYSCALL_TABLE(sys_setuid16, sys_setuid16, 23, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ptrace
+TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 26, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_alarm
+TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 27, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_nice
+TRACE_SYSCALL_TABLE(sys_nice, sys_nice, 34, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_kill
+TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 37, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup
+TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 41, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_brk
+TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 45, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgid16
+TRACE_SYSCALL_TABLE(sys_setgid16, sys_setgid16, 46, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_signal
+TRACE_SYSCALL_TABLE(sys_signal, sys_signal, 48, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioctl
+TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 54, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fcntl
+TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 55, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setpgid
+TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 57, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_umask
+TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 60, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup2
+TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 63, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ssetmask
+TRACE_SYSCALL_TABLE(sys_ssetmask, sys_ssetmask, 69, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setreuid16
+TRACE_SYSCALL_TABLE(sys_setreuid16, sys_setreuid16, 70, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setregid16
+TRACE_SYSCALL_TABLE(sys_setregid16, sys_setregid16, 71, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munmap
+TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 91, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ftruncate
+TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 93, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchmod
+TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 94, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchown16
+TRACE_SYSCALL_TABLE(sys_fchown16, sys_fchown16, 95, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpriority
+TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 96, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setpriority
+TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 97, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fsync
+TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 118, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mprotect
+TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 125, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpgid
+TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 132, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchdir
+TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 133, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_bdflush
+TRACE_SYSCALL_TABLE(sys_bdflush, sys_bdflush, 134, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysfs
+TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 135, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_personality
+TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 136, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsuid16
+TRACE_SYSCALL_TABLE(sys_setfsuid16, sys_setfsuid16, 138, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsgid16
+TRACE_SYSCALL_TABLE(sys_setfsgid16, sys_setfsgid16, 139, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_flock
+TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 143, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msync
+TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 144, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getsid
+TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 147, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fdatasync
+TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 148, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mlock
+TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 150, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munlock
+TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 151, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mlockall
+TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 152, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getscheduler
+TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 157, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_get_priority_max
+TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 159, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_get_priority_min
+TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 160, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mremap
+TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 163, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresuid16
+TRACE_SYSCALL_TABLE(sys_setresuid16, sys_setresuid16, 164, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresgid16
+TRACE_SYSCALL_TABLE(sys_setresgid16, sys_setresgid16, 170, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_prctl
+TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 172, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mmap_pgoff
+TRACE_SYSCALL_TABLE(sys_mmap_pgoff, sys_mmap_pgoff, 192, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setreuid
+TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 203, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setregid
+TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 204, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchown
+TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 207, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresuid
+TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 208, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresgid
+TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 210, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setuid
+TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 213, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgid
+TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 214, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsuid
+TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 215, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsgid
+TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 216, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_madvise
+TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 219, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fcntl64
+TRACE_SYSCALL_TABLE(sys_fcntl64, sys_fcntl64, 221, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tkill
+TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 238, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_destroy
+TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 246, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_exit_group
+TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 252, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_create
+TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 254, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_remap_file_pages
+TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 257, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_getoverrun
+TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 262, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_delete
+TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 263, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tgkill
+TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 270, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_keyctl
+TRACE_SYSCALL_TABLE(sys_keyctl, sys_keyctl, 288, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioprio_set
+TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 289, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioprio_get
+TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 290, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_rm_watch
+TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 293, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unshare
+TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 310, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tee
+TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 315, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_create
+TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 322, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_eventfd
+TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 323, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_eventfd2
+TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 328, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_create1
+TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 329, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup3
+TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 330, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_init1
+TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 332, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fanotify_init
+TRACE_SYSCALL_TABLE(sys_fanotify_init, sys_fanotify_init, 338, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_syncfs
+TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 344, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setns
+TRACE_SYSCALL_TABLE(sys_setns, sys_setns, 346, 2)
+#endif
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h
new file mode 100644
index 0000000..02a83da
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h
@@ -0,0 +1,38 @@
+#ifndef CONFIG_UID16
+
+#define OVERRIDE_sys_getuid16
+#define OVERRIDE_sys_getgid16
+#define OVERRIDE_sys_geteuid16
+#define OVERRIDE_sys_getegid16
+#define OVERRIDE_sys_setuid16
+#define OVERRIDE_sys_setgid16
+#define OVERRIDE_sys_setfsuid16
+#define OVERRIDE_sys_setfsgid16
+#define OVERRIDE_sys_setreuid16
+#define OVERRIDE_sys_setregid16
+#define OVERRIDE_sys_fchown16
+#define OVERRIDE_sys_setresuid16
+#define OVERRIDE_sys_setresgid16
+
+#define OVERRIDE_TABLE_sys_getuid16
+#define OVERRIDE_TABLE_sys_getgid16
+#define OVERRIDE_TABLE_sys_geteuid16
+#define OVERRIDE_TABLE_sys_getegid16
+#define OVERRIDE_TABLE_sys_setuid16
+#define OVERRIDE_TABLE_sys_setgid16
+#define OVERRIDE_TABLE_sys_setreuid16
+#define OVERRIDE_TABLE_sys_setregid16
+#define OVERRIDE_TABLE_sys_fchown16
+#define OVERRIDE_TABLE_sys_setfsuid16
+#define OVERRIDE_TABLE_sys_setfsgid16
+#define OVERRIDE_TABLE_sys_setresuid16
+#define OVERRIDE_TABLE_sys_setresgid16
+
+#endif
+
+#ifdef CREATE_SYSCALL_TABLE
+
+#define OVERRIDE_TABLE_sys_mmap
+TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 90, 6)
+
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h
new file mode 100644
index 0000000..40d5530
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h
@@ -0,0 +1,2230 @@
+/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */
+#ifndef CREATE_SYSCALL_TABLE
+
+#if !defined(_TRACE_SYSCALLS_POINTERS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_POINTERS_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+#include "x86-32-syscalls-3.1.0-rc6_pointers_override.h"
+
+#ifndef OVERRIDE_sys_unlink
+SC_TRACE_EVENT(sys_unlink,
+	TP_PROTO(const char * pathname),
+	TP_ARGS(pathname),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chdir
+SC_TRACE_EVENT(sys_chdir,
+	TP_PROTO(const char * filename),
+	TP_ARGS(filename),
+	TP_STRUCT__entry(__string_from_user(filename, filename)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_time
+SC_TRACE_EVENT(sys_time,
+	TP_PROTO(time_t * tloc),
+	TP_ARGS(tloc),
+	TP_STRUCT__entry(__field_hex(time_t *, tloc)),
+	TP_fast_assign(tp_assign(tloc, tloc)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_oldumount
+SC_TRACE_EVENT(sys_oldumount,
+	TP_PROTO(char * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_stime
+SC_TRACE_EVENT(sys_stime,
+	TP_PROTO(time_t * tptr),
+	TP_ARGS(tptr),
+	TP_STRUCT__entry(__field_hex(time_t *, tptr)),
+	TP_fast_assign(tp_assign(tptr, tptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rmdir
+SC_TRACE_EVENT(sys_rmdir,
+	TP_PROTO(const char * pathname),
+	TP_ARGS(pathname),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pipe
+SC_TRACE_EVENT(sys_pipe,
+	TP_PROTO(int * fildes),
+	TP_ARGS(fildes),
+	TP_STRUCT__entry(__field_hex(int *, fildes)),
+	TP_fast_assign(tp_assign(fildes, fildes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_times
+SC_TRACE_EVENT(sys_times,
+	TP_PROTO(struct tms * tbuf),
+	TP_ARGS(tbuf),
+	TP_STRUCT__entry(__field_hex(struct tms *, tbuf)),
+	TP_fast_assign(tp_assign(tbuf, tbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_acct
+SC_TRACE_EVENT(sys_acct,
+	TP_PROTO(const char * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_olduname
+SC_TRACE_EVENT(sys_olduname,
+	TP_PROTO(struct oldold_utsname * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__field_hex(struct oldold_utsname *, name)),
+	TP_fast_assign(tp_assign(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chroot
+SC_TRACE_EVENT(sys_chroot,
+	TP_PROTO(const char * filename),
+	TP_ARGS(filename),
+	TP_STRUCT__entry(__string_from_user(filename, filename)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sigpending
+SC_TRACE_EVENT(sys_sigpending,
+	TP_PROTO(old_sigset_t * set),
+	TP_ARGS(set),
+	TP_STRUCT__entry(__field_hex(old_sigset_t *, set)),
+	TP_fast_assign(tp_assign(set, set)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_old_select
+SC_TRACE_EVENT(sys_old_select,
+	TP_PROTO(struct sel_arg_struct * arg),
+	TP_ARGS(arg),
+	TP_STRUCT__entry(__field_hex(struct sel_arg_struct *, arg)),
+	TP_fast_assign(tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_uselib
+SC_TRACE_EVENT(sys_uselib,
+	TP_PROTO(const char * library),
+	TP_ARGS(library),
+	TP_STRUCT__entry(__field_hex(const char *, library)),
+	TP_fast_assign(tp_assign(library, library)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_old_mmap
+SC_TRACE_EVENT(sys_old_mmap,
+	TP_PROTO(struct mmap_arg_struct * arg),
+	TP_ARGS(arg),
+	TP_STRUCT__entry(__field_hex(struct mmap_arg_struct *, arg)),
+	TP_fast_assign(tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_uname
+SC_TRACE_EVENT(sys_uname,
+	TP_PROTO(struct old_utsname * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__field_hex(struct old_utsname *, name)),
+	TP_fast_assign(tp_assign(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_swapoff
+SC_TRACE_EVENT(sys_swapoff,
+	TP_PROTO(const char * specialfile),
+	TP_ARGS(specialfile),
+	TP_STRUCT__entry(__string_from_user(specialfile, specialfile)),
+	TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysinfo
+SC_TRACE_EVENT(sys_sysinfo,
+	TP_PROTO(struct sysinfo * info),
+	TP_ARGS(info),
+	TP_STRUCT__entry(__field_hex(struct sysinfo *, info)),
+	TP_fast_assign(tp_assign(info, info)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newuname
+SC_TRACE_EVENT(sys_newuname,
+	TP_PROTO(struct new_utsname * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__field_hex(struct new_utsname *, name)),
+	TP_fast_assign(tp_assign(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_adjtimex
+SC_TRACE_EVENT(sys_adjtimex,
+	TP_PROTO(struct timex * txc_p),
+	TP_ARGS(txc_p),
+	TP_STRUCT__entry(__field_hex(struct timex *, txc_p)),
+	TP_fast_assign(tp_assign(txc_p, txc_p)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysctl
+SC_TRACE_EVENT(sys_sysctl,
+	TP_PROTO(struct __sysctl_args * args),
+	TP_ARGS(args),
+	TP_STRUCT__entry(__field_hex(struct __sysctl_args *, args)),
+	TP_fast_assign(tp_assign(args, args)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_set_tid_address
+SC_TRACE_EVENT(sys_set_tid_address,
+	TP_PROTO(int * tidptr),
+	TP_ARGS(tidptr),
+	TP_STRUCT__entry(__field_hex(int *, tidptr)),
+	TP_fast_assign(tp_assign(tidptr, tidptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_unlink
+SC_TRACE_EVENT(sys_mq_unlink,
+	TP_PROTO(const char * u_name),
+	TP_ARGS(u_name),
+	TP_STRUCT__entry(__string_from_user(u_name, u_name)),
+	TP_fast_assign(tp_copy_string_from_user(u_name, u_name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_creat
+SC_TRACE_EVENT(sys_creat,
+	TP_PROTO(const char * pathname, int mode),
+	TP_ARGS(pathname, mode),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_link
+SC_TRACE_EVENT(sys_link,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chmod
+SC_TRACE_EVENT(sys_chmod,
+	TP_PROTO(const char * filename, mode_t mode),
+	TP_ARGS(filename, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(mode_t, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_stat
+SC_TRACE_EVENT(sys_stat,
+	TP_PROTO(const char * filename, struct __old_kernel_stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct __old_kernel_stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstat
+SC_TRACE_EVENT(sys_fstat,
+	TP_PROTO(unsigned int fd, struct __old_kernel_stat * statbuf),
+	TP_ARGS(fd, statbuf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct __old_kernel_stat *, statbuf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utime
+SC_TRACE_EVENT(sys_utime,
+	TP_PROTO(char * filename, struct utimbuf * times),
+	TP_ARGS(filename, times),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct utimbuf *, times)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(times, times)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_access
+SC_TRACE_EVENT(sys_access,
+	TP_PROTO(const char * filename, int mode),
+	TP_ARGS(filename, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rename
+SC_TRACE_EVENT(sys_rename,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mkdir
+SC_TRACE_EVENT(sys_mkdir,
+	TP_PROTO(const char * pathname, int mode),
+	TP_ARGS(pathname, mode),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_umount
+SC_TRACE_EVENT(sys_umount,
+	TP_PROTO(char * name, int flags),
+	TP_ARGS(name, flags),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ustat
+SC_TRACE_EVENT(sys_ustat,
+	TP_PROTO(unsigned dev, struct ustat * ubuf),
+	TP_ARGS(dev, ubuf),
+	TP_STRUCT__entry(__field(unsigned, dev) __field_hex(struct ustat *, ubuf)),
+	TP_fast_assign(tp_assign(dev, dev) tp_assign(ubuf, ubuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sethostname
+SC_TRACE_EVENT(sys_sethostname,
+	TP_PROTO(char * name, int len),
+	TP_ARGS(name, len),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setrlimit
+SC_TRACE_EVENT(sys_setrlimit,
+	TP_PROTO(unsigned int resource, struct rlimit * rlim),
+	TP_ARGS(resource, rlim),
+	TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)),
+	TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_old_getrlimit
+SC_TRACE_EVENT(sys_old_getrlimit,
+	TP_PROTO(unsigned int resource, struct rlimit * rlim),
+	TP_ARGS(resource, rlim),
+	TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)),
+	TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getrusage
+SC_TRACE_EVENT(sys_getrusage,
+	TP_PROTO(int who, struct rusage * ru),
+	TP_ARGS(who, ru),
+	TP_STRUCT__entry(__field(int, who) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(who, who) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_gettimeofday
+SC_TRACE_EVENT(sys_gettimeofday,
+	TP_PROTO(struct timeval * tv, struct timezone * tz),
+	TP_ARGS(tv, tz),
+	TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)),
+	TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_settimeofday
+SC_TRACE_EVENT(sys_settimeofday,
+	TP_PROTO(struct timeval * tv, struct timezone * tz),
+	TP_ARGS(tv, tz),
+	TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)),
+	TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getgroups16
+SC_TRACE_EVENT(sys_getgroups16,
+	TP_PROTO(int gidsetsize, old_gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(old_gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgroups16
+SC_TRACE_EVENT(sys_setgroups16,
+	TP_PROTO(int gidsetsize, old_gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(old_gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_symlink
+SC_TRACE_EVENT(sys_symlink,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lstat
+SC_TRACE_EVENT(sys_lstat,
+	TP_PROTO(const char * filename, struct __old_kernel_stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct __old_kernel_stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_swapon
+SC_TRACE_EVENT(sys_swapon,
+	TP_PROTO(const char * specialfile, int swap_flags),
+	TP_ARGS(specialfile, swap_flags),
+	TP_STRUCT__entry(__string_from_user(specialfile, specialfile) __field(int, swap_flags)),
+	TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile) tp_assign(swap_flags, swap_flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_truncate
+SC_TRACE_EVENT(sys_truncate,
+	TP_PROTO(const char * path, long length),
+	TP_ARGS(path, length),
+	TP_STRUCT__entry(__string_from_user(path, path) __field(long, length)),
+	TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(length, length)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_statfs
+SC_TRACE_EVENT(sys_statfs,
+	TP_PROTO(const char * pathname, struct statfs * buf),
+	TP_ARGS(pathname, buf),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(struct statfs *, buf)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstatfs
+SC_TRACE_EVENT(sys_fstatfs,
+	TP_PROTO(unsigned int fd, struct statfs * buf),
+	TP_ARGS(fd, buf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct statfs *, buf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_socketcall
+SC_TRACE_EVENT(sys_socketcall,
+	TP_PROTO(int call, unsigned long * args),
+	TP_ARGS(call, args),
+	TP_STRUCT__entry(__field(int, call) __field_hex(unsigned long *, args)),
+	TP_fast_assign(tp_assign(call, call) tp_assign(args, args)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getitimer
+SC_TRACE_EVENT(sys_getitimer,
+	TP_PROTO(int which, struct itimerval * value),
+	TP_ARGS(which, value),
+	TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(value, value)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newstat
+SC_TRACE_EVENT(sys_newstat,
+	TP_PROTO(const char * filename, struct stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newlstat
+SC_TRACE_EVENT(sys_newlstat,
+	TP_PROTO(const char * filename, struct stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newfstat
+SC_TRACE_EVENT(sys_newfstat,
+	TP_PROTO(unsigned int fd, struct stat * statbuf),
+	TP_ARGS(fd, statbuf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setdomainname
+SC_TRACE_EVENT(sys_setdomainname,
+	TP_PROTO(char * name, int len),
+	TP_ARGS(name, len),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_delete_module
+SC_TRACE_EVENT(sys_delete_module,
+	TP_PROTO(const char * name_user, unsigned int flags),
+	TP_ARGS(name_user, flags),
+	TP_STRUCT__entry(__string_from_user(name_user, name_user) __field(unsigned int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(name_user, name_user) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setparam
+SC_TRACE_EVENT(sys_sched_setparam,
+	TP_PROTO(pid_t pid, struct sched_param * param),
+	TP_ARGS(pid, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getparam
+SC_TRACE_EVENT(sys_sched_getparam,
+	TP_PROTO(pid_t pid, struct sched_param * param),
+	TP_ARGS(pid, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_rr_get_interval
+SC_TRACE_EVENT(sys_sched_rr_get_interval,
+	TP_PROTO(pid_t pid, struct timespec * interval),
+	TP_ARGS(pid, interval),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct timespec *, interval)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(interval, interval)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_nanosleep
+SC_TRACE_EVENT(sys_nanosleep,
+	TP_PROTO(struct timespec * rqtp, struct timespec * rmtp),
+	TP_ARGS(rqtp, rmtp),
+	TP_STRUCT__entry(__field_hex(struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)),
+	TP_fast_assign(tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigpending
+SC_TRACE_EVENT(sys_rt_sigpending,
+	TP_PROTO(sigset_t * set, size_t sigsetsize),
+	TP_ARGS(set, sigsetsize),
+	TP_STRUCT__entry(__field_hex(sigset_t *, set) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(set, set) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigsuspend
+SC_TRACE_EVENT(sys_rt_sigsuspend,
+	TP_PROTO(sigset_t * unewset, size_t sigsetsize),
+	TP_ARGS(unewset, sigsetsize),
+	TP_STRUCT__entry(__field_hex(sigset_t *, unewset) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(unewset, unewset) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getcwd
+SC_TRACE_EVENT(sys_getcwd,
+	TP_PROTO(char * buf, unsigned long size),
+	TP_ARGS(buf, size),
+	TP_STRUCT__entry(__field_hex(char *, buf) __field(unsigned long, size)),
+	TP_fast_assign(tp_assign(buf, buf) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getrlimit
+SC_TRACE_EVENT(sys_getrlimit,
+	TP_PROTO(unsigned int resource, struct rlimit * rlim),
+	TP_ARGS(resource, rlim),
+	TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)),
+	TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_stat64
+SC_TRACE_EVENT(sys_stat64,
+	TP_PROTO(const char * filename, struct stat64 * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lstat64
+SC_TRACE_EVENT(sys_lstat64,
+	TP_PROTO(const char * filename, struct stat64 * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstat64
+SC_TRACE_EVENT(sys_fstat64,
+	TP_PROTO(unsigned long fd, struct stat64 * statbuf),
+	TP_ARGS(fd, statbuf),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(struct stat64 *, statbuf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getgroups
+SC_TRACE_EVENT(sys_getgroups,
+	TP_PROTO(int gidsetsize, gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgroups
+SC_TRACE_EVENT(sys_setgroups,
+	TP_PROTO(int gidsetsize, gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pivot_root
+SC_TRACE_EVENT(sys_pivot_root,
+	TP_PROTO(const char * new_root, const char * put_old),
+	TP_ARGS(new_root, put_old),
+	TP_STRUCT__entry(__string_from_user(new_root, new_root) __string_from_user(put_old, put_old)),
+	TP_fast_assign(tp_copy_string_from_user(new_root, new_root) tp_copy_string_from_user(put_old, put_old)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_removexattr
+SC_TRACE_EVENT(sys_removexattr,
+	TP_PROTO(const char * pathname, const char * name),
+	TP_ARGS(pathname, name),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lremovexattr
+SC_TRACE_EVENT(sys_lremovexattr,
+	TP_PROTO(const char * pathname, const char * name),
+	TP_ARGS(pathname, name),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fremovexattr
+SC_TRACE_EVENT(sys_fremovexattr,
+	TP_PROTO(int fd, const char * name),
+	TP_ARGS(fd, name),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_setup
+SC_TRACE_EVENT(sys_io_setup,
+	TP_PROTO(unsigned nr_events, aio_context_t * ctxp),
+	TP_ARGS(nr_events, ctxp),
+	TP_STRUCT__entry(__field(unsigned, nr_events) __field_hex(aio_context_t *, ctxp)),
+	TP_fast_assign(tp_assign(nr_events, nr_events) tp_assign(ctxp, ctxp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_gettime
+SC_TRACE_EVENT(sys_timer_gettime,
+	TP_PROTO(timer_t timer_id, struct itimerspec * setting),
+	TP_ARGS(timer_id, setting),
+	TP_STRUCT__entry(__field(timer_t, timer_id) __field_hex(struct itimerspec *, setting)),
+	TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(setting, setting)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_settime
+SC_TRACE_EVENT(sys_clock_settime,
+	TP_PROTO(const clockid_t which_clock, const struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(const struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_gettime
+SC_TRACE_EVENT(sys_clock_gettime,
+	TP_PROTO(const clockid_t which_clock, struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_getres
+SC_TRACE_EVENT(sys_clock_getres,
+	TP_PROTO(const clockid_t which_clock, struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utimes
+SC_TRACE_EVENT(sys_utimes,
+	TP_PROTO(char * filename, struct timeval * utimes),
+	TP_ARGS(filename, utimes),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct timeval *, utimes)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_notify
+SC_TRACE_EVENT(sys_mq_notify,
+	TP_PROTO(mqd_t mqdes, const struct sigevent * u_notification),
+	TP_ARGS(mqdes, u_notification),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct sigevent *, u_notification)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_notification, u_notification)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_set_robust_list
+SC_TRACE_EVENT(sys_set_robust_list,
+	TP_PROTO(struct robust_list_head * head, size_t len),
+	TP_ARGS(head, len),
+	TP_STRUCT__entry(__field_hex(struct robust_list_head *, head) __field(size_t, len)),
+	TP_fast_assign(tp_assign(head, head) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_gettime
+SC_TRACE_EVENT(sys_timerfd_gettime,
+	TP_PROTO(int ufd, struct itimerspec * otmr),
+	TP_ARGS(ufd, otmr),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(struct itimerspec *, otmr)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(otmr, otmr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pipe2
+SC_TRACE_EVENT(sys_pipe2,
+	TP_PROTO(int * fildes, int flags),
+	TP_ARGS(fildes, flags),
+	TP_STRUCT__entry(__field_hex(int *, fildes) __field(int, flags)),
+	TP_fast_assign(tp_assign(fildes, fildes) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_adjtime
+SC_TRACE_EVENT(sys_clock_adjtime,
+	TP_PROTO(const clockid_t which_clock, struct timex * utx),
+	TP_ARGS(which_clock, utx),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timex *, utx)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(utx, utx)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_read
+SC_TRACE_EVENT(sys_read,
+	TP_PROTO(unsigned int fd, char * buf, size_t count),
+	TP_ARGS(fd, buf, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(char *, buf) __field(size_t, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_write
+SC_TRACE_EVENT(sys_write,
+	TP_PROTO(unsigned int fd, const char * buf, size_t count),
+	TP_ARGS(fd, buf, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(const char *, buf) __field(size_t, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_open
+SC_TRACE_EVENT(sys_open,
+	TP_PROTO(const char * filename, int flags, int mode),
+	TP_ARGS(filename, flags, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, flags) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_waitpid
+SC_TRACE_EVENT(sys_waitpid,
+	TP_PROTO(pid_t pid, int * stat_addr, int options),
+	TP_ARGS(pid, stat_addr, options),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(int *, stat_addr) __field(int, options)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(stat_addr, stat_addr) tp_assign(options, options)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mknod
+SC_TRACE_EVENT(sys_mknod,
+	TP_PROTO(const char * filename, int mode, unsigned dev),
+	TP_ARGS(filename, mode, dev),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lchown16
+SC_TRACE_EVENT(sys_lchown16,
+	TP_PROTO(const char * filename, old_uid_t user, old_gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(old_uid_t, user) __field(old_gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readlink
+SC_TRACE_EVENT(sys_readlink,
+	TP_PROTO(const char * path, char * buf, int bufsiz),
+	TP_ARGS(path, buf, bufsiz),
+	TP_STRUCT__entry(__string_from_user(path, path) __field_hex(char *, buf) __field(int, bufsiz)),
+	TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_old_readdir
+SC_TRACE_EVENT(sys_old_readdir,
+	TP_PROTO(unsigned int fd, struct old_linux_dirent * dirent, unsigned int count),
+	TP_ARGS(fd, dirent, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct old_linux_dirent *, dirent) __field(unsigned int, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_syslog
+SC_TRACE_EVENT(sys_syslog,
+	TP_PROTO(int type, char * buf, int len),
+	TP_ARGS(type, buf, len),
+	TP_STRUCT__entry(__field(int, type) __field_hex(char *, buf) __field(int, len)),
+	TP_fast_assign(tp_assign(type, type) tp_assign(buf, buf) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setitimer
+SC_TRACE_EVENT(sys_setitimer,
+	TP_PROTO(int which, struct itimerval * value, struct itimerval * ovalue),
+	TP_ARGS(which, value, ovalue),
+	TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value) __field_hex(struct itimerval *, ovalue)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(value, value) tp_assign(ovalue, ovalue)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sigprocmask
+SC_TRACE_EVENT(sys_sigprocmask,
+	TP_PROTO(int how, old_sigset_t * nset, old_sigset_t * oset),
+	TP_ARGS(how, nset, oset),
+	TP_STRUCT__entry(__field(int, how) __field_hex(old_sigset_t *, nset) __field_hex(old_sigset_t *, oset)),
+	TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_init_module
+SC_TRACE_EVENT(sys_init_module,
+	TP_PROTO(void * umod, unsigned long len, const char * uargs),
+	TP_ARGS(umod, len, uargs),
+	TP_STRUCT__entry(__field_hex(void *, umod) __field(unsigned long, len) __field_hex(const char *, uargs)),
+	TP_fast_assign(tp_assign(umod, umod) tp_assign(len, len) tp_assign(uargs, uargs)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getdents
+SC_TRACE_EVENT(sys_getdents,
+	TP_PROTO(unsigned int fd, struct linux_dirent * dirent, unsigned int count),
+	TP_ARGS(fd, dirent, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent *, dirent) __field(unsigned int, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readv
+SC_TRACE_EVENT(sys_readv,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen),
+	TP_ARGS(fd, vec, vlen),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_writev
+SC_TRACE_EVENT(sys_writev,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen),
+	TP_ARGS(fd, vec, vlen),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setscheduler
+SC_TRACE_EVENT(sys_sched_setscheduler,
+	TP_PROTO(pid_t pid, int policy, struct sched_param * param),
+	TP_ARGS(pid, policy, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, policy) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(policy, policy) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresuid16
+SC_TRACE_EVENT(sys_getresuid16,
+	TP_PROTO(old_uid_t * ruid, old_uid_t * euid, old_uid_t * suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field_hex(old_uid_t *, ruid) __field_hex(old_uid_t *, euid) __field_hex(old_uid_t *, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_poll
+SC_TRACE_EVENT(sys_poll,
+	TP_PROTO(struct pollfd * ufds, unsigned int nfds, long timeout_msecs),
+	TP_ARGS(ufds, nfds, timeout_msecs),
+	TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field(long, timeout_msecs)),
+	TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(timeout_msecs, timeout_msecs)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresgid16
+SC_TRACE_EVENT(sys_getresgid16,
+	TP_PROTO(old_gid_t * rgid, old_gid_t * egid, old_gid_t * sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field_hex(old_gid_t *, rgid) __field_hex(old_gid_t *, egid) __field_hex(old_gid_t *, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigqueueinfo
+SC_TRACE_EVENT(sys_rt_sigqueueinfo,
+	TP_PROTO(pid_t pid, int sig, siginfo_t * uinfo),
+	TP_ARGS(pid, sig, uinfo),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chown16
+SC_TRACE_EVENT(sys_chown16,
+	TP_PROTO(const char * filename, old_uid_t user, old_gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(old_uid_t, user) __field(old_gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lchown
+SC_TRACE_EVENT(sys_lchown,
+	TP_PROTO(const char * filename, uid_t user, gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresuid
+SC_TRACE_EVENT(sys_getresuid,
+	TP_PROTO(uid_t * ruid, uid_t * euid, uid_t * suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field_hex(uid_t *, ruid) __field_hex(uid_t *, euid) __field_hex(uid_t *, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresgid
+SC_TRACE_EVENT(sys_getresgid,
+	TP_PROTO(gid_t * rgid, gid_t * egid, gid_t * sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field_hex(gid_t *, rgid) __field_hex(gid_t *, egid) __field_hex(gid_t *, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chown
+SC_TRACE_EVENT(sys_chown,
+	TP_PROTO(const char * filename, uid_t user, gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mincore
+SC_TRACE_EVENT(sys_mincore,
+	TP_PROTO(unsigned long start, size_t len, unsigned char * vec),
+	TP_ARGS(start, len, vec),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field_hex(unsigned char *, vec)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(vec, vec)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getdents64
+SC_TRACE_EVENT(sys_getdents64,
+	TP_PROTO(unsigned int fd, struct linux_dirent64 * dirent, unsigned int count),
+	TP_ARGS(fd, dirent, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent64 *, dirent) __field(unsigned int, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_listxattr
+SC_TRACE_EVENT(sys_listxattr,
+	TP_PROTO(const char * pathname, char * list, size_t size),
+	TP_ARGS(pathname, list, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_llistxattr
+SC_TRACE_EVENT(sys_llistxattr,
+	TP_PROTO(const char * pathname, char * list, size_t size),
+	TP_ARGS(pathname, list, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_flistxattr
+SC_TRACE_EVENT(sys_flistxattr,
+	TP_PROTO(int fd, char * list, size_t size),
+	TP_ARGS(fd, list, size),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setaffinity
+SC_TRACE_EVENT(sys_sched_setaffinity,
+	TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr),
+	TP_ARGS(pid, len, user_mask_ptr),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getaffinity
+SC_TRACE_EVENT(sys_sched_getaffinity,
+	TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr),
+	TP_ARGS(pid, len, user_mask_ptr),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_submit
+SC_TRACE_EVENT(sys_io_submit,
+	TP_PROTO(aio_context_t ctx_id, long nr, struct iocb * * iocbpp),
+	TP_ARGS(ctx_id, nr, iocbpp),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, nr) __field_hex(struct iocb * *, iocbpp)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(nr, nr) tp_assign(iocbpp, iocbpp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_cancel
+SC_TRACE_EVENT(sys_io_cancel,
+	TP_PROTO(aio_context_t ctx_id, struct iocb * iocb, struct io_event * result),
+	TP_ARGS(ctx_id, iocb, result),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field_hex(struct iocb *, iocb) __field_hex(struct io_event *, result)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(iocb, iocb) tp_assign(result, result)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_create
+SC_TRACE_EVENT(sys_timer_create,
+	TP_PROTO(const clockid_t which_clock, struct sigevent * timer_event_spec, timer_t * created_timer_id),
+	TP_ARGS(which_clock, timer_event_spec, created_timer_id),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct sigevent *, timer_event_spec) __field_hex(timer_t *, created_timer_id)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(timer_event_spec, timer_event_spec) tp_assign(created_timer_id, created_timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_statfs64
+SC_TRACE_EVENT(sys_statfs64,
+	TP_PROTO(const char * pathname, size_t sz, struct statfs64 * buf),
+	TP_ARGS(pathname, sz, buf),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(size_t, sz) __field_hex(struct statfs64 *, buf)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(sz, sz) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstatfs64
+SC_TRACE_EVENT(sys_fstatfs64,
+	TP_PROTO(unsigned int fd, size_t sz, struct statfs64 * buf),
+	TP_ARGS(fd, sz, buf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(size_t, sz) __field_hex(struct statfs64 *, buf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(sz, sz) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_getsetattr
+SC_TRACE_EVENT(sys_mq_getsetattr,
+	TP_PROTO(mqd_t mqdes, const struct mq_attr * u_mqstat, struct mq_attr * u_omqstat),
+	TP_ARGS(mqdes, u_mqstat, u_omqstat),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct mq_attr *, u_mqstat) __field_hex(struct mq_attr *, u_omqstat)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_mqstat, u_mqstat) tp_assign(u_omqstat, u_omqstat)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_add_watch
+SC_TRACE_EVENT(sys_inotify_add_watch,
+	TP_PROTO(int fd, const char * pathname, u32 mask),
+	TP_ARGS(fd, pathname, mask),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(pathname, pathname) __field(u32, mask)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(pathname, pathname) tp_assign(mask, mask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mkdirat
+SC_TRACE_EVENT(sys_mkdirat,
+	TP_PROTO(int dfd, const char * pathname, int mode),
+	TP_ARGS(dfd, pathname, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_futimesat
+SC_TRACE_EVENT(sys_futimesat,
+	TP_PROTO(int dfd, const char * filename, struct timeval * utimes),
+	TP_ARGS(dfd, filename, utimes),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timeval *, utimes)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_unlinkat
+SC_TRACE_EVENT(sys_unlinkat,
+	TP_PROTO(int dfd, const char * pathname, int flag),
+	TP_ARGS(dfd, pathname, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_symlinkat
+SC_TRACE_EVENT(sys_symlinkat,
+	TP_PROTO(const char * oldname, int newdfd, const char * newname),
+	TP_ARGS(oldname, newdfd, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchmodat
+SC_TRACE_EVENT(sys_fchmodat,
+	TP_PROTO(int dfd, const char * filename, mode_t mode),
+	TP_ARGS(dfd, filename, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(mode_t, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_faccessat
+SC_TRACE_EVENT(sys_faccessat,
+	TP_PROTO(int dfd, const char * filename, int mode),
+	TP_ARGS(dfd, filename, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_get_robust_list
+SC_TRACE_EVENT(sys_get_robust_list,
+	TP_PROTO(int pid, struct robust_list_head * * head_ptr, size_t * len_ptr),
+	TP_ARGS(pid, head_ptr, len_ptr),
+	TP_STRUCT__entry(__field(int, pid) __field_hex(struct robust_list_head * *, head_ptr) __field_hex(size_t *, len_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(head_ptr, head_ptr) tp_assign(len_ptr, len_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getcpu
+SC_TRACE_EVENT(sys_getcpu,
+	TP_PROTO(unsigned * cpup, unsigned * nodep, struct getcpu_cache * unused),
+	TP_ARGS(cpup, nodep, unused),
+	TP_STRUCT__entry(__field_hex(unsigned *, cpup) __field_hex(unsigned *, nodep) __field_hex(struct getcpu_cache *, unused)),
+	TP_fast_assign(tp_assign(cpup, cpup) tp_assign(nodep, nodep) tp_assign(unused, unused)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_signalfd
+SC_TRACE_EVENT(sys_signalfd,
+	TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask),
+	TP_ARGS(ufd, user_mask, sizemask),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_reboot
+SC_TRACE_EVENT(sys_reboot,
+	TP_PROTO(int magic1, int magic2, unsigned int cmd, void * arg),
+	TP_ARGS(magic1, magic2, cmd, arg),
+	TP_STRUCT__entry(__field(int, magic1) __field(int, magic2) __field(unsigned int, cmd) __field_hex(void *, arg)),
+	TP_fast_assign(tp_assign(magic1, magic1) tp_assign(magic2, magic2) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_wait4
+SC_TRACE_EVENT(sys_wait4,
+	TP_PROTO(pid_t upid, int * stat_addr, int options, struct rusage * ru),
+	TP_ARGS(upid, stat_addr, options, ru),
+	TP_STRUCT__entry(__field(pid_t, upid) __field_hex(int *, stat_addr) __field(int, options) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(upid, upid) tp_assign(stat_addr, stat_addr) tp_assign(options, options) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_quotactl
+SC_TRACE_EVENT(sys_quotactl,
+	TP_PROTO(unsigned int cmd, const char * special, qid_t id, void * addr),
+	TP_ARGS(cmd, special, id, addr),
+	TP_STRUCT__entry(__field(unsigned int, cmd) __field_hex(const char *, special) __field(qid_t, id) __field_hex(void *, addr)),
+	TP_fast_assign(tp_assign(cmd, cmd) tp_assign(special, special) tp_assign(id, id) tp_assign(addr, addr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigaction
+SC_TRACE_EVENT(sys_rt_sigaction,
+	TP_PROTO(int sig, const struct sigaction * act, struct sigaction * oact, size_t sigsetsize),
+	TP_ARGS(sig, act, oact, sigsetsize),
+	TP_STRUCT__entry(__field(int, sig) __field_hex(const struct sigaction *, act) __field_hex(struct sigaction *, oact) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(sig, sig) tp_assign(act, act) tp_assign(oact, oact) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigprocmask
+SC_TRACE_EVENT(sys_rt_sigprocmask,
+	TP_PROTO(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize),
+	TP_ARGS(how, nset, oset, sigsetsize),
+	TP_STRUCT__entry(__field(int, how) __field_hex(sigset_t *, nset) __field_hex(sigset_t *, oset) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigtimedwait
+SC_TRACE_EVENT(sys_rt_sigtimedwait,
+	TP_PROTO(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec * uts, size_t sigsetsize),
+	TP_ARGS(uthese, uinfo, uts, sigsetsize),
+	TP_STRUCT__entry(__field_hex(const sigset_t *, uthese) __field_hex(siginfo_t *, uinfo) __field_hex(const struct timespec *, uts) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(uthese, uthese) tp_assign(uinfo, uinfo) tp_assign(uts, uts) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendfile
+SC_TRACE_EVENT(sys_sendfile,
+	TP_PROTO(int out_fd, int in_fd, off_t * offset, size_t count),
+	TP_ARGS(out_fd, in_fd, offset, count),
+	TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(off_t *, offset) __field(size_t, count)),
+	TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getxattr
+SC_TRACE_EVENT(sys_getxattr,
+	TP_PROTO(const char * pathname, const char * name, void * value, size_t size),
+	TP_ARGS(pathname, name, value, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lgetxattr
+SC_TRACE_EVENT(sys_lgetxattr,
+	TP_PROTO(const char * pathname, const char * name, void * value, size_t size),
+	TP_ARGS(pathname, name, value, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fgetxattr
+SC_TRACE_EVENT(sys_fgetxattr,
+	TP_PROTO(int fd, const char * name, void * value, size_t size),
+	TP_ARGS(fd, name, value, size),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendfile64
+SC_TRACE_EVENT(sys_sendfile64,
+	TP_PROTO(int out_fd, int in_fd, loff_t * offset, size_t count),
+	TP_ARGS(out_fd, in_fd, offset, count),
+	TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(loff_t *, offset) __field(size_t, count)),
+	TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_ctl
+SC_TRACE_EVENT(sys_epoll_ctl,
+	TP_PROTO(int epfd, int op, int fd, struct epoll_event * event),
+	TP_ARGS(epfd, op, fd, event),
+	TP_STRUCT__entry(__field(int, epfd) __field(int, op) __field(int, fd) __field_hex(struct epoll_event *, event)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(op, op) tp_assign(fd, fd) tp_assign(event, event)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_wait
+SC_TRACE_EVENT(sys_epoll_wait,
+	TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout),
+	TP_ARGS(epfd, events, maxevents, timeout),
+	TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_settime
+SC_TRACE_EVENT(sys_timer_settime,
+	TP_PROTO(timer_t timer_id, int flags, const struct itimerspec * new_setting, struct itimerspec * old_setting),
+	TP_ARGS(timer_id, flags, new_setting, old_setting),
+	TP_STRUCT__entry(__field(timer_t, timer_id) __field(int, flags) __field_hex(const struct itimerspec *, new_setting) __field_hex(struct itimerspec *, old_setting)),
+	TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(flags, flags) tp_assign(new_setting, new_setting) tp_assign(old_setting, old_setting)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_nanosleep
+SC_TRACE_EVENT(sys_clock_nanosleep,
+	TP_PROTO(const clockid_t which_clock, int flags, const struct timespec * rqtp, struct timespec * rmtp),
+	TP_ARGS(which_clock, flags, rqtp, rmtp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field(int, flags) __field_hex(const struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(flags, flags) tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_open
+SC_TRACE_EVENT(sys_mq_open,
+	TP_PROTO(const char * u_name, int oflag, mode_t mode, struct mq_attr * u_attr),
+	TP_ARGS(u_name, oflag, mode, u_attr),
+	TP_STRUCT__entry(__string_from_user(u_name, u_name) __field(int, oflag) __field(mode_t, mode) __field_hex(struct mq_attr *, u_attr)),
+	TP_fast_assign(tp_copy_string_from_user(u_name, u_name) tp_assign(oflag, oflag) tp_assign(mode, mode) tp_assign(u_attr, u_attr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_kexec_load
+SC_TRACE_EVENT(sys_kexec_load,
+	TP_PROTO(unsigned long entry, unsigned long nr_segments, struct kexec_segment * segments, unsigned long flags),
+	TP_ARGS(entry, nr_segments, segments, flags),
+	TP_STRUCT__entry(__field(unsigned long, entry) __field(unsigned long, nr_segments) __field_hex(struct kexec_segment *, segments) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(entry, entry) tp_assign(nr_segments, nr_segments) tp_assign(segments, segments) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_request_key
+SC_TRACE_EVENT(sys_request_key,
+	TP_PROTO(const char * _type, const char * _description, const char * _callout_info, key_serial_t destringid),
+	TP_ARGS(_type, _description, _callout_info, destringid),
+	TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const char *, _callout_info) __field(key_serial_t, destringid)),
+	TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_callout_info, _callout_info) tp_assign(destringid, destringid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_openat
+SC_TRACE_EVENT(sys_openat,
+	TP_PROTO(int dfd, const char * filename, int flags, int mode),
+	TP_ARGS(dfd, filename, flags, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, flags) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mknodat
+SC_TRACE_EVENT(sys_mknodat,
+	TP_PROTO(int dfd, const char * filename, int mode, unsigned dev),
+	TP_ARGS(dfd, filename, mode, dev),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstatat64
+SC_TRACE_EVENT(sys_fstatat64,
+	TP_PROTO(int dfd, const char * filename, struct stat64 * statbuf, int flag),
+	TP_ARGS(dfd, filename, statbuf, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_renameat
+SC_TRACE_EVENT(sys_renameat,
+	TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname),
+	TP_ARGS(olddfd, oldname, newdfd, newname),
+	TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readlinkat
+SC_TRACE_EVENT(sys_readlinkat,
+	TP_PROTO(int dfd, const char * pathname, char * buf, int bufsiz),
+	TP_ARGS(dfd, pathname, buf, bufsiz),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field_hex(char *, buf) __field(int, bufsiz)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_vmsplice
+SC_TRACE_EVENT(sys_vmsplice,
+	TP_PROTO(int fd, const struct iovec * iov, unsigned long nr_segs, unsigned int flags),
+	TP_ARGS(fd, iov, nr_segs, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(const struct iovec *, iov) __field(unsigned long, nr_segs) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(iov, iov) tp_assign(nr_segs, nr_segs) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utimensat
+SC_TRACE_EVENT(sys_utimensat,
+	TP_PROTO(int dfd, const char * filename, struct timespec * utimes, int flags),
+	TP_ARGS(dfd, filename, utimes, flags),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timespec *, utimes) __field(int, flags)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_settime
+SC_TRACE_EVENT(sys_timerfd_settime,
+	TP_PROTO(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr),
+	TP_ARGS(ufd, flags, utmr, otmr),
+	TP_STRUCT__entry(__field(int, ufd) __field(int, flags) __field_hex(const struct itimerspec *, utmr) __field_hex(struct itimerspec *, otmr)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(flags, flags) tp_assign(utmr, utmr) tp_assign(otmr, otmr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_signalfd4
+SC_TRACE_EVENT(sys_signalfd4,
+	TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask, int flags),
+	TP_ARGS(ufd, user_mask, sizemask, flags),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask) __field(int, flags)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_tgsigqueueinfo
+SC_TRACE_EVENT(sys_rt_tgsigqueueinfo,
+	TP_PROTO(pid_t tgid, pid_t pid, int sig, siginfo_t * uinfo),
+	TP_ARGS(tgid, pid, sig, uinfo),
+	TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)),
+	TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_prlimit64
+SC_TRACE_EVENT(sys_prlimit64,
+	TP_PROTO(pid_t pid, unsigned int resource, const struct rlimit64 * new_rlim, struct rlimit64 * old_rlim),
+	TP_ARGS(pid, resource, new_rlim, old_rlim),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, resource) __field_hex(const struct rlimit64 *, new_rlim) __field_hex(struct rlimit64 *, old_rlim)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(resource, resource) tp_assign(new_rlim, new_rlim) tp_assign(old_rlim, old_rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendmmsg
+SC_TRACE_EVENT(sys_sendmmsg,
+	TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags),
+	TP_ARGS(fd, mmsg, vlen, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mount
+SC_TRACE_EVENT(sys_mount,
+	TP_PROTO(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data),
+	TP_ARGS(dev_name, dir_name, type, flags, data),
+	TP_STRUCT__entry(__string_from_user(dev_name, dev_name) __string_from_user(dir_name, dir_name) __string_from_user(type, type) __field(unsigned long, flags) __field_hex(void *, data)),
+	TP_fast_assign(tp_copy_string_from_user(dev_name, dev_name) tp_copy_string_from_user(dir_name, dir_name) tp_copy_string_from_user(type, type) tp_assign(flags, flags) tp_assign(data, data)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_llseek
+SC_TRACE_EVENT(sys_llseek,
+	TP_PROTO(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int origin),
+	TP_ARGS(fd, offset_high, offset_low, result, origin),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, offset_high) __field(unsigned long, offset_low) __field_hex(loff_t *, result) __field(unsigned int, origin)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(offset_high, offset_high) tp_assign(offset_low, offset_low) tp_assign(result, result) tp_assign(origin, origin)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_select
+SC_TRACE_EVENT(sys_select,
+	TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timeval * tvp),
+	TP_ARGS(n, inp, outp, exp, tvp),
+	TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timeval *, tvp)),
+	TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tvp, tvp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setxattr
+SC_TRACE_EVENT(sys_setxattr,
+	TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(pathname, name, value, size, flags),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lsetxattr
+SC_TRACE_EVENT(sys_lsetxattr,
+	TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(pathname, name, value, size, flags),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fsetxattr
+SC_TRACE_EVENT(sys_fsetxattr,
+	TP_PROTO(int fd, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(fd, name, value, size, flags),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_getevents
+SC_TRACE_EVENT(sys_io_getevents,
+	TP_PROTO(aio_context_t ctx_id, long min_nr, long nr, struct io_event * events, struct timespec * timeout),
+	TP_ARGS(ctx_id, min_nr, nr, events, timeout),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, min_nr) __field(long, nr) __field_hex(struct io_event *, events) __field_hex(struct timespec *, timeout)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(min_nr, min_nr) tp_assign(nr, nr) tp_assign(events, events) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_timedsend
+SC_TRACE_EVENT(sys_mq_timedsend,
+	TP_PROTO(mqd_t mqdes, const char * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec * u_abs_timeout),
+	TP_ARGS(mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const char *, u_msg_ptr) __field(size_t, msg_len) __field(unsigned int, msg_prio) __field_hex(const struct timespec *, u_abs_timeout)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(msg_prio, msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_timedreceive
+SC_TRACE_EVENT(sys_mq_timedreceive,
+	TP_PROTO(mqd_t mqdes, char * u_msg_ptr, size_t msg_len, unsigned int * u_msg_prio, const struct timespec * u_abs_timeout),
+	TP_ARGS(mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(char *, u_msg_ptr) __field(size_t, msg_len) __field_hex(unsigned int *, u_msg_prio) __field_hex(const struct timespec *, u_abs_timeout)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(u_msg_prio, u_msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_waitid
+SC_TRACE_EVENT(sys_waitid,
+	TP_PROTO(int which, pid_t upid, struct siginfo * infop, int options, struct rusage * ru),
+	TP_ARGS(which, upid, infop, options, ru),
+	TP_STRUCT__entry(__field(int, which) __field(pid_t, upid) __field_hex(struct siginfo *, infop) __field(int, options) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(upid, upid) tp_assign(infop, infop) tp_assign(options, options) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_add_key
+SC_TRACE_EVENT(sys_add_key,
+	TP_PROTO(const char * _type, const char * _description, const void * _payload, size_t plen, key_serial_t ringid),
+	TP_ARGS(_type, _description, _payload, plen, ringid),
+	TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const void *, _payload) __field(size_t, plen) __field(key_serial_t, ringid)),
+	TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_payload, _payload) tp_assign(plen, plen) tp_assign(ringid, ringid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchownat
+SC_TRACE_EVENT(sys_fchownat,
+	TP_PROTO(int dfd, const char * filename, uid_t user, gid_t group, int flag),
+	TP_ARGS(dfd, filename, user, group, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_linkat
+SC_TRACE_EVENT(sys_linkat,
+	TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname, int flags),
+	TP_ARGS(olddfd, oldname, newdfd, newname, flags),
+	TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname) __field(int, flags)),
+	TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ppoll
+SC_TRACE_EVENT(sys_ppoll,
+	TP_PROTO(struct pollfd * ufds, unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize),
+	TP_ARGS(ufds, nfds, tsp, sigmask, sigsetsize),
+	TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field_hex(struct timespec *, tsp) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(tsp, tsp) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_preadv
+SC_TRACE_EVENT(sys_preadv,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h),
+	TP_ARGS(fd, vec, vlen, pos_l, pos_h),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pwritev
+SC_TRACE_EVENT(sys_pwritev,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h),
+	TP_ARGS(fd, vec, vlen, pos_l, pos_h),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_perf_event_open
+SC_TRACE_EVENT(sys_perf_event_open,
+	TP_PROTO(struct perf_event_attr * attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags),
+	TP_ARGS(attr_uptr, pid, cpu, group_fd, flags),
+	TP_STRUCT__entry(__field_hex(struct perf_event_attr *, attr_uptr) __field(pid_t, pid) __field(int, cpu) __field(int, group_fd) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(attr_uptr, attr_uptr) tp_assign(pid, pid) tp_assign(cpu, cpu) tp_assign(group_fd, group_fd) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_recvmmsg
+SC_TRACE_EVENT(sys_recvmmsg,
+	TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags, struct timespec * timeout),
+	TP_ARGS(fd, mmsg, vlen, flags, timeout),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags) __field_hex(struct timespec *, timeout)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ipc
+SC_TRACE_EVENT(sys_ipc,
+	TP_PROTO(unsigned int call, int first, unsigned long second, unsigned long third, void * ptr, long fifth),
+	TP_ARGS(call, first, second, third, ptr, fifth),
+	TP_STRUCT__entry(__field(unsigned int, call) __field(int, first) __field(unsigned long, second) __field(unsigned long, third) __field_hex(void *, ptr) __field(long, fifth)),
+	TP_fast_assign(tp_assign(call, call) tp_assign(first, first) tp_assign(second, second) tp_assign(third, third) tp_assign(ptr, ptr) tp_assign(fifth, fifth)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_futex
+SC_TRACE_EVENT(sys_futex,
+	TP_PROTO(u32 * uaddr, int op, u32 val, struct timespec * utime, u32 * uaddr2, u32 val3),
+	TP_ARGS(uaddr, op, val, utime, uaddr2, val3),
+	TP_STRUCT__entry(__field_hex(u32 *, uaddr) __field(int, op) __field(u32, val) __field_hex(struct timespec *, utime) __field_hex(u32 *, uaddr2) __field(u32, val3)),
+	TP_fast_assign(tp_assign(uaddr, uaddr) tp_assign(op, op) tp_assign(val, val) tp_assign(utime, utime) tp_assign(uaddr2, uaddr2) tp_assign(val3, val3)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pselect6
+SC_TRACE_EVENT(sys_pselect6,
+	TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timespec * tsp, void * sig),
+	TP_ARGS(n, inp, outp, exp, tsp, sig),
+	TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timespec *, tsp) __field_hex(void *, sig)),
+	TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tsp, tsp) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_splice
+SC_TRACE_EVENT(sys_splice,
+	TP_PROTO(int fd_in, loff_t * off_in, int fd_out, loff_t * off_out, size_t len, unsigned int flags),
+	TP_ARGS(fd_in, off_in, fd_out, off_out, len, flags),
+	TP_STRUCT__entry(__field(int, fd_in) __field_hex(loff_t *, off_in) __field(int, fd_out) __field_hex(loff_t *, off_out) __field(size_t, len) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd_in, fd_in) tp_assign(off_in, off_in) tp_assign(fd_out, fd_out) tp_assign(off_out, off_out) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_pwait
+SC_TRACE_EVENT(sys_epoll_pwait,
+	TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout, const sigset_t * sigmask, size_t sigsetsize),
+	TP_ARGS(epfd, events, maxevents, timeout, sigmask, sigsetsize),
+	TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+
+#endif /*  _TRACE_SYSCALLS_POINTERS_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
+#else /* CREATE_SYSCALL_TABLE */
+
+#include "x86-32-syscalls-3.1.0-rc6_pointers_override.h"
+
+#ifndef OVERRIDE_TABLE_sys_read
+TRACE_SYSCALL_TABLE(sys_read, sys_read, 3, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_write
+TRACE_SYSCALL_TABLE(sys_write, sys_write, 4, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_open
+TRACE_SYSCALL_TABLE(sys_open, sys_open, 5, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_waitpid
+TRACE_SYSCALL_TABLE(sys_waitpid, sys_waitpid, 7, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_creat
+TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 8, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_link
+TRACE_SYSCALL_TABLE(sys_link, sys_link, 9, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unlink
+TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 10, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chdir
+TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 12, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_time
+TRACE_SYSCALL_TABLE(sys_time, sys_time, 13, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mknod
+TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 14, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chmod
+TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 15, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lchown16
+TRACE_SYSCALL_TABLE(sys_lchown16, sys_lchown16, 16, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_stat
+TRACE_SYSCALL_TABLE(sys_stat, sys_stat, 18, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mount
+TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 21, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_oldumount
+TRACE_SYSCALL_TABLE(sys_oldumount, sys_oldumount, 22, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_stime
+TRACE_SYSCALL_TABLE(sys_stime, sys_stime, 25, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstat
+TRACE_SYSCALL_TABLE(sys_fstat, sys_fstat, 28, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utime
+TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 30, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_access
+TRACE_SYSCALL_TABLE(sys_access, sys_access, 33, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rename
+TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 38, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mkdir
+TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 39, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rmdir
+TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 40, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pipe
+TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 42, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_times
+TRACE_SYSCALL_TABLE(sys_times, sys_times, 43, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_acct
+TRACE_SYSCALL_TABLE(sys_acct, sys_acct, 51, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_umount
+TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 52, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_olduname
+TRACE_SYSCALL_TABLE(sys_olduname, sys_olduname, 59, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chroot
+TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 61, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ustat
+TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 62, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sigpending
+TRACE_SYSCALL_TABLE(sys_sigpending, sys_sigpending, 73, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sethostname
+TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 74, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setrlimit
+TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 75, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_old_getrlimit
+TRACE_SYSCALL_TABLE(sys_old_getrlimit, sys_old_getrlimit, 76, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getrusage
+TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 77, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_gettimeofday
+TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 78, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_settimeofday
+TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 79, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgroups16
+TRACE_SYSCALL_TABLE(sys_getgroups16, sys_getgroups16, 80, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgroups16
+TRACE_SYSCALL_TABLE(sys_setgroups16, sys_setgroups16, 81, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_old_select
+TRACE_SYSCALL_TABLE(sys_old_select, sys_old_select, 82, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_symlink
+TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 83, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lstat
+TRACE_SYSCALL_TABLE(sys_lstat, sys_lstat, 84, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readlink
+TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 85, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_uselib
+TRACE_SYSCALL_TABLE(sys_uselib, sys_uselib, 86, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_swapon
+TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 87, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_reboot
+TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 88, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_old_readdir
+TRACE_SYSCALL_TABLE(sys_old_readdir, sys_old_readdir, 89, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_old_mmap
+TRACE_SYSCALL_TABLE(sys_old_mmap, sys_old_mmap, 90, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_truncate
+TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 92, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_statfs
+TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 99, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstatfs
+TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 100, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_socketcall
+TRACE_SYSCALL_TABLE(sys_socketcall, sys_socketcall, 102, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_syslog
+TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setitimer
+TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 104, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getitimer
+TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 105, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newstat
+TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 106, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newlstat
+TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 107, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newfstat
+TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 108, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_uname
+TRACE_SYSCALL_TABLE(sys_uname, sys_uname, 109, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_wait4
+TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 114, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_swapoff
+TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 115, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysinfo
+TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 116, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ipc
+TRACE_SYSCALL_TABLE(sys_ipc, sys_ipc, 117, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setdomainname
+TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 121, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newuname
+TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 122, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_adjtimex
+TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 124, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sigprocmask
+TRACE_SYSCALL_TABLE(sys_sigprocmask, sys_sigprocmask, 126, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_init_module
+TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 128, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_delete_module
+TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 129, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_quotactl
+TRACE_SYSCALL_TABLE(sys_quotactl, sys_quotactl, 131, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_llseek
+TRACE_SYSCALL_TABLE(sys_llseek, sys_llseek, 140, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getdents
+TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 141, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_select
+TRACE_SYSCALL_TABLE(sys_select, sys_select, 142, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readv
+TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 145, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_writev
+TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 146, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysctl
+TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 149, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setparam
+TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 154, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getparam
+TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 155, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setscheduler
+TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 156, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_rr_get_interval
+TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 161, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_nanosleep
+TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 162, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresuid16
+TRACE_SYSCALL_TABLE(sys_getresuid16, sys_getresuid16, 165, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_poll
+TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 168, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresgid16
+TRACE_SYSCALL_TABLE(sys_getresgid16, sys_getresgid16, 171, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigaction
+TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 174, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigprocmask
+TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 175, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigpending
+TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 176, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigtimedwait
+TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 177, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigqueueinfo
+TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 178, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigsuspend
+TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 179, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chown16
+TRACE_SYSCALL_TABLE(sys_chown16, sys_chown16, 182, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getcwd
+TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 183, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendfile
+TRACE_SYSCALL_TABLE(sys_sendfile, sys_sendfile, 187, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getrlimit
+TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 191, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_stat64
+TRACE_SYSCALL_TABLE(sys_stat64, sys_stat64, 195, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lstat64
+TRACE_SYSCALL_TABLE(sys_lstat64, sys_lstat64, 196, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstat64
+TRACE_SYSCALL_TABLE(sys_fstat64, sys_fstat64, 197, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lchown
+TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 198, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgroups
+TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 205, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgroups
+TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 206, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresuid
+TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 209, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresgid
+TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 211, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chown
+TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 212, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pivot_root
+TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 217, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mincore
+TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 218, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getdents64
+TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 220, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setxattr
+TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 226, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lsetxattr
+TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 227, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fsetxattr
+TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 228, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getxattr
+TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 229, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lgetxattr
+TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 230, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fgetxattr
+TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 231, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_listxattr
+TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 232, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_llistxattr
+TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 233, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_flistxattr
+TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 234, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_removexattr
+TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 235, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lremovexattr
+TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 236, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fremovexattr
+TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 237, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendfile64
+TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 239, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_futex
+TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 240, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setaffinity
+TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 241, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getaffinity
+TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 242, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_setup
+TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 245, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_getevents
+TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 247, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_submit
+TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 248, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_cancel
+TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 249, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_ctl
+TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 255, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_wait
+TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 256, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_set_tid_address
+TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 258, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_create
+TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 259, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_settime
+TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 260, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_gettime
+TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 261, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_settime
+TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 264, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_gettime
+TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 265, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_getres
+TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 266, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_nanosleep
+TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 267, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_statfs64
+TRACE_SYSCALL_TABLE(sys_statfs64, sys_statfs64, 268, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstatfs64
+TRACE_SYSCALL_TABLE(sys_fstatfs64, sys_fstatfs64, 269, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utimes
+TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 271, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_open
+TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 277, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_unlink
+TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 278, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_timedsend
+TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 279, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_timedreceive
+TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 280, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_notify
+TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 281, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_getsetattr
+TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 282, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_kexec_load
+TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 283, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_waitid
+TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 284, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_add_key
+TRACE_SYSCALL_TABLE(sys_add_key, sys_add_key, 286, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_request_key
+TRACE_SYSCALL_TABLE(sys_request_key, sys_request_key, 287, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_add_watch
+TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 292, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_openat
+TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 295, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mkdirat
+TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 296, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mknodat
+TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 297, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchownat
+TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 298, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_futimesat
+TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 299, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstatat64
+TRACE_SYSCALL_TABLE(sys_fstatat64, sys_fstatat64, 300, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unlinkat
+TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 301, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_renameat
+TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 302, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_linkat
+TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 303, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_symlinkat
+TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 304, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readlinkat
+TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 305, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchmodat
+TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 306, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_faccessat
+TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 307, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pselect6
+TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 308, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ppoll
+TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 309, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_set_robust_list
+TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 311, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_get_robust_list
+TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 312, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_splice
+TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 313, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_vmsplice
+TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 316, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getcpu
+TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 318, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_pwait
+TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 319, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utimensat
+TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 320, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_signalfd
+TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 321, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_settime
+TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 325, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_gettime
+TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 326, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_signalfd4
+TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 327, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pipe2
+TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 331, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_preadv
+TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 333, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pwritev
+TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 334, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_tgsigqueueinfo
+TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 335, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_perf_event_open
+TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 336, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_recvmmsg
+TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 337, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_prlimit64
+TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 340, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_adjtime
+TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 343, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendmmsg
+TRACE_SYSCALL_TABLE(sys_sendmmsg, sys_sendmmsg, 345, 4)
+#endif
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h
new file mode 100644
index 0000000..e0235be
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h
@@ -0,0 +1,17 @@
+#ifndef CONFIG_UID16
+
+#define OVERRIDE_sys_getgroups16
+#define OVERRIDE_sys_setgroups16
+#define OVERRIDE_sys_lchown16
+#define OVERRIDE_sys_getresuid16
+#define OVERRIDE_sys_getresgid16
+#define OVERRIDE_sys_chown16
+
+#define OVERRIDE_TABLE_sys_getgroups16
+#define OVERRIDE_TABLE_sys_setgroups16
+#define OVERRIDE_TABLE_sys_lchown16
+#define OVERRIDE_TABLE_sys_getresuid16
+#define OVERRIDE_TABLE_sys_getresgid16
+#define OVERRIDE_TABLE_sys_chown16
+
+#endif
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h
new file mode 100644
index 0000000..ce15b68
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h
@@ -0,0 +1,1011 @@
+/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */
+#ifndef CREATE_SYSCALL_TABLE
+
+#if !defined(_TRACE_SYSCALLS_INTEGERS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_INTEGERS_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+#include "x86-64-syscalls-3.0.4_integers_override.h"
+
+SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,
+	TP_STRUCT__entry(),
+	TP_fast_assign(),
+	TP_printk()
+)
+#ifndef OVERRIDE_sys_sched_yield
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield)
+#endif
+#ifndef OVERRIDE_sys_pause
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause)
+#endif
+#ifndef OVERRIDE_sys_getpid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid)
+#endif
+#ifndef OVERRIDE_sys_getuid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid)
+#endif
+#ifndef OVERRIDE_sys_getgid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid)
+#endif
+#ifndef OVERRIDE_sys_geteuid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid)
+#endif
+#ifndef OVERRIDE_sys_getegid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid)
+#endif
+#ifndef OVERRIDE_sys_getppid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid)
+#endif
+#ifndef OVERRIDE_sys_getpgrp
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp)
+#endif
+#ifndef OVERRIDE_sys_setsid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid)
+#endif
+#ifndef OVERRIDE_sys_munlockall
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall)
+#endif
+#ifndef OVERRIDE_sys_vhangup
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup)
+#endif
+#ifndef OVERRIDE_sys_sync
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync)
+#endif
+#ifndef OVERRIDE_sys_gettid
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid)
+#endif
+#ifndef OVERRIDE_sys_restart_syscall
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall)
+#endif
+#ifndef OVERRIDE_sys_inotify_init
+SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init)
+#endif
+#ifndef OVERRIDE_sys_close
+SC_TRACE_EVENT(sys_close,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_brk
+SC_TRACE_EVENT(sys_brk,
+	TP_PROTO(unsigned long brk),
+	TP_ARGS(brk),
+	TP_STRUCT__entry(__field(unsigned long, brk)),
+	TP_fast_assign(tp_assign(brk, brk)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup
+SC_TRACE_EVENT(sys_dup,
+	TP_PROTO(unsigned int fildes),
+	TP_ARGS(fildes),
+	TP_STRUCT__entry(__field(unsigned int, fildes)),
+	TP_fast_assign(tp_assign(fildes, fildes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_alarm
+SC_TRACE_EVENT(sys_alarm,
+	TP_PROTO(unsigned int seconds),
+	TP_ARGS(seconds),
+	TP_STRUCT__entry(__field(unsigned int, seconds)),
+	TP_fast_assign(tp_assign(seconds, seconds)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_exit
+SC_TRACE_EVENT(sys_exit,
+	TP_PROTO(int error_code),
+	TP_ARGS(error_code),
+	TP_STRUCT__entry(__field(int, error_code)),
+	TP_fast_assign(tp_assign(error_code, error_code)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fsync
+SC_TRACE_EVENT(sys_fsync,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fdatasync
+SC_TRACE_EVENT(sys_fdatasync,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchdir
+SC_TRACE_EVENT(sys_fchdir,
+	TP_PROTO(unsigned int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(unsigned int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_umask
+SC_TRACE_EVENT(sys_umask,
+	TP_PROTO(int mask),
+	TP_ARGS(mask),
+	TP_STRUCT__entry(__field(int, mask)),
+	TP_fast_assign(tp_assign(mask, mask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setuid
+SC_TRACE_EVENT(sys_setuid,
+	TP_PROTO(uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgid
+SC_TRACE_EVENT(sys_setgid,
+	TP_PROTO(gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getpgid
+SC_TRACE_EVENT(sys_getpgid,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsuid
+SC_TRACE_EVENT(sys_setfsuid,
+	TP_PROTO(uid_t uid),
+	TP_ARGS(uid),
+	TP_STRUCT__entry(__field(uid_t, uid)),
+	TP_fast_assign(tp_assign(uid, uid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setfsgid
+SC_TRACE_EVENT(sys_setfsgid,
+	TP_PROTO(gid_t gid),
+	TP_ARGS(gid),
+	TP_STRUCT__entry(__field(gid_t, gid)),
+	TP_fast_assign(tp_assign(gid, gid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getsid
+SC_TRACE_EVENT(sys_getsid,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_personality
+SC_TRACE_EVENT(sys_personality,
+	TP_PROTO(unsigned int personality),
+	TP_ARGS(personality),
+	TP_STRUCT__entry(__field(unsigned int, personality)),
+	TP_fast_assign(tp_assign(personality, personality)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getscheduler
+SC_TRACE_EVENT(sys_sched_getscheduler,
+	TP_PROTO(pid_t pid),
+	TP_ARGS(pid),
+	TP_STRUCT__entry(__field(pid_t, pid)),
+	TP_fast_assign(tp_assign(pid, pid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_get_priority_max
+SC_TRACE_EVENT(sys_sched_get_priority_max,
+	TP_PROTO(int policy),
+	TP_ARGS(policy),
+	TP_STRUCT__entry(__field(int, policy)),
+	TP_fast_assign(tp_assign(policy, policy)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_get_priority_min
+SC_TRACE_EVENT(sys_sched_get_priority_min,
+	TP_PROTO(int policy),
+	TP_ARGS(policy),
+	TP_STRUCT__entry(__field(int, policy)),
+	TP_fast_assign(tp_assign(policy, policy)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mlockall
+SC_TRACE_EVENT(sys_mlockall,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_destroy
+SC_TRACE_EVENT(sys_io_destroy,
+	TP_PROTO(aio_context_t ctx),
+	TP_ARGS(ctx),
+	TP_STRUCT__entry(__field(aio_context_t, ctx)),
+	TP_fast_assign(tp_assign(ctx, ctx)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_create
+SC_TRACE_EVENT(sys_epoll_create,
+	TP_PROTO(int size),
+	TP_ARGS(size),
+	TP_STRUCT__entry(__field(int, size)),
+	TP_fast_assign(tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_getoverrun
+SC_TRACE_EVENT(sys_timer_getoverrun,
+	TP_PROTO(timer_t timer_id),
+	TP_ARGS(timer_id),
+	TP_STRUCT__entry(__field(timer_t, timer_id)),
+	TP_fast_assign(tp_assign(timer_id, timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_delete
+SC_TRACE_EVENT(sys_timer_delete,
+	TP_PROTO(timer_t timer_id),
+	TP_ARGS(timer_id),
+	TP_STRUCT__entry(__field(timer_t, timer_id)),
+	TP_fast_assign(tp_assign(timer_id, timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_exit_group
+SC_TRACE_EVENT(sys_exit_group,
+	TP_PROTO(int error_code),
+	TP_ARGS(error_code),
+	TP_STRUCT__entry(__field(int, error_code)),
+	TP_fast_assign(tp_assign(error_code, error_code)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_unshare
+SC_TRACE_EVENT(sys_unshare,
+	TP_PROTO(unsigned long unshare_flags),
+	TP_ARGS(unshare_flags),
+	TP_STRUCT__entry(__field(unsigned long, unshare_flags)),
+	TP_fast_assign(tp_assign(unshare_flags, unshare_flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_eventfd
+SC_TRACE_EVENT(sys_eventfd,
+	TP_PROTO(unsigned int count),
+	TP_ARGS(count),
+	TP_STRUCT__entry(__field(unsigned int, count)),
+	TP_fast_assign(tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_create1
+SC_TRACE_EVENT(sys_epoll_create1,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_init1
+SC_TRACE_EVENT(sys_inotify_init1,
+	TP_PROTO(int flags),
+	TP_ARGS(flags),
+	TP_STRUCT__entry(__field(int, flags)),
+	TP_fast_assign(tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_syncfs
+SC_TRACE_EVENT(sys_syncfs,
+	TP_PROTO(int fd),
+	TP_ARGS(fd),
+	TP_STRUCT__entry(__field(int, fd)),
+	TP_fast_assign(tp_assign(fd, fd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_munmap
+SC_TRACE_EVENT(sys_munmap,
+	TP_PROTO(unsigned long addr, size_t len),
+	TP_ARGS(addr, len),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup2
+SC_TRACE_EVENT(sys_dup2,
+	TP_PROTO(unsigned int oldfd, unsigned int newfd),
+	TP_ARGS(oldfd, newfd),
+	TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd)),
+	TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_shutdown
+SC_TRACE_EVENT(sys_shutdown,
+	TP_PROTO(int fd, int how),
+	TP_ARGS(fd, how),
+	TP_STRUCT__entry(__field(int, fd) __field(int, how)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(how, how)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_listen
+SC_TRACE_EVENT(sys_listen,
+	TP_PROTO(int fd, int backlog),
+	TP_ARGS(fd, backlog),
+	TP_STRUCT__entry(__field(int, fd) __field(int, backlog)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(backlog, backlog)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_kill
+SC_TRACE_EVENT(sys_kill,
+	TP_PROTO(pid_t pid, int sig),
+	TP_ARGS(pid, sig),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msgget
+SC_TRACE_EVENT(sys_msgget,
+	TP_PROTO(key_t key, int msgflg),
+	TP_ARGS(key, msgflg),
+	TP_STRUCT__entry(__field(key_t, key) __field(int, msgflg)),
+	TP_fast_assign(tp_assign(key, key) tp_assign(msgflg, msgflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_flock
+SC_TRACE_EVENT(sys_flock,
+	TP_PROTO(unsigned int fd, unsigned int cmd),
+	TP_ARGS(fd, cmd),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ftruncate
+SC_TRACE_EVENT(sys_ftruncate,
+	TP_PROTO(unsigned int fd, unsigned long length),
+	TP_ARGS(fd, length),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, length)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(length, length)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchmod
+SC_TRACE_EVENT(sys_fchmod,
+	TP_PROTO(unsigned int fd, mode_t mode),
+	TP_ARGS(fd, mode),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(mode_t, mode)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setpgid
+SC_TRACE_EVENT(sys_setpgid,
+	TP_PROTO(pid_t pid, pid_t pgid),
+	TP_ARGS(pid, pgid),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(pid_t, pgid)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(pgid, pgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setreuid
+SC_TRACE_EVENT(sys_setreuid,
+	TP_PROTO(uid_t ruid, uid_t euid),
+	TP_ARGS(ruid, euid),
+	TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setregid
+SC_TRACE_EVENT(sys_setregid,
+	TP_PROTO(gid_t rgid, gid_t egid),
+	TP_ARGS(rgid, egid),
+	TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getpriority
+SC_TRACE_EVENT(sys_getpriority,
+	TP_PROTO(int which, int who),
+	TP_ARGS(which, who),
+	TP_STRUCT__entry(__field(int, which) __field(int, who)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mlock
+SC_TRACE_EVENT(sys_mlock,
+	TP_PROTO(unsigned long start, size_t len),
+	TP_ARGS(start, len),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_munlock
+SC_TRACE_EVENT(sys_munlock,
+	TP_PROTO(unsigned long start, size_t len),
+	TP_ARGS(start, len),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tkill
+SC_TRACE_EVENT(sys_tkill,
+	TP_PROTO(pid_t pid, int sig),
+	TP_ARGS(pid, sig),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioprio_get
+SC_TRACE_EVENT(sys_ioprio_get,
+	TP_PROTO(int which, int who),
+	TP_ARGS(which, who),
+	TP_STRUCT__entry(__field(int, which) __field(int, who)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_rm_watch
+SC_TRACE_EVENT(sys_inotify_rm_watch,
+	TP_PROTO(int fd, __s32 wd),
+	TP_ARGS(fd, wd),
+	TP_STRUCT__entry(__field(int, fd) __field(__s32, wd)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(wd, wd)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_create
+SC_TRACE_EVENT(sys_timerfd_create,
+	TP_PROTO(int clockid, int flags),
+	TP_ARGS(clockid, flags),
+	TP_STRUCT__entry(__field(int, clockid) __field(int, flags)),
+	TP_fast_assign(tp_assign(clockid, clockid) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_eventfd2
+SC_TRACE_EVENT(sys_eventfd2,
+	TP_PROTO(unsigned int count, int flags),
+	TP_ARGS(count, flags),
+	TP_STRUCT__entry(__field(unsigned int, count) __field(int, flags)),
+	TP_fast_assign(tp_assign(count, count) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setns
+SC_TRACE_EVENT(sys_setns,
+	TP_PROTO(int fd, int nstype),
+	TP_ARGS(fd, nstype),
+	TP_STRUCT__entry(__field(int, fd) __field(int, nstype)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(nstype, nstype)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lseek
+SC_TRACE_EVENT(sys_lseek,
+	TP_PROTO(unsigned int fd, off_t offset, unsigned int origin),
+	TP_ARGS(fd, offset, origin),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(off_t, offset) __field(unsigned int, origin)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(offset, offset) tp_assign(origin, origin)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mprotect
+SC_TRACE_EVENT(sys_mprotect,
+	TP_PROTO(unsigned long start, size_t len, unsigned long prot),
+	TP_ARGS(start, len, prot),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(unsigned long, prot)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(prot, prot)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioctl
+SC_TRACE_EVENT(sys_ioctl,
+	TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg),
+	TP_ARGS(fd, cmd, arg),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msync
+SC_TRACE_EVENT(sys_msync,
+	TP_PROTO(unsigned long start, size_t len, int flags),
+	TP_ARGS(start, len, flags),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(int, flags)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_madvise
+SC_TRACE_EVENT(sys_madvise,
+	TP_PROTO(unsigned long start, size_t len_in, int behavior),
+	TP_ARGS(start, len_in, behavior),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len_in) __field(int, behavior)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len_in, len_in) tp_assign(behavior, behavior)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_shmget
+SC_TRACE_EVENT(sys_shmget,
+	TP_PROTO(key_t key, size_t size, int shmflg),
+	TP_ARGS(key, size, shmflg),
+	TP_STRUCT__entry(__field(key_t, key) __field(size_t, size) __field(int, shmflg)),
+	TP_fast_assign(tp_assign(key, key) tp_assign(size, size) tp_assign(shmflg, shmflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_socket
+SC_TRACE_EVENT(sys_socket,
+	TP_PROTO(int family, int type, int protocol),
+	TP_ARGS(family, type, protocol),
+	TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol)),
+	TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_semget
+SC_TRACE_EVENT(sys_semget,
+	TP_PROTO(key_t key, int nsems, int semflg),
+	TP_ARGS(key, nsems, semflg),
+	TP_STRUCT__entry(__field(key_t, key) __field(int, nsems) __field(int, semflg)),
+	TP_fast_assign(tp_assign(key, key) tp_assign(nsems, nsems) tp_assign(semflg, semflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fcntl
+SC_TRACE_EVENT(sys_fcntl,
+	TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg),
+	TP_ARGS(fd, cmd, arg),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchown
+SC_TRACE_EVENT(sys_fchown,
+	TP_PROTO(unsigned int fd, uid_t user, gid_t group),
+	TP_ARGS(fd, user, group),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresuid
+SC_TRACE_EVENT(sys_setresuid,
+	TP_PROTO(uid_t ruid, uid_t euid, uid_t suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid) __field(uid_t, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setresgid
+SC_TRACE_EVENT(sys_setresgid,
+	TP_PROTO(gid_t rgid, gid_t egid, gid_t sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid) __field(gid_t, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysfs
+SC_TRACE_EVENT(sys_sysfs,
+	TP_PROTO(int option, unsigned long arg1, unsigned long arg2),
+	TP_ARGS(option, arg1, arg2),
+	TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg1) __field(unsigned long, arg2)),
+	TP_fast_assign(tp_assign(option, option) tp_assign(arg1, arg1) tp_assign(arg2, arg2)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setpriority
+SC_TRACE_EVENT(sys_setpriority,
+	TP_PROTO(int which, int who, int niceval),
+	TP_ARGS(which, who, niceval),
+	TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, niceval)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(niceval, niceval)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tgkill
+SC_TRACE_EVENT(sys_tgkill,
+	TP_PROTO(pid_t tgid, pid_t pid, int sig),
+	TP_ARGS(tgid, pid, sig),
+	TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig)),
+	TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ioprio_set
+SC_TRACE_EVENT(sys_ioprio_set,
+	TP_PROTO(int which, int who, int ioprio),
+	TP_ARGS(which, who, ioprio),
+	TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, ioprio)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(ioprio, ioprio)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_dup3
+SC_TRACE_EVENT(sys_dup3,
+	TP_PROTO(unsigned int oldfd, unsigned int newfd, int flags),
+	TP_ARGS(oldfd, newfd, flags),
+	TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd) __field(int, flags)),
+	TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ptrace
+SC_TRACE_EVENT(sys_ptrace,
+	TP_PROTO(long request, long pid, unsigned long addr, unsigned long data),
+	TP_ARGS(request, pid, addr, data),
+	TP_STRUCT__entry(__field(long, request) __field(long, pid) __field_hex(unsigned long, addr) __field(unsigned long, data)),
+	TP_fast_assign(tp_assign(request, request) tp_assign(pid, pid) tp_assign(addr, addr) tp_assign(data, data)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_tee
+SC_TRACE_EVENT(sys_tee,
+	TP_PROTO(int fdin, int fdout, size_t len, unsigned int flags),
+	TP_ARGS(fdin, fdout, len, flags),
+	TP_STRUCT__entry(__field(int, fdin) __field(int, fdout) __field(size_t, len) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fdin, fdin) tp_assign(fdout, fdout) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mremap
+SC_TRACE_EVENT(sys_mremap,
+	TP_PROTO(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr),
+	TP_ARGS(addr, old_len, new_len, flags, new_addr),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, old_len) __field(unsigned long, new_len) __field(unsigned long, flags) __field_hex(unsigned long, new_addr)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(old_len, old_len) tp_assign(new_len, new_len) tp_assign(flags, flags) tp_assign(new_addr, new_addr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_prctl
+SC_TRACE_EVENT(sys_prctl,
+	TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5),
+	TP_ARGS(option, arg2, arg3, arg4, arg5),
+	TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)),
+	TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_remap_file_pages
+SC_TRACE_EVENT(sys_remap_file_pages,
+	TP_PROTO(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags),
+	TP_ARGS(start, size, prot, pgoff, flags),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, size) __field(unsigned long, prot) __field(unsigned long, pgoff) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(size, size) tp_assign(prot, prot) tp_assign(pgoff, pgoff) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mmap
+SC_TRACE_EVENT(sys_mmap,
+	TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off),
+	TP_ARGS(addr, len, prot, flags, fd, off),
+	TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, prot) __field(unsigned long, flags) __field(unsigned long, fd) __field(unsigned long, off)),
+	TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(off, off)),
+	TP_printk()
+)
+#endif
+
+#endif /*  _TRACE_SYSCALLS_INTEGERS_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
+#else /* CREATE_SYSCALL_TABLE */
+
+#include "x86-64-syscalls-3.0.4_integers_override.h"
+
+#ifndef OVERRIDE_TABLE_sys_sched_yield
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 24, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pause
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 34, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 39, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getuid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 102, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 104, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_geteuid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 107, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getegid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 108, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getppid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 110, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpgrp
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 111, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setsid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 112, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munlockall
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 152, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_vhangup
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 153, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sync
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 162, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_gettid
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 186, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_restart_syscall
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 219, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_init
+TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 253, 0)
+#endif
+#ifndef OVERRIDE_TABLE_sys_close
+TRACE_SYSCALL_TABLE(sys_close, sys_close, 3, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lseek
+TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 8, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mmap
+TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 9, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mprotect
+TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 10, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munmap
+TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 11, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_brk
+TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 12, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioctl
+TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 16, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mremap
+TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 25, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msync
+TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 26, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_madvise
+TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 28, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_shmget
+TRACE_SYSCALL_TABLE(sys_shmget, sys_shmget, 29, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup
+TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 32, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup2
+TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 33, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_alarm
+TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 37, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_socket
+TRACE_SYSCALL_TABLE(sys_socket, sys_socket, 41, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_shutdown
+TRACE_SYSCALL_TABLE(sys_shutdown, sys_shutdown, 48, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_listen
+TRACE_SYSCALL_TABLE(sys_listen, sys_listen, 50, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_exit
+TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 60, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_kill
+TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 62, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_semget
+TRACE_SYSCALL_TABLE(sys_semget, sys_semget, 64, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msgget
+TRACE_SYSCALL_TABLE(sys_msgget, sys_msgget, 68, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fcntl
+TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 72, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_flock
+TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 73, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fsync
+TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 74, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fdatasync
+TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 75, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ftruncate
+TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 77, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchdir
+TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 81, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchmod
+TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 91, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchown
+TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 93, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_umask
+TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 95, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ptrace
+TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 101, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setuid
+TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 105, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgid
+TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 106, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setpgid
+TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 109, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setreuid
+TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 113, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setregid
+TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 114, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresuid
+TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 117, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setresgid
+TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 119, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpgid
+TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 121, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsuid
+TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 122, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setfsgid
+TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 123, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getsid
+TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 124, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_personality
+TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 135, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysfs
+TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 139, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpriority
+TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 140, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setpriority
+TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 141, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getscheduler
+TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 145, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_get_priority_max
+TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 146, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_get_priority_min
+TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 147, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mlock
+TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 149, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_munlock
+TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 150, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mlockall
+TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 151, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_prctl
+TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 157, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tkill
+TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 200, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_destroy
+TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 207, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_create
+TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 213, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_remap_file_pages
+TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 216, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_getoverrun
+TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 225, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_delete
+TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 226, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_exit_group
+TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 231, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tgkill
+TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 234, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioprio_set
+TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 251, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ioprio_get
+TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 252, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_rm_watch
+TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 255, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unshare
+TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 272, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_tee
+TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 276, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_create
+TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 283, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_eventfd
+TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 284, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_eventfd2
+TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 290, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_create1
+TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 291, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_dup3
+TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 292, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_init1
+TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 294, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_syncfs
+TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 306, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setns
+TRACE_SYSCALL_TABLE(sys_setns, sys_setns, 308, 2)
+#endif
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h
new file mode 100644
index 0000000..e69de29
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h
new file mode 100644
index 0000000..8de6edf
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h
@@ -0,0 +1,2074 @@
+/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */
+#ifndef CREATE_SYSCALL_TABLE
+
+#if !defined(_TRACE_SYSCALLS_POINTERS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_POINTERS_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+#include "x86-64-syscalls-3.0.4_pointers_override.h"
+
+#ifndef OVERRIDE_sys_pipe
+SC_TRACE_EVENT(sys_pipe,
+	TP_PROTO(int * fildes),
+	TP_ARGS(fildes),
+	TP_STRUCT__entry(__field_hex(int *, fildes)),
+	TP_fast_assign(tp_assign(fildes, fildes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newuname
+SC_TRACE_EVENT(sys_newuname,
+	TP_PROTO(struct new_utsname * name),
+	TP_ARGS(name),
+	TP_STRUCT__entry(__field_hex(struct new_utsname *, name)),
+	TP_fast_assign(tp_assign(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_shmdt
+SC_TRACE_EVENT(sys_shmdt,
+	TP_PROTO(char * shmaddr),
+	TP_ARGS(shmaddr),
+	TP_STRUCT__entry(__field_hex(char *, shmaddr)),
+	TP_fast_assign(tp_assign(shmaddr, shmaddr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chdir
+SC_TRACE_EVENT(sys_chdir,
+	TP_PROTO(const char * filename),
+	TP_ARGS(filename),
+	TP_STRUCT__entry(__string_from_user(filename, filename)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rmdir
+SC_TRACE_EVENT(sys_rmdir,
+	TP_PROTO(const char * pathname),
+	TP_ARGS(pathname),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_unlink
+SC_TRACE_EVENT(sys_unlink,
+	TP_PROTO(const char * pathname),
+	TP_ARGS(pathname),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysinfo
+SC_TRACE_EVENT(sys_sysinfo,
+	TP_PROTO(struct sysinfo * info),
+	TP_ARGS(info),
+	TP_STRUCT__entry(__field_hex(struct sysinfo *, info)),
+	TP_fast_assign(tp_assign(info, info)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_times
+SC_TRACE_EVENT(sys_times,
+	TP_PROTO(struct tms * tbuf),
+	TP_ARGS(tbuf),
+	TP_STRUCT__entry(__field_hex(struct tms *, tbuf)),
+	TP_fast_assign(tp_assign(tbuf, tbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sysctl
+SC_TRACE_EVENT(sys_sysctl,
+	TP_PROTO(struct __sysctl_args * args),
+	TP_ARGS(args),
+	TP_STRUCT__entry(__field_hex(struct __sysctl_args *, args)),
+	TP_fast_assign(tp_assign(args, args)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_adjtimex
+SC_TRACE_EVENT(sys_adjtimex,
+	TP_PROTO(struct timex * txc_p),
+	TP_ARGS(txc_p),
+	TP_STRUCT__entry(__field_hex(struct timex *, txc_p)),
+	TP_fast_assign(tp_assign(txc_p, txc_p)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chroot
+SC_TRACE_EVENT(sys_chroot,
+	TP_PROTO(const char * filename),
+	TP_ARGS(filename),
+	TP_STRUCT__entry(__string_from_user(filename, filename)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_swapoff
+SC_TRACE_EVENT(sys_swapoff,
+	TP_PROTO(const char * specialfile),
+	TP_ARGS(specialfile),
+	TP_STRUCT__entry(__string_from_user(specialfile, specialfile)),
+	TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_time
+SC_TRACE_EVENT(sys_time,
+	TP_PROTO(time_t * tloc),
+	TP_ARGS(tloc),
+	TP_STRUCT__entry(__field_hex(time_t *, tloc)),
+	TP_fast_assign(tp_assign(tloc, tloc)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_set_tid_address
+SC_TRACE_EVENT(sys_set_tid_address,
+	TP_PROTO(int * tidptr),
+	TP_ARGS(tidptr),
+	TP_STRUCT__entry(__field_hex(int *, tidptr)),
+	TP_fast_assign(tp_assign(tidptr, tidptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_unlink
+SC_TRACE_EVENT(sys_mq_unlink,
+	TP_PROTO(const char * u_name),
+	TP_ARGS(u_name),
+	TP_STRUCT__entry(__string_from_user(u_name, u_name)),
+	TP_fast_assign(tp_copy_string_from_user(u_name, u_name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newstat
+SC_TRACE_EVENT(sys_newstat,
+	TP_PROTO(const char * filename, struct stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newfstat
+SC_TRACE_EVENT(sys_newfstat,
+	TP_PROTO(unsigned int fd, struct stat * statbuf),
+	TP_ARGS(fd, statbuf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newlstat
+SC_TRACE_EVENT(sys_newlstat,
+	TP_PROTO(const char * filename, struct stat * statbuf),
+	TP_ARGS(filename, statbuf),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_access
+SC_TRACE_EVENT(sys_access,
+	TP_PROTO(const char * filename, int mode),
+	TP_ARGS(filename, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_nanosleep
+SC_TRACE_EVENT(sys_nanosleep,
+	TP_PROTO(struct timespec * rqtp, struct timespec * rmtp),
+	TP_ARGS(rqtp, rmtp),
+	TP_STRUCT__entry(__field_hex(struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)),
+	TP_fast_assign(tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getitimer
+SC_TRACE_EVENT(sys_getitimer,
+	TP_PROTO(int which, struct itimerval * value),
+	TP_ARGS(which, value),
+	TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(value, value)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_truncate
+SC_TRACE_EVENT(sys_truncate,
+	TP_PROTO(const char * path, long length),
+	TP_ARGS(path, length),
+	TP_STRUCT__entry(__string_from_user(path, path) __field(long, length)),
+	TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(length, length)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getcwd
+SC_TRACE_EVENT(sys_getcwd,
+	TP_PROTO(char * buf, unsigned long size),
+	TP_ARGS(buf, size),
+	TP_STRUCT__entry(__field_hex(char *, buf) __field(unsigned long, size)),
+	TP_fast_assign(tp_assign(buf, buf) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rename
+SC_TRACE_EVENT(sys_rename,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mkdir
+SC_TRACE_EVENT(sys_mkdir,
+	TP_PROTO(const char * pathname, int mode),
+	TP_ARGS(pathname, mode),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_creat
+SC_TRACE_EVENT(sys_creat,
+	TP_PROTO(const char * pathname, int mode),
+	TP_ARGS(pathname, mode),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_link
+SC_TRACE_EVENT(sys_link,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_symlink
+SC_TRACE_EVENT(sys_symlink,
+	TP_PROTO(const char * oldname, const char * newname),
+	TP_ARGS(oldname, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chmod
+SC_TRACE_EVENT(sys_chmod,
+	TP_PROTO(const char * filename, mode_t mode),
+	TP_ARGS(filename, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(mode_t, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_gettimeofday
+SC_TRACE_EVENT(sys_gettimeofday,
+	TP_PROTO(struct timeval * tv, struct timezone * tz),
+	TP_ARGS(tv, tz),
+	TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)),
+	TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getrlimit
+SC_TRACE_EVENT(sys_getrlimit,
+	TP_PROTO(unsigned int resource, struct rlimit * rlim),
+	TP_ARGS(resource, rlim),
+	TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)),
+	TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getrusage
+SC_TRACE_EVENT(sys_getrusage,
+	TP_PROTO(int who, struct rusage * ru),
+	TP_ARGS(who, ru),
+	TP_STRUCT__entry(__field(int, who) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(who, who) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getgroups
+SC_TRACE_EVENT(sys_getgroups,
+	TP_PROTO(int gidsetsize, gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setgroups
+SC_TRACE_EVENT(sys_setgroups,
+	TP_PROTO(int gidsetsize, gid_t * grouplist),
+	TP_ARGS(gidsetsize, grouplist),
+	TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)),
+	TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigpending
+SC_TRACE_EVENT(sys_rt_sigpending,
+	TP_PROTO(sigset_t * set, size_t sigsetsize),
+	TP_ARGS(set, sigsetsize),
+	TP_STRUCT__entry(__field_hex(sigset_t *, set) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(set, set) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigsuspend
+SC_TRACE_EVENT(sys_rt_sigsuspend,
+	TP_PROTO(sigset_t * unewset, size_t sigsetsize),
+	TP_ARGS(unewset, sigsetsize),
+	TP_STRUCT__entry(__field_hex(sigset_t *, unewset) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(unewset, unewset) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utime
+SC_TRACE_EVENT(sys_utime,
+	TP_PROTO(char * filename, struct utimbuf * times),
+	TP_ARGS(filename, times),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct utimbuf *, times)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(times, times)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ustat
+SC_TRACE_EVENT(sys_ustat,
+	TP_PROTO(unsigned dev, struct ustat * ubuf),
+	TP_ARGS(dev, ubuf),
+	TP_STRUCT__entry(__field(unsigned, dev) __field_hex(struct ustat *, ubuf)),
+	TP_fast_assign(tp_assign(dev, dev) tp_assign(ubuf, ubuf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_statfs
+SC_TRACE_EVENT(sys_statfs,
+	TP_PROTO(const char * pathname, struct statfs * buf),
+	TP_ARGS(pathname, buf),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(struct statfs *, buf)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fstatfs
+SC_TRACE_EVENT(sys_fstatfs,
+	TP_PROTO(unsigned int fd, struct statfs * buf),
+	TP_ARGS(fd, buf),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct statfs *, buf)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setparam
+SC_TRACE_EVENT(sys_sched_setparam,
+	TP_PROTO(pid_t pid, struct sched_param * param),
+	TP_ARGS(pid, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getparam
+SC_TRACE_EVENT(sys_sched_getparam,
+	TP_PROTO(pid_t pid, struct sched_param * param),
+	TP_ARGS(pid, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_rr_get_interval
+SC_TRACE_EVENT(sys_sched_rr_get_interval,
+	TP_PROTO(pid_t pid, struct timespec * interval),
+	TP_ARGS(pid, interval),
+	TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct timespec *, interval)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(interval, interval)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pivot_root
+SC_TRACE_EVENT(sys_pivot_root,
+	TP_PROTO(const char * new_root, const char * put_old),
+	TP_ARGS(new_root, put_old),
+	TP_STRUCT__entry(__string_from_user(new_root, new_root) __string_from_user(put_old, put_old)),
+	TP_fast_assign(tp_copy_string_from_user(new_root, new_root) tp_copy_string_from_user(put_old, put_old)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setrlimit
+SC_TRACE_EVENT(sys_setrlimit,
+	TP_PROTO(unsigned int resource, struct rlimit * rlim),
+	TP_ARGS(resource, rlim),
+	TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)),
+	TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_settimeofday
+SC_TRACE_EVENT(sys_settimeofday,
+	TP_PROTO(struct timeval * tv, struct timezone * tz),
+	TP_ARGS(tv, tz),
+	TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)),
+	TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_umount
+SC_TRACE_EVENT(sys_umount,
+	TP_PROTO(char * name, int flags),
+	TP_ARGS(name, flags),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_swapon
+SC_TRACE_EVENT(sys_swapon,
+	TP_PROTO(const char * specialfile, int swap_flags),
+	TP_ARGS(specialfile, swap_flags),
+	TP_STRUCT__entry(__string_from_user(specialfile, specialfile) __field(int, swap_flags)),
+	TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile) tp_assign(swap_flags, swap_flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sethostname
+SC_TRACE_EVENT(sys_sethostname,
+	TP_PROTO(char * name, int len),
+	TP_ARGS(name, len),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setdomainname
+SC_TRACE_EVENT(sys_setdomainname,
+	TP_PROTO(char * name, int len),
+	TP_ARGS(name, len),
+	TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)),
+	TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_delete_module
+SC_TRACE_EVENT(sys_delete_module,
+	TP_PROTO(const char * name_user, unsigned int flags),
+	TP_ARGS(name_user, flags),
+	TP_STRUCT__entry(__string_from_user(name_user, name_user) __field(unsigned int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(name_user, name_user) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_removexattr
+SC_TRACE_EVENT(sys_removexattr,
+	TP_PROTO(const char * pathname, const char * name),
+	TP_ARGS(pathname, name),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lremovexattr
+SC_TRACE_EVENT(sys_lremovexattr,
+	TP_PROTO(const char * pathname, const char * name),
+	TP_ARGS(pathname, name),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fremovexattr
+SC_TRACE_EVENT(sys_fremovexattr,
+	TP_PROTO(int fd, const char * name),
+	TP_ARGS(fd, name),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_setup
+SC_TRACE_EVENT(sys_io_setup,
+	TP_PROTO(unsigned nr_events, aio_context_t * ctxp),
+	TP_ARGS(nr_events, ctxp),
+	TP_STRUCT__entry(__field(unsigned, nr_events) __field_hex(aio_context_t *, ctxp)),
+	TP_fast_assign(tp_assign(nr_events, nr_events) tp_assign(ctxp, ctxp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_gettime
+SC_TRACE_EVENT(sys_timer_gettime,
+	TP_PROTO(timer_t timer_id, struct itimerspec * setting),
+	TP_ARGS(timer_id, setting),
+	TP_STRUCT__entry(__field(timer_t, timer_id) __field_hex(struct itimerspec *, setting)),
+	TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(setting, setting)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_settime
+SC_TRACE_EVENT(sys_clock_settime,
+	TP_PROTO(const clockid_t which_clock, const struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(const struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_gettime
+SC_TRACE_EVENT(sys_clock_gettime,
+	TP_PROTO(const clockid_t which_clock, struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_getres
+SC_TRACE_EVENT(sys_clock_getres,
+	TP_PROTO(const clockid_t which_clock, struct timespec * tp),
+	TP_ARGS(which_clock, tp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utimes
+SC_TRACE_EVENT(sys_utimes,
+	TP_PROTO(char * filename, struct timeval * utimes),
+	TP_ARGS(filename, utimes),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct timeval *, utimes)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_notify
+SC_TRACE_EVENT(sys_mq_notify,
+	TP_PROTO(mqd_t mqdes, const struct sigevent * u_notification),
+	TP_ARGS(mqdes, u_notification),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct sigevent *, u_notification)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_notification, u_notification)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_set_robust_list
+SC_TRACE_EVENT(sys_set_robust_list,
+	TP_PROTO(struct robust_list_head * head, size_t len),
+	TP_ARGS(head, len),
+	TP_STRUCT__entry(__field_hex(struct robust_list_head *, head) __field(size_t, len)),
+	TP_fast_assign(tp_assign(head, head) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_gettime
+SC_TRACE_EVENT(sys_timerfd_gettime,
+	TP_PROTO(int ufd, struct itimerspec * otmr),
+	TP_ARGS(ufd, otmr),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(struct itimerspec *, otmr)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(otmr, otmr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pipe2
+SC_TRACE_EVENT(sys_pipe2,
+	TP_PROTO(int * fildes, int flags),
+	TP_ARGS(fildes, flags),
+	TP_STRUCT__entry(__field_hex(int *, fildes) __field(int, flags)),
+	TP_fast_assign(tp_assign(fildes, fildes) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_adjtime
+SC_TRACE_EVENT(sys_clock_adjtime,
+	TP_PROTO(const clockid_t which_clock, struct timex * utx),
+	TP_ARGS(which_clock, utx),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timex *, utx)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(utx, utx)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_read
+SC_TRACE_EVENT(sys_read,
+	TP_PROTO(unsigned int fd, char * buf, size_t count),
+	TP_ARGS(fd, buf, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(char *, buf) __field(size_t, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_write
+SC_TRACE_EVENT(sys_write,
+	TP_PROTO(unsigned int fd, const char * buf, size_t count),
+	TP_ARGS(fd, buf, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(const char *, buf) __field(size_t, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_open
+SC_TRACE_EVENT(sys_open,
+	TP_PROTO(const char * filename, int flags, int mode),
+	TP_ARGS(filename, flags, mode),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, flags) __field(int, mode)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_poll
+SC_TRACE_EVENT(sys_poll,
+	TP_PROTO(struct pollfd * ufds, unsigned int nfds, long timeout_msecs),
+	TP_ARGS(ufds, nfds, timeout_msecs),
+	TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field(long, timeout_msecs)),
+	TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(timeout_msecs, timeout_msecs)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readv
+SC_TRACE_EVENT(sys_readv,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen),
+	TP_ARGS(fd, vec, vlen),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_writev
+SC_TRACE_EVENT(sys_writev,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen),
+	TP_ARGS(fd, vec, vlen),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mincore
+SC_TRACE_EVENT(sys_mincore,
+	TP_PROTO(unsigned long start, size_t len, unsigned char * vec),
+	TP_ARGS(start, len, vec),
+	TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field_hex(unsigned char *, vec)),
+	TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(vec, vec)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_shmat
+SC_TRACE_EVENT(sys_shmat,
+	TP_PROTO(int shmid, char * shmaddr, int shmflg),
+	TP_ARGS(shmid, shmaddr, shmflg),
+	TP_STRUCT__entry(__field(int, shmid) __field_hex(char *, shmaddr) __field(int, shmflg)),
+	TP_fast_assign(tp_assign(shmid, shmid) tp_assign(shmaddr, shmaddr) tp_assign(shmflg, shmflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_shmctl
+SC_TRACE_EVENT(sys_shmctl,
+	TP_PROTO(int shmid, int cmd, struct shmid_ds * buf),
+	TP_ARGS(shmid, cmd, buf),
+	TP_STRUCT__entry(__field(int, shmid) __field(int, cmd) __field_hex(struct shmid_ds *, buf)),
+	TP_fast_assign(tp_assign(shmid, shmid) tp_assign(cmd, cmd) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setitimer
+SC_TRACE_EVENT(sys_setitimer,
+	TP_PROTO(int which, struct itimerval * value, struct itimerval * ovalue),
+	TP_ARGS(which, value, ovalue),
+	TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value) __field_hex(struct itimerval *, ovalue)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(value, value) tp_assign(ovalue, ovalue)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_connect
+SC_TRACE_EVENT(sys_connect,
+	TP_PROTO(int fd, struct sockaddr * uservaddr, int addrlen),
+	TP_ARGS(fd, uservaddr, addrlen),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, uservaddr) __field_hex(int, addrlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(uservaddr, uservaddr) tp_assign(addrlen, addrlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_accept
+SC_TRACE_EVENT(sys_accept,
+	TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen),
+	TP_ARGS(fd, upeer_sockaddr, upeer_addrlen),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendmsg
+SC_TRACE_EVENT(sys_sendmsg,
+	TP_PROTO(int fd, struct msghdr * msg, unsigned flags),
+	TP_ARGS(fd, msg, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_recvmsg
+SC_TRACE_EVENT(sys_recvmsg,
+	TP_PROTO(int fd, struct msghdr * msg, unsigned int flags),
+	TP_ARGS(fd, msg, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_bind
+SC_TRACE_EVENT(sys_bind,
+	TP_PROTO(int fd, struct sockaddr * umyaddr, int addrlen),
+	TP_ARGS(fd, umyaddr, addrlen),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, umyaddr) __field_hex(int, addrlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(umyaddr, umyaddr) tp_assign(addrlen, addrlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getsockname
+SC_TRACE_EVENT(sys_getsockname,
+	TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len),
+	TP_ARGS(fd, usockaddr, usockaddr_len),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getpeername
+SC_TRACE_EVENT(sys_getpeername,
+	TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len),
+	TP_ARGS(fd, usockaddr, usockaddr_len),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_semop
+SC_TRACE_EVENT(sys_semop,
+	TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops),
+	TP_ARGS(semid, tsops, nsops),
+	TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops)),
+	TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msgctl
+SC_TRACE_EVENT(sys_msgctl,
+	TP_PROTO(int msqid, int cmd, struct msqid_ds * buf),
+	TP_ARGS(msqid, cmd, buf),
+	TP_STRUCT__entry(__field(int, msqid) __field(int, cmd) __field_hex(struct msqid_ds *, buf)),
+	TP_fast_assign(tp_assign(msqid, msqid) tp_assign(cmd, cmd) tp_assign(buf, buf)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getdents
+SC_TRACE_EVENT(sys_getdents,
+	TP_PROTO(unsigned int fd, struct linux_dirent * dirent, unsigned int count),
+	TP_ARGS(fd, dirent, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent *, dirent) __field(unsigned int, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readlink
+SC_TRACE_EVENT(sys_readlink,
+	TP_PROTO(const char * path, char * buf, int bufsiz),
+	TP_ARGS(path, buf, bufsiz),
+	TP_STRUCT__entry(__string_from_user(path, path) __field_hex(char *, buf) __field(int, bufsiz)),
+	TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_chown
+SC_TRACE_EVENT(sys_chown,
+	TP_PROTO(const char * filename, uid_t user, gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lchown
+SC_TRACE_EVENT(sys_lchown,
+	TP_PROTO(const char * filename, uid_t user, gid_t group),
+	TP_ARGS(filename, user, group),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_syslog
+SC_TRACE_EVENT(sys_syslog,
+	TP_PROTO(int type, char * buf, int len),
+	TP_ARGS(type, buf, len),
+	TP_STRUCT__entry(__field(int, type) __field_hex(char *, buf) __field(int, len)),
+	TP_fast_assign(tp_assign(type, type) tp_assign(buf, buf) tp_assign(len, len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresuid
+SC_TRACE_EVENT(sys_getresuid,
+	TP_PROTO(uid_t * ruid, uid_t * euid, uid_t * suid),
+	TP_ARGS(ruid, euid, suid),
+	TP_STRUCT__entry(__field_hex(uid_t *, ruid) __field_hex(uid_t *, euid) __field_hex(uid_t *, suid)),
+	TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getresgid
+SC_TRACE_EVENT(sys_getresgid,
+	TP_PROTO(gid_t * rgid, gid_t * egid, gid_t * sgid),
+	TP_ARGS(rgid, egid, sgid),
+	TP_STRUCT__entry(__field_hex(gid_t *, rgid) __field_hex(gid_t *, egid) __field_hex(gid_t *, sgid)),
+	TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigqueueinfo
+SC_TRACE_EVENT(sys_rt_sigqueueinfo,
+	TP_PROTO(pid_t pid, int sig, siginfo_t * uinfo),
+	TP_ARGS(pid, sig, uinfo),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mknod
+SC_TRACE_EVENT(sys_mknod,
+	TP_PROTO(const char * filename, int mode, unsigned dev),
+	TP_ARGS(filename, mode, dev),
+	TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)),
+	TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setscheduler
+SC_TRACE_EVENT(sys_sched_setscheduler,
+	TP_PROTO(pid_t pid, int policy, struct sched_param * param),
+	TP_ARGS(pid, policy, param),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(int, policy) __field_hex(struct sched_param *, param)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(policy, policy) tp_assign(param, param)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_init_module
+SC_TRACE_EVENT(sys_init_module,
+	TP_PROTO(void * umod, unsigned long len, const char * uargs),
+	TP_ARGS(umod, len, uargs),
+	TP_STRUCT__entry(__field_hex(void *, umod) __field(unsigned long, len) __field_hex(const char *, uargs)),
+	TP_fast_assign(tp_assign(umod, umod) tp_assign(len, len) tp_assign(uargs, uargs)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_nfsservctl
+SC_TRACE_EVENT(sys_nfsservctl,
+	TP_PROTO(int cmd, struct nfsctl_arg * arg, void * res),
+	TP_ARGS(cmd, arg, res),
+	TP_STRUCT__entry(__field(int, cmd) __field_hex(struct nfsctl_arg *, arg) __field_hex(void *, res)),
+	TP_fast_assign(tp_assign(cmd, cmd) tp_assign(arg, arg) tp_assign(res, res)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_listxattr
+SC_TRACE_EVENT(sys_listxattr,
+	TP_PROTO(const char * pathname, char * list, size_t size),
+	TP_ARGS(pathname, list, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_llistxattr
+SC_TRACE_EVENT(sys_llistxattr,
+	TP_PROTO(const char * pathname, char * list, size_t size),
+	TP_ARGS(pathname, list, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_flistxattr
+SC_TRACE_EVENT(sys_flistxattr,
+	TP_PROTO(int fd, char * list, size_t size),
+	TP_ARGS(fd, list, size),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(char *, list) __field(size_t, size)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(list, list) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_setaffinity
+SC_TRACE_EVENT(sys_sched_setaffinity,
+	TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr),
+	TP_ARGS(pid, len, user_mask_ptr),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sched_getaffinity
+SC_TRACE_EVENT(sys_sched_getaffinity,
+	TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr),
+	TP_ARGS(pid, len, user_mask_ptr),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_submit
+SC_TRACE_EVENT(sys_io_submit,
+	TP_PROTO(aio_context_t ctx_id, long nr, struct iocb * * iocbpp),
+	TP_ARGS(ctx_id, nr, iocbpp),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, nr) __field_hex(struct iocb * *, iocbpp)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(nr, nr) tp_assign(iocbpp, iocbpp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_cancel
+SC_TRACE_EVENT(sys_io_cancel,
+	TP_PROTO(aio_context_t ctx_id, struct iocb * iocb, struct io_event * result),
+	TP_ARGS(ctx_id, iocb, result),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field_hex(struct iocb *, iocb) __field_hex(struct io_event *, result)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(iocb, iocb) tp_assign(result, result)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getdents64
+SC_TRACE_EVENT(sys_getdents64,
+	TP_PROTO(unsigned int fd, struct linux_dirent64 * dirent, unsigned int count),
+	TP_ARGS(fd, dirent, count),
+	TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent64 *, dirent) __field(unsigned int, count)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_create
+SC_TRACE_EVENT(sys_timer_create,
+	TP_PROTO(const clockid_t which_clock, struct sigevent * timer_event_spec, timer_t * created_timer_id),
+	TP_ARGS(which_clock, timer_event_spec, created_timer_id),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct sigevent *, timer_event_spec) __field_hex(timer_t *, created_timer_id)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(timer_event_spec, timer_event_spec) tp_assign(created_timer_id, created_timer_id)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_getsetattr
+SC_TRACE_EVENT(sys_mq_getsetattr,
+	TP_PROTO(mqd_t mqdes, const struct mq_attr * u_mqstat, struct mq_attr * u_omqstat),
+	TP_ARGS(mqdes, u_mqstat, u_omqstat),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct mq_attr *, u_mqstat) __field_hex(struct mq_attr *, u_omqstat)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_mqstat, u_mqstat) tp_assign(u_omqstat, u_omqstat)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_inotify_add_watch
+SC_TRACE_EVENT(sys_inotify_add_watch,
+	TP_PROTO(int fd, const char * pathname, u32 mask),
+	TP_ARGS(fd, pathname, mask),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(pathname, pathname) __field(u32, mask)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(pathname, pathname) tp_assign(mask, mask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mkdirat
+SC_TRACE_EVENT(sys_mkdirat,
+	TP_PROTO(int dfd, const char * pathname, int mode),
+	TP_ARGS(dfd, pathname, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_futimesat
+SC_TRACE_EVENT(sys_futimesat,
+	TP_PROTO(int dfd, const char * filename, struct timeval * utimes),
+	TP_ARGS(dfd, filename, utimes),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timeval *, utimes)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_unlinkat
+SC_TRACE_EVENT(sys_unlinkat,
+	TP_PROTO(int dfd, const char * pathname, int flag),
+	TP_ARGS(dfd, pathname, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_symlinkat
+SC_TRACE_EVENT(sys_symlinkat,
+	TP_PROTO(const char * oldname, int newdfd, const char * newname),
+	TP_ARGS(oldname, newdfd, newname),
+	TP_STRUCT__entry(__string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchmodat
+SC_TRACE_EVENT(sys_fchmodat,
+	TP_PROTO(int dfd, const char * filename, mode_t mode),
+	TP_ARGS(dfd, filename, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(mode_t, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_faccessat
+SC_TRACE_EVENT(sys_faccessat,
+	TP_PROTO(int dfd, const char * filename, int mode),
+	TP_ARGS(dfd, filename, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_get_robust_list
+SC_TRACE_EVENT(sys_get_robust_list,
+	TP_PROTO(int pid, struct robust_list_head * * head_ptr, size_t * len_ptr),
+	TP_ARGS(pid, head_ptr, len_ptr),
+	TP_STRUCT__entry(__field(int, pid) __field_hex(struct robust_list_head * *, head_ptr) __field_hex(size_t *, len_ptr)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(head_ptr, head_ptr) tp_assign(len_ptr, len_ptr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_signalfd
+SC_TRACE_EVENT(sys_signalfd,
+	TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask),
+	TP_ARGS(ufd, user_mask, sizemask),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigaction
+SC_TRACE_EVENT(sys_rt_sigaction,
+	TP_PROTO(int sig, const struct sigaction * act, struct sigaction * oact, size_t sigsetsize),
+	TP_ARGS(sig, act, oact, sigsetsize),
+	TP_STRUCT__entry(__field(int, sig) __field_hex(const struct sigaction *, act) __field_hex(struct sigaction *, oact) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(sig, sig) tp_assign(act, act) tp_assign(oact, oact) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigprocmask
+SC_TRACE_EVENT(sys_rt_sigprocmask,
+	TP_PROTO(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize),
+	TP_ARGS(how, nset, oset, sigsetsize),
+	TP_STRUCT__entry(__field(int, how) __field_hex(sigset_t *, nset) __field_hex(sigset_t *, oset) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendfile64
+SC_TRACE_EVENT(sys_sendfile64,
+	TP_PROTO(int out_fd, int in_fd, loff_t * offset, size_t count),
+	TP_ARGS(out_fd, in_fd, offset, count),
+	TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(loff_t *, offset) __field(size_t, count)),
+	TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_socketpair
+SC_TRACE_EVENT(sys_socketpair,
+	TP_PROTO(int family, int type, int protocol, int * usockvec),
+	TP_ARGS(family, type, protocol, usockvec),
+	TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol) __field_hex(int *, usockvec)),
+	TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol) tp_assign(usockvec, usockvec)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_wait4
+SC_TRACE_EVENT(sys_wait4,
+	TP_PROTO(pid_t upid, int * stat_addr, int options, struct rusage * ru),
+	TP_ARGS(upid, stat_addr, options, ru),
+	TP_STRUCT__entry(__field(pid_t, upid) __field_hex(int *, stat_addr) __field(int, options) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(upid, upid) tp_assign(stat_addr, stat_addr) tp_assign(options, options) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msgsnd
+SC_TRACE_EVENT(sys_msgsnd,
+	TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, int msgflg),
+	TP_ARGS(msqid, msgp, msgsz, msgflg),
+	TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(int, msgflg)),
+	TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgflg, msgflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_sigtimedwait
+SC_TRACE_EVENT(sys_rt_sigtimedwait,
+	TP_PROTO(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec * uts, size_t sigsetsize),
+	TP_ARGS(uthese, uinfo, uts, sigsetsize),
+	TP_STRUCT__entry(__field_hex(const sigset_t *, uthese) __field_hex(siginfo_t *, uinfo) __field_hex(const struct timespec *, uts) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(uthese, uthese) tp_assign(uinfo, uinfo) tp_assign(uts, uts) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_reboot
+SC_TRACE_EVENT(sys_reboot,
+	TP_PROTO(int magic1, int magic2, unsigned int cmd, void * arg),
+	TP_ARGS(magic1, magic2, cmd, arg),
+	TP_STRUCT__entry(__field(int, magic1) __field(int, magic2) __field(unsigned int, cmd) __field_hex(void *, arg)),
+	TP_fast_assign(tp_assign(magic1, magic1) tp_assign(magic2, magic2) tp_assign(cmd, cmd) tp_assign(arg, arg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getxattr
+SC_TRACE_EVENT(sys_getxattr,
+	TP_PROTO(const char * pathname, const char * name, void * value, size_t size),
+	TP_ARGS(pathname, name, value, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lgetxattr
+SC_TRACE_EVENT(sys_lgetxattr,
+	TP_PROTO(const char * pathname, const char * name, void * value, size_t size),
+	TP_ARGS(pathname, name, value, size),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fgetxattr
+SC_TRACE_EVENT(sys_fgetxattr,
+	TP_PROTO(int fd, const char * name, void * value, size_t size),
+	TP_ARGS(fd, name, value, size),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_semtimedop
+SC_TRACE_EVENT(sys_semtimedop,
+	TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops, const struct timespec * timeout),
+	TP_ARGS(semid, tsops, nsops, timeout),
+	TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops) __field_hex(const struct timespec *, timeout)),
+	TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timer_settime
+SC_TRACE_EVENT(sys_timer_settime,
+	TP_PROTO(timer_t timer_id, int flags, const struct itimerspec * new_setting, struct itimerspec * old_setting),
+	TP_ARGS(timer_id, flags, new_setting, old_setting),
+	TP_STRUCT__entry(__field(timer_t, timer_id) __field(int, flags) __field_hex(const struct itimerspec *, new_setting) __field_hex(struct itimerspec *, old_setting)),
+	TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(flags, flags) tp_assign(new_setting, new_setting) tp_assign(old_setting, old_setting)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_clock_nanosleep
+SC_TRACE_EVENT(sys_clock_nanosleep,
+	TP_PROTO(const clockid_t which_clock, int flags, const struct timespec * rqtp, struct timespec * rmtp),
+	TP_ARGS(which_clock, flags, rqtp, rmtp),
+	TP_STRUCT__entry(__field(const clockid_t, which_clock) __field(int, flags) __field_hex(const struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)),
+	TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(flags, flags) tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_wait
+SC_TRACE_EVENT(sys_epoll_wait,
+	TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout),
+	TP_ARGS(epfd, events, maxevents, timeout),
+	TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_ctl
+SC_TRACE_EVENT(sys_epoll_ctl,
+	TP_PROTO(int epfd, int op, int fd, struct epoll_event * event),
+	TP_ARGS(epfd, op, fd, event),
+	TP_STRUCT__entry(__field(int, epfd) __field(int, op) __field(int, fd) __field_hex(struct epoll_event *, event)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(op, op) tp_assign(fd, fd) tp_assign(event, event)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_open
+SC_TRACE_EVENT(sys_mq_open,
+	TP_PROTO(const char * u_name, int oflag, mode_t mode, struct mq_attr * u_attr),
+	TP_ARGS(u_name, oflag, mode, u_attr),
+	TP_STRUCT__entry(__string_from_user(u_name, u_name) __field(int, oflag) __field(mode_t, mode) __field_hex(struct mq_attr *, u_attr)),
+	TP_fast_assign(tp_copy_string_from_user(u_name, u_name) tp_assign(oflag, oflag) tp_assign(mode, mode) tp_assign(u_attr, u_attr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_kexec_load
+SC_TRACE_EVENT(sys_kexec_load,
+	TP_PROTO(unsigned long entry, unsigned long nr_segments, struct kexec_segment * segments, unsigned long flags),
+	TP_ARGS(entry, nr_segments, segments, flags),
+	TP_STRUCT__entry(__field(unsigned long, entry) __field(unsigned long, nr_segments) __field_hex(struct kexec_segment *, segments) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(entry, entry) tp_assign(nr_segments, nr_segments) tp_assign(segments, segments) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_openat
+SC_TRACE_EVENT(sys_openat,
+	TP_PROTO(int dfd, const char * filename, int flags, int mode),
+	TP_ARGS(dfd, filename, flags, mode),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, flags) __field(int, mode)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mknodat
+SC_TRACE_EVENT(sys_mknodat,
+	TP_PROTO(int dfd, const char * filename, int mode, unsigned dev),
+	TP_ARGS(dfd, filename, mode, dev),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_newfstatat
+SC_TRACE_EVENT(sys_newfstatat,
+	TP_PROTO(int dfd, const char * filename, struct stat * statbuf, int flag),
+	TP_ARGS(dfd, filename, statbuf, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct stat *, statbuf) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_renameat
+SC_TRACE_EVENT(sys_renameat,
+	TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname),
+	TP_ARGS(olddfd, oldname, newdfd, newname),
+	TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)),
+	TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_readlinkat
+SC_TRACE_EVENT(sys_readlinkat,
+	TP_PROTO(int dfd, const char * pathname, char * buf, int bufsiz),
+	TP_ARGS(dfd, pathname, buf, bufsiz),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field_hex(char *, buf) __field(int, bufsiz)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_vmsplice
+SC_TRACE_EVENT(sys_vmsplice,
+	TP_PROTO(int fd, const struct iovec * iov, unsigned long nr_segs, unsigned int flags),
+	TP_ARGS(fd, iov, nr_segs, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(const struct iovec *, iov) __field(unsigned long, nr_segs) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(iov, iov) tp_assign(nr_segs, nr_segs) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_utimensat
+SC_TRACE_EVENT(sys_utimensat,
+	TP_PROTO(int dfd, const char * filename, struct timespec * utimes, int flags),
+	TP_ARGS(dfd, filename, utimes, flags),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timespec *, utimes) __field(int, flags)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_timerfd_settime
+SC_TRACE_EVENT(sys_timerfd_settime,
+	TP_PROTO(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr),
+	TP_ARGS(ufd, flags, utmr, otmr),
+	TP_STRUCT__entry(__field(int, ufd) __field(int, flags) __field_hex(const struct itimerspec *, utmr) __field_hex(struct itimerspec *, otmr)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(flags, flags) tp_assign(utmr, utmr) tp_assign(otmr, otmr)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_accept4
+SC_TRACE_EVENT(sys_accept4,
+	TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen, int flags),
+	TP_ARGS(fd, upeer_sockaddr, upeer_addrlen, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen) __field(int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_signalfd4
+SC_TRACE_EVENT(sys_signalfd4,
+	TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask, int flags),
+	TP_ARGS(ufd, user_mask, sizemask, flags),
+	TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask) __field(int, flags)),
+	TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_rt_tgsigqueueinfo
+SC_TRACE_EVENT(sys_rt_tgsigqueueinfo,
+	TP_PROTO(pid_t tgid, pid_t pid, int sig, siginfo_t * uinfo),
+	TP_ARGS(tgid, pid, sig, uinfo),
+	TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)),
+	TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_prlimit64
+SC_TRACE_EVENT(sys_prlimit64,
+	TP_PROTO(pid_t pid, unsigned int resource, const struct rlimit64 * new_rlim, struct rlimit64 * old_rlim),
+	TP_ARGS(pid, resource, new_rlim, old_rlim),
+	TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, resource) __field_hex(const struct rlimit64 *, new_rlim) __field_hex(struct rlimit64 *, old_rlim)),
+	TP_fast_assign(tp_assign(pid, pid) tp_assign(resource, resource) tp_assign(new_rlim, new_rlim) tp_assign(old_rlim, old_rlim)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendmmsg
+SC_TRACE_EVENT(sys_sendmmsg,
+	TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags),
+	TP_ARGS(fd, mmsg, vlen, flags),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_select
+SC_TRACE_EVENT(sys_select,
+	TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timeval * tvp),
+	TP_ARGS(n, inp, outp, exp, tvp),
+	TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timeval *, tvp)),
+	TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tvp, tvp)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setsockopt
+SC_TRACE_EVENT(sys_setsockopt,
+	TP_PROTO(int fd, int level, int optname, char * optval, int optlen),
+	TP_ARGS(fd, level, optname, optval, optlen),
+	TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field(int, optlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_getsockopt
+SC_TRACE_EVENT(sys_getsockopt,
+	TP_PROTO(int fd, int level, int optname, char * optval, int * optlen),
+	TP_ARGS(fd, level, optname, optval, optlen),
+	TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field_hex(int *, optlen)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_msgrcv
+SC_TRACE_EVENT(sys_msgrcv,
+	TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, long msgtyp, int msgflg),
+	TP_ARGS(msqid, msgp, msgsz, msgtyp, msgflg),
+	TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(long, msgtyp) __field(int, msgflg)),
+	TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgtyp, msgtyp) tp_assign(msgflg, msgflg)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mount
+SC_TRACE_EVENT(sys_mount,
+	TP_PROTO(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data),
+	TP_ARGS(dev_name, dir_name, type, flags, data),
+	TP_STRUCT__entry(__string_from_user(dev_name, dev_name) __string_from_user(dir_name, dir_name) __string_from_user(type, type) __field(unsigned long, flags) __field_hex(void *, data)),
+	TP_fast_assign(tp_copy_string_from_user(dev_name, dev_name) tp_copy_string_from_user(dir_name, dir_name) tp_copy_string_from_user(type, type) tp_assign(flags, flags) tp_assign(data, data)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_setxattr
+SC_TRACE_EVENT(sys_setxattr,
+	TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(pathname, name, value, size, flags),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_lsetxattr
+SC_TRACE_EVENT(sys_lsetxattr,
+	TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(pathname, name, value, size, flags),
+	TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fsetxattr
+SC_TRACE_EVENT(sys_fsetxattr,
+	TP_PROTO(int fd, const char * name, const void * value, size_t size, int flags),
+	TP_ARGS(fd, name, value, size, flags),
+	TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)),
+	TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_io_getevents
+SC_TRACE_EVENT(sys_io_getevents,
+	TP_PROTO(aio_context_t ctx_id, long min_nr, long nr, struct io_event * events, struct timespec * timeout),
+	TP_ARGS(ctx_id, min_nr, nr, events, timeout),
+	TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, min_nr) __field(long, nr) __field_hex(struct io_event *, events) __field_hex(struct timespec *, timeout)),
+	TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(min_nr, min_nr) tp_assign(nr, nr) tp_assign(events, events) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_timedsend
+SC_TRACE_EVENT(sys_mq_timedsend,
+	TP_PROTO(mqd_t mqdes, const char * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec * u_abs_timeout),
+	TP_ARGS(mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const char *, u_msg_ptr) __field(size_t, msg_len) __field(unsigned int, msg_prio) __field_hex(const struct timespec *, u_abs_timeout)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(msg_prio, msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_mq_timedreceive
+SC_TRACE_EVENT(sys_mq_timedreceive,
+	TP_PROTO(mqd_t mqdes, char * u_msg_ptr, size_t msg_len, unsigned int * u_msg_prio, const struct timespec * u_abs_timeout),
+	TP_ARGS(mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout),
+	TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(char *, u_msg_ptr) __field(size_t, msg_len) __field_hex(unsigned int *, u_msg_prio) __field_hex(const struct timespec *, u_abs_timeout)),
+	TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(u_msg_prio, u_msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_waitid
+SC_TRACE_EVENT(sys_waitid,
+	TP_PROTO(int which, pid_t upid, struct siginfo * infop, int options, struct rusage * ru),
+	TP_ARGS(which, upid, infop, options, ru),
+	TP_STRUCT__entry(__field(int, which) __field(pid_t, upid) __field_hex(struct siginfo *, infop) __field(int, options) __field_hex(struct rusage *, ru)),
+	TP_fast_assign(tp_assign(which, which) tp_assign(upid, upid) tp_assign(infop, infop) tp_assign(options, options) tp_assign(ru, ru)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_fchownat
+SC_TRACE_EVENT(sys_fchownat,
+	TP_PROTO(int dfd, const char * filename, uid_t user, gid_t group, int flag),
+	TP_ARGS(dfd, filename, user, group, flag),
+	TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group) __field(int, flag)),
+	TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group) tp_assign(flag, flag)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_linkat
+SC_TRACE_EVENT(sys_linkat,
+	TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname, int flags),
+	TP_ARGS(olddfd, oldname, newdfd, newname, flags),
+	TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname) __field(int, flags)),
+	TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_ppoll
+SC_TRACE_EVENT(sys_ppoll,
+	TP_PROTO(struct pollfd * ufds, unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize),
+	TP_ARGS(ufds, nfds, tsp, sigmask, sigsetsize),
+	TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field_hex(struct timespec *, tsp) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(tsp, tsp) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_preadv
+SC_TRACE_EVENT(sys_preadv,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h),
+	TP_ARGS(fd, vec, vlen, pos_l, pos_h),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pwritev
+SC_TRACE_EVENT(sys_pwritev,
+	TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h),
+	TP_ARGS(fd, vec, vlen, pos_l, pos_h),
+	TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_perf_event_open
+SC_TRACE_EVENT(sys_perf_event_open,
+	TP_PROTO(struct perf_event_attr * attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags),
+	TP_ARGS(attr_uptr, pid, cpu, group_fd, flags),
+	TP_STRUCT__entry(__field_hex(struct perf_event_attr *, attr_uptr) __field(pid_t, pid) __field(int, cpu) __field(int, group_fd) __field(unsigned long, flags)),
+	TP_fast_assign(tp_assign(attr_uptr, attr_uptr) tp_assign(pid, pid) tp_assign(cpu, cpu) tp_assign(group_fd, group_fd) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_recvmmsg
+SC_TRACE_EVENT(sys_recvmmsg,
+	TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags, struct timespec * timeout),
+	TP_ARGS(fd, mmsg, vlen, flags, timeout),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags) __field_hex(struct timespec *, timeout)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags) tp_assign(timeout, timeout)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_sendto
+SC_TRACE_EVENT(sys_sendto,
+	TP_PROTO(int fd, void * buff, size_t len, unsigned flags, struct sockaddr * addr, int addr_len),
+	TP_ARGS(fd, buff, len, flags, addr, addr_len),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(void *, buff) __field(size_t, len) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int, addr_len)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(buff, buff) tp_assign(len, len) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_recvfrom
+SC_TRACE_EVENT(sys_recvfrom,
+	TP_PROTO(int fd, void * ubuf, size_t size, unsigned flags, struct sockaddr * addr, int * addr_len),
+	TP_ARGS(fd, ubuf, size, flags, addr, addr_len),
+	TP_STRUCT__entry(__field(int, fd) __field_hex(void *, ubuf) __field(size_t, size) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int *, addr_len)),
+	TP_fast_assign(tp_assign(fd, fd) tp_assign(ubuf, ubuf) tp_assign(size, size) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_futex
+SC_TRACE_EVENT(sys_futex,
+	TP_PROTO(u32 * uaddr, int op, u32 val, struct timespec * utime, u32 * uaddr2, u32 val3),
+	TP_ARGS(uaddr, op, val, utime, uaddr2, val3),
+	TP_STRUCT__entry(__field_hex(u32 *, uaddr) __field(int, op) __field(u32, val) __field_hex(struct timespec *, utime) __field_hex(u32 *, uaddr2) __field(u32, val3)),
+	TP_fast_assign(tp_assign(uaddr, uaddr) tp_assign(op, op) tp_assign(val, val) tp_assign(utime, utime) tp_assign(uaddr2, uaddr2) tp_assign(val3, val3)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_pselect6
+SC_TRACE_EVENT(sys_pselect6,
+	TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timespec * tsp, void * sig),
+	TP_ARGS(n, inp, outp, exp, tsp, sig),
+	TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timespec *, tsp) __field_hex(void *, sig)),
+	TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tsp, tsp) tp_assign(sig, sig)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_splice
+SC_TRACE_EVENT(sys_splice,
+	TP_PROTO(int fd_in, loff_t * off_in, int fd_out, loff_t * off_out, size_t len, unsigned int flags),
+	TP_ARGS(fd_in, off_in, fd_out, off_out, len, flags),
+	TP_STRUCT__entry(__field(int, fd_in) __field_hex(loff_t *, off_in) __field(int, fd_out) __field_hex(loff_t *, off_out) __field(size_t, len) __field(unsigned int, flags)),
+	TP_fast_assign(tp_assign(fd_in, fd_in) tp_assign(off_in, off_in) tp_assign(fd_out, fd_out) tp_assign(off_out, off_out) tp_assign(len, len) tp_assign(flags, flags)),
+	TP_printk()
+)
+#endif
+#ifndef OVERRIDE_sys_epoll_pwait
+SC_TRACE_EVENT(sys_epoll_pwait,
+	TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout, const sigset_t * sigmask, size_t sigsetsize),
+	TP_ARGS(epfd, events, maxevents, timeout, sigmask, sigsetsize),
+	TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)),
+	TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)),
+	TP_printk()
+)
+#endif
+
+#endif /*  _TRACE_SYSCALLS_POINTERS_H */
+
+/* This part must be outside protection */
+#include "../../../probes/define_trace.h"
+
+#else /* CREATE_SYSCALL_TABLE */
+
+#include "x86-64-syscalls-3.0.4_pointers_override.h"
+
+#ifndef OVERRIDE_TABLE_sys_read
+TRACE_SYSCALL_TABLE(sys_read, sys_read, 0, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_write
+TRACE_SYSCALL_TABLE(sys_write, sys_write, 1, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_open
+TRACE_SYSCALL_TABLE(sys_open, sys_open, 2, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newstat
+TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 4, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newfstat
+TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 5, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newlstat
+TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 6, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_poll
+TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 7, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigaction
+TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 13, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigprocmask
+TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 14, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readv
+TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 19, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_writev
+TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 20, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_access
+TRACE_SYSCALL_TABLE(sys_access, sys_access, 21, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pipe
+TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 22, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_select
+TRACE_SYSCALL_TABLE(sys_select, sys_select, 23, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mincore
+TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 27, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_shmat
+TRACE_SYSCALL_TABLE(sys_shmat, sys_shmat, 30, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_shmctl
+TRACE_SYSCALL_TABLE(sys_shmctl, sys_shmctl, 31, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_nanosleep
+TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 35, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getitimer
+TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 36, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setitimer
+TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 38, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendfile64
+TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 40, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_connect
+TRACE_SYSCALL_TABLE(sys_connect, sys_connect, 42, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_accept
+TRACE_SYSCALL_TABLE(sys_accept, sys_accept, 43, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendto
+TRACE_SYSCALL_TABLE(sys_sendto, sys_sendto, 44, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_recvfrom
+TRACE_SYSCALL_TABLE(sys_recvfrom, sys_recvfrom, 45, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendmsg
+TRACE_SYSCALL_TABLE(sys_sendmsg, sys_sendmsg, 46, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_recvmsg
+TRACE_SYSCALL_TABLE(sys_recvmsg, sys_recvmsg, 47, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_bind
+TRACE_SYSCALL_TABLE(sys_bind, sys_bind, 49, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getsockname
+TRACE_SYSCALL_TABLE(sys_getsockname, sys_getsockname, 51, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getpeername
+TRACE_SYSCALL_TABLE(sys_getpeername, sys_getpeername, 52, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_socketpair
+TRACE_SYSCALL_TABLE(sys_socketpair, sys_socketpair, 53, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setsockopt
+TRACE_SYSCALL_TABLE(sys_setsockopt, sys_setsockopt, 54, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getsockopt
+TRACE_SYSCALL_TABLE(sys_getsockopt, sys_getsockopt, 55, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_wait4
+TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 61, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newuname
+TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 63, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_semop
+TRACE_SYSCALL_TABLE(sys_semop, sys_semop, 65, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_shmdt
+TRACE_SYSCALL_TABLE(sys_shmdt, sys_shmdt, 67, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msgsnd
+TRACE_SYSCALL_TABLE(sys_msgsnd, sys_msgsnd, 69, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msgrcv
+TRACE_SYSCALL_TABLE(sys_msgrcv, sys_msgrcv, 70, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_msgctl
+TRACE_SYSCALL_TABLE(sys_msgctl, sys_msgctl, 71, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_truncate
+TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 76, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getdents
+TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 78, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getcwd
+TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 79, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chdir
+TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 80, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rename
+TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 82, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mkdir
+TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 83, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rmdir
+TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 84, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_creat
+TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 85, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_link
+TRACE_SYSCALL_TABLE(sys_link, sys_link, 86, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unlink
+TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 87, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_symlink
+TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 88, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readlink
+TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 89, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chmod
+TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 90, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chown
+TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 92, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lchown
+TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 94, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_gettimeofday
+TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 96, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getrlimit
+TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 97, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getrusage
+TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 98, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysinfo
+TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 99, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_times
+TRACE_SYSCALL_TABLE(sys_times, sys_times, 100, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_syslog
+TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getgroups
+TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 115, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setgroups
+TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 116, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresuid
+TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 118, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getresgid
+TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 120, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigpending
+TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 127, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigtimedwait
+TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 128, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigqueueinfo
+TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 129, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_sigsuspend
+TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 130, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utime
+TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 132, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mknod
+TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 133, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ustat
+TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 136, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_statfs
+TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 137, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fstatfs
+TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 138, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setparam
+TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 142, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getparam
+TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 143, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setscheduler
+TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 144, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_rr_get_interval
+TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 148, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pivot_root
+TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 155, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sysctl
+TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 156, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_adjtimex
+TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 159, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setrlimit
+TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 160, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_chroot
+TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 161, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_settimeofday
+TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 164, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mount
+TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 165, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_umount
+TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 166, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_swapon
+TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 167, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_swapoff
+TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 168, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_reboot
+TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 169, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sethostname
+TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 170, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setdomainname
+TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 171, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_init_module
+TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 175, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_delete_module
+TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 176, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_nfsservctl
+TRACE_SYSCALL_TABLE(sys_nfsservctl, sys_nfsservctl, 180, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_setxattr
+TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 188, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lsetxattr
+TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 189, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fsetxattr
+TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 190, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getxattr
+TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 191, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lgetxattr
+TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 192, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fgetxattr
+TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 193, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_listxattr
+TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 194, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_llistxattr
+TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 195, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_flistxattr
+TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 196, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_removexattr
+TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 197, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_lremovexattr
+TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 198, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fremovexattr
+TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 199, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_time
+TRACE_SYSCALL_TABLE(sys_time, sys_time, 201, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_futex
+TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 202, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_setaffinity
+TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 203, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sched_getaffinity
+TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 204, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_setup
+TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 206, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_getevents
+TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 208, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_submit
+TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 209, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_io_cancel
+TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 210, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_getdents64
+TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 217, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_set_tid_address
+TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 218, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_semtimedop
+TRACE_SYSCALL_TABLE(sys_semtimedop, sys_semtimedop, 220, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_create
+TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 222, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_settime
+TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 223, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timer_gettime
+TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 224, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_settime
+TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 227, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_gettime
+TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 228, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_getres
+TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 229, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_nanosleep
+TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 230, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_wait
+TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 232, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_ctl
+TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 233, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utimes
+TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 235, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_open
+TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 240, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_unlink
+TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 241, 1)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_timedsend
+TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 242, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_timedreceive
+TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 243, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_notify
+TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 244, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mq_getsetattr
+TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 245, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_kexec_load
+TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 246, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_waitid
+TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 247, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_inotify_add_watch
+TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 254, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_openat
+TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 257, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mkdirat
+TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 258, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_mknodat
+TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 259, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchownat
+TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 260, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_futimesat
+TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 261, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_newfstatat
+TRACE_SYSCALL_TABLE(sys_newfstatat, sys_newfstatat, 262, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_unlinkat
+TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 263, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_renameat
+TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 264, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_linkat
+TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 265, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_symlinkat
+TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 266, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_readlinkat
+TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 267, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_fchmodat
+TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 268, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_faccessat
+TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 269, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pselect6
+TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 270, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_ppoll
+TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 271, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_set_robust_list
+TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 273, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_get_robust_list
+TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 274, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_splice
+TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 275, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_vmsplice
+TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 278, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_utimensat
+TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 280, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_epoll_pwait
+TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 281, 6)
+#endif
+#ifndef OVERRIDE_TABLE_sys_signalfd
+TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 282, 3)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_settime
+TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 286, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_timerfd_gettime
+TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 287, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_accept4
+TRACE_SYSCALL_TABLE(sys_accept4, sys_accept4, 288, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_signalfd4
+TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 289, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pipe2
+TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 293, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_preadv
+TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 295, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_pwritev
+TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 296, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_rt_tgsigqueueinfo
+TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 297, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_perf_event_open
+TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 298, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_recvmmsg
+TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 299, 5)
+#endif
+#ifndef OVERRIDE_TABLE_sys_prlimit64
+TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 302, 4)
+#endif
+#ifndef OVERRIDE_TABLE_sys_clock_adjtime
+TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 305, 2)
+#endif
+#ifndef OVERRIDE_TABLE_sys_sendmmsg
+TRACE_SYSCALL_TABLE(sys_sendmmsg, sys_sendmmsg, 307, 4)
+#endif
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h
new file mode 100644
index 0000000..0cdb32a
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h
@@ -0,0 +1,5 @@
+#ifndef CREATE_SYSCALL_TABLE
+
+#else	/* CREATE_SYSCALL_TABLE */
+
+#endif /* CREATE_SYSCALL_TABLE */
diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile
new file mode 100644
index 0000000..4beb88c
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile
@@ -0,0 +1 @@
+obj-m += lttng-syscalls-extractor.o
diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c
new file mode 100644
index 0000000..06c0da1
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ * Copyright 2011 - Julien Desfossez <julien.desfossez at polymtl.ca>
+ *
+ * Dump syscall metadata to console.
+ *
+ * GPLv2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/kallsyms.h>
+#include <linux/dcache.h>
+#include <linux/ftrace_event.h>
+#include <trace/syscall.h>
+
+#ifndef CONFIG_FTRACE_SYSCALLS
+#error "You need to set CONFIG_FTRACE_SYSCALLS=y"
+#endif
+
+#ifndef CONFIG_KALLSYMS_ALL
+#error "You need to set CONFIG_KALLSYMS_ALL=y"
+#endif
+
+static struct syscall_metadata **__start_syscalls_metadata;
+static struct syscall_metadata **__stop_syscalls_metadata;
+
+static __init
+struct syscall_metadata *find_syscall_meta(unsigned long syscall)
+{
+	struct syscall_metadata **iter;
+
+	for (iter = __start_syscalls_metadata;
+			iter < __stop_syscalls_metadata; iter++) {
+		if ((*iter)->syscall_nr == syscall)
+			return (*iter);
+	}
+	return NULL;
+}
+
+int init_module(void)
+{
+	struct syscall_metadata *meta;
+	int i;
+
+	__start_syscalls_metadata = (void *) kallsyms_lookup_name("__start_syscalls_metadata");
+	__stop_syscalls_metadata = (void *) kallsyms_lookup_name("__stop_syscalls_metadata");
+
+	for (i = 0; i < NR_syscalls; i++) {
+		int j;
+
+		meta = find_syscall_meta(i);
+		if (!meta)
+			continue;
+		printk("syscall %s nr %d nbargs %d ",
+			meta->name, meta->syscall_nr, meta->nb_args);
+		printk("types: (");
+		for (j = 0; j < meta->nb_args; j++) {
+			if (j > 0)
+				printk(", ");
+			printk("%s", meta->types[j]);
+		}
+		printk(") ");
+		printk("args: (");
+		for (j = 0; j < meta->nb_args; j++) {
+			if (j > 0)
+				printk(", ");
+			printk("%s", meta->args[j]);
+		}
+		printk(")\n");
+	}
+	printk("SUCCESS\n");
+
+	return -1;
+}
+
+void cleanup_module(void)
+{
+}  
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh
new file mode 100644
index 0000000..c6636e7
--- /dev/null
+++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh
@@ -0,0 +1,272 @@
+#!/bin/sh
+
+# Generate system call probe description macros from syscall metadata dump file.
+# example usage:
+#
+# lttng-syscalls-generate-headers.sh integers 3.0.4 x86-64-syscalls-3.0.4
+# lttng-syscalls-generate-headers.sh pointers 3.0.4 x86-64-syscalls-3.0.4
+
+CLASS=$1
+INPUTDIR=$2
+INPUTFILE=$3
+INPUT=${INPUTDIR}/${INPUTFILE}
+SRCFILE=gen.tmp.0
+TMPFILE=gen.tmp.1
+HEADER=headers/${INPUTFILE}_${CLASS}.h
+
+cp ${INPUT} ${SRCFILE}
+
+#Cleanup
+perl -p -e 's/^\[.*\] //g' ${SRCFILE} > ${TMPFILE}
+mv ${TMPFILE} ${SRCFILE}
+
+perl -p -e 's/^syscall sys_([^ ]*)/syscall $1/g' ${SRCFILE} > ${TMPFILE}
+mv ${TMPFILE} ${SRCFILE}
+
+#Filter
+
+if [ "$CLASS" = integers ]; then
+	#select integers and no-args.
+	CLASSCAP=INTEGERS
+	grep -v "\\*\|cap_user_header_t" ${SRCFILE} > ${TMPFILE}
+	mv ${TMPFILE} ${SRCFILE}
+fi
+
+
+if [ "$CLASS" = pointers ]; then
+	#select system calls using pointers.
+	CLASSCAP=POINTERS
+	grep "\\*\|cap_#user_header_t" ${SRCFILE} > ${TMPFILE}
+	mv ${TMPFILE} ${SRCFILE}
+fi
+
+echo "/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */" > ${HEADER}
+
+echo \
+"#ifndef CREATE_SYSCALL_TABLE
+
+#if !defined(_TRACE_SYSCALLS_${CLASSCAP}_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SYSCALLS_${CLASSCAP}_H
+
+#include <linux/tracepoint.h>
+#include <linux/syscalls.h>
+#include \"${INPUTFILE}_${CLASS}_override.h\"
+" >> ${HEADER}
+
+if [ "$CLASS" = integers ]; then
+
+NRARGS=0
+
+echo \
+'SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,\n'\
+'	TP_STRUCT__entry(),\n'\
+'	TP_fast_assign(),\n'\
+'	TP_printk()\n'\
+')'\
+	>> ${HEADER}
+
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^)]*)\) '\
+'args: \(([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_$1)\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+fi
+
+
+# types: 4
+# args   5
+
+NRARGS=1
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^)]*)\) '\
+'args: \(([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $5),\n'\
+'	TP_ARGS($5),\n'\
+'	TP_STRUCT__entry(__field($4, $5)),\n'\
+'	TP_fast_assign(tp_assign($4, $5, $5)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+# types: 4 5
+# args   6 7
+
+NRARGS=2
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^,]*), ([^)]*)\) '\
+'args: \(([^,]*), ([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $6, $5 $7),\n'\
+'	TP_ARGS($6, $7),\n'\
+'	TP_STRUCT__entry(__field($4, $6) __field($5, $7)),\n'\
+'	TP_fast_assign(tp_assign($4, $6, $6) tp_assign($5, $7, $7)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+# types: 4 5 6
+# args   7 8 9
+
+NRARGS=3
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^,]*), ([^,]*), ([^)]*)\) '\
+'args: \(([^,]*), ([^,]*), ([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $7, $5 $8, $6 $9),\n'\
+'	TP_ARGS($7, $8, $9),\n'\
+'	TP_STRUCT__entry(__field($4, $7) __field($5, $8) __field($6, $9)),\n'\
+'	TP_fast_assign(tp_assign($4, $7, $7) tp_assign($5, $8, $8) tp_assign($6, $9, $9)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+
+# types: 4 5  6  7
+# args   8 9 10 11
+
+NRARGS=4
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^,]*), ([^,]*), ([^,]*), ([^)]*)\) '\
+'args: \(([^,]*), ([^,]*), ([^,]*), ([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $8, $5 $9, $6 $10, $7 $11),\n'\
+'	TP_ARGS($8, $9, $10, $11),\n'\
+'	TP_STRUCT__entry(__field($4, $8) __field($5, $9) __field($6, $10) __field($7, $11)),\n'\
+'	TP_fast_assign(tp_assign($4, $8, $8) tp_assign($5, $9, $9) tp_assign($6, $10, $10) tp_assign($7, $11, $11)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+# types: 4  5  6  7  8
+# args   9 10 11 12 13
+
+NRARGS=5
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^)]*)\) '\
+'args: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $9, $5 $10, $6 $11, $7 $12, $8 $13),\n'\
+'	TP_ARGS($9, $10, $11, $12, $13),\n'\
+'	TP_STRUCT__entry(__field($4, $9) __field($5, $10) __field($6, $11) __field($7, $12) __field($8, $13)),\n'\
+'	TP_fast_assign(tp_assign($4, $9, $9) tp_assign($5, $10, $10) tp_assign($6, $11, $11) tp_assign($7, $12, $12) tp_assign($8, $13, $13)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+
+# types: 4   5  6  7  8  9
+# args   10 11 12 13 14 15
+
+NRARGS=6
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\
+'types: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^\)]*)\) '\
+'args: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^\)]*)\)/'\
+'#ifndef OVERRIDE_sys_$1\n'\
+'SC_TRACE_EVENT(sys_$1,\n'\
+'	TP_PROTO($4 $10, $5 $11, $6 $12, $7 $13, $8 $14, $9 $15),\n'\
+'	TP_ARGS($10, $11, $12, $13, $14, $15),\n'\
+'	TP_STRUCT__entry(__field($4, $10) __field($5, $11) __field($6, $12) __field($7, $13) __field($8, $14) __field($9, $15)),\n'\
+'	TP_fast_assign(tp_assign($4, $10, $10) tp_assign($5, $11, $11) tp_assign($6, $12, $12) tp_assign($7, $13, $13) tp_assign($8, $14, $14) tp_assign($9, $15, $15)),\n'\
+'	TP_printk()\n'\
+')\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+# Macro for tracing syscall table
+
+rm -f ${TMPFILE}
+for NRARGS in $(seq 0 6); do
+	grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} >> ${TMPFILE}
+done
+
+echo \
+"
+#endif /*  _TRACE_SYSCALLS_${CLASSCAP}_H */
+
+/* This part must be outside protection */
+#include \"../../../probes/define_trace.h\"
+
+#else /* CREATE_SYSCALL_TABLE */
+
+#include \"${INPUTFILE}_${CLASS}_override.h\"
+" >> ${HEADER}
+
+NRARGS=0
+
+if [ "$CLASS" = integers ]; then
+#noargs
+grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) .*$/'\
+'#ifndef OVERRIDE_TABLE_sys_$1\n'\
+'TRACE_SYSCALL_TABLE\(syscalls_noargs, sys_$1, $2, $3\)\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+fi
+
+#others.
+grep -v "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE}
+perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) .*$/'\
+'#ifndef OVERRIDE_TABLE_sys_$1\n'\
+'TRACE_SYSCALL_TABLE(sys_$1, sys_$1, $2, $3)\n'\
+'#endif/g'\
+	${TMPFILE} >> ${HEADER}
+
+echo -n \
+"
+#endif /* CREATE_SYSCALL_TABLE */
+" >> ${HEADER}
+
+#fields names: ...char * type with *name* or *file* or *path* or *root*
+# or *put_old* or *type*
+cp -f ${HEADER} ${TMPFILE}
+rm -f ${HEADER}
+perl -p -e 's/__field\(([^,)]*char \*), ([^\)]*)(name|file|path|root|put_old|type)([^\)]*)\)/__string_from_user($2$3$4, $2$3$4)/g'\
+	${TMPFILE} >> ${HEADER}
+cp -f ${HEADER} ${TMPFILE}
+rm -f ${HEADER}
+perl -p -e 's/tp_assign\(([^,)]*char \*), ([^,]*)(name|file|path|root|put_old|type)([^,]*), ([^\)]*)\)/tp_copy_string_from_user($2$3$4, $5)/g'\
+	${TMPFILE} >> ${HEADER}
+
+#prettify addresses heuristics.
+#field names with addr or ptr
+cp -f ${HEADER} ${TMPFILE}
+rm -f ${HEADER}
+perl -p -e 's/__field\(([^,)]*), ([^,)]*addr|[^,)]*ptr)([^),]*)\)/__field_hex($1, $2$3)/g'\
+	${TMPFILE} >> ${HEADER}
+
+#field types ending with '*'
+cp -f ${HEADER} ${TMPFILE}
+rm -f ${HEADER}
+perl -p -e 's/__field\(([^,)]*\*), ([^),]*)\)/__field_hex($1, $2)/g'\
+	${TMPFILE} >> ${HEADER}
+
+#strip the extra type information from tp_assign.
+cp -f ${HEADER} ${TMPFILE}
+rm -f ${HEADER}
+perl -p -e 's/tp_assign\(([^,)]*), ([^,]*), ([^\)]*)\)/tp_assign($2, $3)/g'\
+	${TMPFILE} >> ${HEADER}
+
+rm -f ${INPUTFILE}.tmp
+rm -f ${TMPFILE}
+rm -f ${SRCFILE}
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 09/19] lttng: lib ring buffer clients
  2011-11-26 15:03               ` [lttng-dev] [PATCH 08/19] lttng: syscall instrumentation Mathieu Desnoyers
@ 2011-11-26 15:03                 ` Mathieu Desnoyers
  2011-11-26 15:03                   ` [lttng-dev] [PATCH 10/19] lttng: tracer control and core structures Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Each lttng buffer configuration (discard mode, overwrite mode, mmap
support, splice support, per-cpu buffers, global buffer for metadata) is
a lib ring buffer client.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 .../staging/lttng/ltt-ring-buffer-client-discard.c |   21 +
 .../lttng/ltt-ring-buffer-client-mmap-discard.c    |   21 +
 .../lttng/ltt-ring-buffer-client-mmap-overwrite.c  |   21 +
 .../lttng/ltt-ring-buffer-client-overwrite.c       |   21 +
 drivers/staging/lttng/ltt-ring-buffer-client.h     |  569 ++++++++++++++++++++
 .../lttng/ltt-ring-buffer-metadata-client.c        |   21 +
 .../lttng/ltt-ring-buffer-metadata-client.h        |  330 ++++++++++++
 .../lttng/ltt-ring-buffer-metadata-mmap-client.c   |   21 +
 8 files changed, 1025 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-discard.c
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client.h
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-client.c
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-client.h
 create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c

diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-discard.c b/drivers/staging/lttng/ltt-ring-buffer-client-discard.c
new file mode 100644
index 0000000..eafcf45
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-client-discard.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-client-discard.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client (discard mode).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_DISCARD
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"discard"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_SPLICE
+#include "ltt-ring-buffer-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c
new file mode 100644
index 0000000..29819a7
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-client-discard.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client (discard mode).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_DISCARD
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"discard-mmap"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_MMAP
+#include "ltt-ring-buffer-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c
new file mode 100644
index 0000000..741aa7b
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-client-overwrite.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client (overwrite mode).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_OVERWRITE
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"overwrite-mmap"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_MMAP
+#include "ltt-ring-buffer-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c b/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c
new file mode 100644
index 0000000..9811941
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-client-overwrite.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client (overwrite mode).
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_OVERWRITE
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"overwrite"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_SPLICE
+#include "ltt-ring-buffer-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-client.h b/drivers/staging/lttng/ltt-ring-buffer-client.h
new file mode 100644
index 0000000..8df3790
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-client.h
@@ -0,0 +1,569 @@
+/*
+ * ltt-ring-buffer-client.h
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client template.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include "lib/bitfield.h"
+#include "wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "wrapper/trace-clock.h"
+#include "ltt-events.h"
+#include "ltt-tracer.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+
+/*
+ * Keep the natural field alignment for _each field_ within this structure if
+ * you ever add/remove a field from this header. Packed attribute is not used
+ * because gcc generates poor code on at least powerpc and mips. Don't ever
+ * let gcc add padding between the structure elements.
+ *
+ * The guarantee we have with timestamps is that all the events in a
+ * packet are included (inclusive) within the begin/end timestamps of
+ * the packet. Another guarantee we have is that the "timestamp begin",
+ * as well as the event timestamps, are monotonically increasing (never
+ * decrease) when moving forward in a stream (physically). But this
+ * guarantee does not apply to "timestamp end", because it is sampled at
+ * commit time, which is not ordered with respect to space reservation.
+ */
+
+struct packet_header {
+	/* Trace packet header */
+	uint32_t magic;			/*
+					 * Trace magic number.
+					 * contains endianness information.
+					 */
+	uint8_t uuid[16];
+	uint32_t stream_id;
+
+	struct {
+		/* Stream packet context */
+		uint64_t timestamp_begin;	/* Cycle count at subbuffer start */
+		uint64_t timestamp_end;		/* Cycle count at subbuffer end */
+		uint32_t events_discarded;	/*
+						 * Events lost in this subbuffer since
+						 * the beginning of the trace.
+						 * (may overflow)
+						 */
+		uint32_t content_size;		/* Size of data in subbuffer */
+		uint32_t packet_size;		/* Subbuffer size (include padding) */
+		uint32_t cpu_id;		/* CPU id associated with stream */
+		uint8_t header_end;		/* End of header */
+	} ctx;
+};
+
+
+static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan)
+{
+	return trace_clock_read64();
+}
+
+static inline
+size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx)
+{
+	int i;
+	size_t orig_offset = offset;
+
+	if (likely(!ctx))
+		return 0;
+	for (i = 0; i < ctx->nr_fields; i++)
+		offset += ctx->fields[i].get_size(offset);
+	return offset - orig_offset;
+}
+
+static inline
+void ctx_record(struct lib_ring_buffer_ctx *bufctx,
+		struct ltt_channel *chan,
+		struct lttng_ctx *ctx)
+{
+	int i;
+
+	if (likely(!ctx))
+		return;
+	for (i = 0; i < ctx->nr_fields; i++)
+		ctx->fields[i].record(&ctx->fields[i], bufctx, chan);
+}
+
+/*
+ * record_header_size - Calculate the header size and padding necessary.
+ * @config: ring buffer instance configuration
+ * @chan: channel
+ * @offset: offset in the write buffer
+ * @pre_header_padding: padding to add before the header (output)
+ * @ctx: reservation context
+ *
+ * Returns the event header size (including padding).
+ *
+ * The payload must itself determine its own alignment from the biggest type it
+ * contains.
+ */
+static __inline__
+unsigned char record_header_size(const struct lib_ring_buffer_config *config,
+				 struct channel *chan, size_t offset,
+				 size_t *pre_header_padding,
+				 struct lib_ring_buffer_ctx *ctx)
+{
+	struct ltt_channel *ltt_chan = channel_get_private(chan);
+	struct ltt_event *event = ctx->priv;
+	size_t orig_offset = offset;
+	size_t padding;
+
+	switch (ltt_chan->header_type) {
+	case 1:	/* compact */
+		padding = lib_ring_buffer_align(offset, ltt_alignof(uint32_t));
+		offset += padding;
+		if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) {
+			offset += sizeof(uint32_t);	/* id and timestamp */
+		} else {
+			/* Minimum space taken by 5-bit id */
+			offset += sizeof(uint8_t);
+			/* Align extended struct on largest member */
+			offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+			offset += sizeof(uint32_t);	/* id */
+			offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+			offset += sizeof(uint64_t);	/* timestamp */
+		}
+		break;
+	case 2:	/* large */
+		padding = lib_ring_buffer_align(offset, ltt_alignof(uint16_t));
+		offset += padding;
+		offset += sizeof(uint16_t);
+		if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) {
+			offset += lib_ring_buffer_align(offset, ltt_alignof(uint32_t));
+			offset += sizeof(uint32_t);	/* timestamp */
+		} else {
+			/* Align extended struct on largest member */
+			offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+			offset += sizeof(uint32_t);	/* id */
+			offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+			offset += sizeof(uint64_t);	/* timestamp */
+		}
+		break;
+	default:
+		padding = 0;
+		WARN_ON_ONCE(1);
+	}
+	offset += ctx_get_size(offset, event->ctx);
+	offset += ctx_get_size(offset, ltt_chan->ctx);
+
+	*pre_header_padding = padding;
+	return offset - orig_offset;
+}
+
+#include "wrapper/ringbuffer/api.h"
+
+static
+void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer_ctx *ctx,
+				 uint32_t event_id);
+
+/*
+ * ltt_write_event_header
+ *
+ * Writes the event header to the offset (already aligned on 32-bits).
+ *
+ * @config: ring buffer instance configuration
+ * @ctx: reservation context
+ * @event_id: event ID
+ */
+static __inline__
+void ltt_write_event_header(const struct lib_ring_buffer_config *config,
+			    struct lib_ring_buffer_ctx *ctx,
+			    uint32_t event_id)
+{
+	struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+	struct ltt_event *event = ctx->priv;
+
+	if (unlikely(ctx->rflags))
+		goto slow_path;
+
+	switch (ltt_chan->header_type) {
+	case 1:	/* compact */
+	{
+		uint32_t id_time = 0;
+
+		bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id);
+		bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc);
+		lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
+		break;
+	}
+	case 2:	/* large */
+	{
+		uint32_t timestamp = (uint32_t) ctx->tsc;
+		uint16_t id = event_id;
+
+		lib_ring_buffer_write(config, ctx, &id, sizeof(id));
+		lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t));
+		lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+		break;
+	}
+	default:
+		WARN_ON_ONCE(1);
+	}
+
+	ctx_record(ctx, ltt_chan, ltt_chan->ctx);
+	ctx_record(ctx, ltt_chan, event->ctx);
+	lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
+
+	return;
+
+slow_path:
+	ltt_write_event_header_slow(config, ctx, event_id);
+}
+
+static
+void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config,
+				 struct lib_ring_buffer_ctx *ctx,
+				 uint32_t event_id)
+{
+	struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+	struct ltt_event *event = ctx->priv;
+
+	switch (ltt_chan->header_type) {
+	case 1:	/* compact */
+		if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) {
+			uint32_t id_time = 0;
+
+			bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id);
+			bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc);
+			lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time));
+		} else {
+			uint8_t id = 0;
+			uint64_t timestamp = ctx->tsc;
+
+			bt_bitfield_write(&id, uint8_t, 0, 5, 31);
+			lib_ring_buffer_write(config, ctx, &id, sizeof(id));
+			/* Align extended struct on largest member */
+			lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+			lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+			lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+			lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+		}
+		break;
+	case 2:	/* large */
+	{
+		if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) {
+			uint32_t timestamp = (uint32_t) ctx->tsc;
+			uint16_t id = event_id;
+
+			lib_ring_buffer_write(config, ctx, &id, sizeof(id));
+			lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t));
+			lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+		} else {
+			uint16_t id = 65535;
+			uint64_t timestamp = ctx->tsc;
+
+			lib_ring_buffer_write(config, ctx, &id, sizeof(id));
+			/* Align extended struct on largest member */
+			lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+			lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
+			lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint64_t));
+			lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
+		}
+		break;
+	}
+	default:
+		WARN_ON_ONCE(1);
+	}
+	ctx_record(ctx, ltt_chan, ltt_chan->ctx);
+	ctx_record(ctx, ltt_chan, event->ctx);
+	lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
+}
+
+static const struct lib_ring_buffer_config client_config;
+
+static u64 client_ring_buffer_clock_read(struct channel *chan)
+{
+	return lib_ring_buffer_clock_read(chan);
+}
+
+static
+size_t client_record_header_size(const struct lib_ring_buffer_config *config,
+				 struct channel *chan, size_t offset,
+				 size_t *pre_header_padding,
+				 struct lib_ring_buffer_ctx *ctx)
+{
+	return record_header_size(config, chan, offset,
+				  pre_header_padding, ctx);
+}
+
+/**
+ * client_packet_header_size - called on buffer-switch to a new sub-buffer
+ *
+ * Return header size without padding after the structure. Don't use packed
+ * structure because gcc generates inefficient code on some architectures
+ * (powerpc, mips..)
+ */
+static size_t client_packet_header_size(void)
+{
+	return offsetof(struct packet_header, ctx.header_end);
+}
+
+static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
+				unsigned int subbuf_idx)
+{
+	struct channel *chan = buf->backend.chan;
+	struct packet_header *header =
+		(struct packet_header *)
+			lib_ring_buffer_offset_address(&buf->backend,
+				subbuf_idx * chan->backend.subbuf_size);
+	struct ltt_channel *ltt_chan = channel_get_private(chan);
+	struct ltt_session *session = ltt_chan->session;
+
+	header->magic = CTF_MAGIC_NUMBER;
+	memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
+	header->stream_id = ltt_chan->id;
+	header->ctx.timestamp_begin = tsc;
+	header->ctx.timestamp_end = 0;
+	header->ctx.events_discarded = 0;
+	header->ctx.content_size = 0xFFFFFFFF; /* for debugging */
+	header->ctx.packet_size = 0xFFFFFFFF;
+	header->ctx.cpu_id = buf->backend.cpu;
+}
+
+/*
+ * offset is assumed to never be 0 here : never deliver a completely empty
+ * subbuffer. data_size is between 1 and subbuf_size.
+ */
+static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc,
+			      unsigned int subbuf_idx, unsigned long data_size)
+{
+	struct channel *chan = buf->backend.chan;
+	struct packet_header *header =
+		(struct packet_header *)
+			lib_ring_buffer_offset_address(&buf->backend,
+				subbuf_idx * chan->backend.subbuf_size);
+	unsigned long records_lost = 0;
+
+	header->ctx.timestamp_end = tsc;
+	header->ctx.content_size = data_size * CHAR_BIT; 	/* in bits */
+	header->ctx.packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */
+	records_lost += lib_ring_buffer_get_records_lost_full(&client_config, buf);
+	records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
+	records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
+	header->ctx.events_discarded = records_lost;
+}
+
+static int client_buffer_create(struct lib_ring_buffer *buf, void *priv,
+				int cpu, const char *name)
+{
+	return 0;
+}
+
+static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu)
+{
+}
+
+static const struct lib_ring_buffer_config client_config = {
+	.cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
+	.cb.record_header_size = client_record_header_size,
+	.cb.subbuffer_header_size = client_packet_header_size,
+	.cb.buffer_begin = client_buffer_begin,
+	.cb.buffer_end = client_buffer_end,
+	.cb.buffer_create = client_buffer_create,
+	.cb.buffer_finalize = client_buffer_finalize,
+
+	.tsc_bits = 32,
+	.alloc = RING_BUFFER_ALLOC_PER_CPU,
+	.sync = RING_BUFFER_SYNC_PER_CPU,
+	.mode = RING_BUFFER_MODE_TEMPLATE,
+	.backend = RING_BUFFER_PAGE,
+	.output = RING_BUFFER_OUTPUT_TEMPLATE,
+	.oops = RING_BUFFER_OOPS_CONSISTENCY,
+	.ipi = RING_BUFFER_IPI_BARRIER,
+	.wakeup = RING_BUFFER_WAKEUP_BY_TIMER,
+};
+
+static
+struct channel *_channel_create(const char *name,
+				struct ltt_channel *ltt_chan, void *buf_addr,
+				size_t subbuf_size, size_t num_subbuf,
+				unsigned int switch_timer_interval,
+				unsigned int read_timer_interval)
+{
+	return channel_create(&client_config, name, ltt_chan, buf_addr,
+			      subbuf_size, num_subbuf, switch_timer_interval,
+			      read_timer_interval);
+}
+
+static
+void ltt_channel_destroy(struct channel *chan)
+{
+	channel_destroy(chan);
+}
+
+static
+struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan)
+{
+	struct lib_ring_buffer *buf;
+	int cpu;
+
+	for_each_channel_cpu(cpu, chan) {
+		buf = channel_get_ring_buffer(&client_config, chan, cpu);
+		if (!lib_ring_buffer_open_read(buf))
+			return buf;
+	}
+	return NULL;
+}
+
+static
+int ltt_buffer_has_read_closed_stream(struct channel *chan)
+{
+	struct lib_ring_buffer *buf;
+	int cpu;
+
+	for_each_channel_cpu(cpu, chan) {
+		buf = channel_get_ring_buffer(&client_config, chan, cpu);
+		if (!atomic_long_read(&buf->active_readers))
+			return 1;
+	}
+	return 0;
+}
+
+static
+void ltt_buffer_read_close(struct lib_ring_buffer *buf)
+{
+	lib_ring_buffer_release_read(buf);
+}
+
+static
+int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx,
+		      uint32_t event_id)
+{
+	struct ltt_channel *ltt_chan = channel_get_private(ctx->chan);
+	int ret, cpu;
+
+	cpu = lib_ring_buffer_get_cpu(&client_config);
+	if (cpu < 0)
+		return -EPERM;
+	ctx->cpu = cpu;
+
+	switch (ltt_chan->header_type) {
+	case 1:	/* compact */
+		if (event_id > 30)
+			ctx->rflags |= LTT_RFLAG_EXTENDED;
+		break;
+	case 2:	/* large */
+		if (event_id > 65534)
+			ctx->rflags |= LTT_RFLAG_EXTENDED;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+
+	ret = lib_ring_buffer_reserve(&client_config, ctx);
+	if (ret)
+		goto put;
+	ltt_write_event_header(&client_config, ctx, event_id);
+	return 0;
+put:
+	lib_ring_buffer_put_cpu(&client_config);
+	return ret;
+}
+
+static
+void ltt_event_commit(struct lib_ring_buffer_ctx *ctx)
+{
+	lib_ring_buffer_commit(&client_config, ctx);
+	lib_ring_buffer_put_cpu(&client_config);
+}
+
+static
+void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src,
+		     size_t len)
+{
+	lib_ring_buffer_write(&client_config, ctx, src, len);
+}
+
+static
+void ltt_event_write_from_user(struct lib_ring_buffer_ctx *ctx,
+			       const void __user *src, size_t len)
+{
+	lib_ring_buffer_copy_from_user(&client_config, ctx, src, len);
+}
+
+static
+void ltt_event_memset(struct lib_ring_buffer_ctx *ctx,
+		int c, size_t len)
+{
+	lib_ring_buffer_memset(&client_config, ctx, c, len);
+}
+
+static
+wait_queue_head_t *ltt_get_writer_buf_wait_queue(struct channel *chan, int cpu)
+{
+	struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config,
+					chan, cpu);
+	return &buf->write_wait;
+}
+
+static
+wait_queue_head_t *ltt_get_hp_wait_queue(struct channel *chan)
+{
+	return &chan->hp_wait;
+}
+
+static
+int ltt_is_finalized(struct channel *chan)
+{
+	return lib_ring_buffer_channel_is_finalized(chan);
+}
+
+static
+int ltt_is_disabled(struct channel *chan)
+{
+	return lib_ring_buffer_channel_is_disabled(chan);
+}
+
+static struct ltt_transport ltt_relay_transport = {
+	.name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
+	.owner = THIS_MODULE,
+	.ops = {
+		.channel_create = _channel_create,
+		.channel_destroy = ltt_channel_destroy,
+		.buffer_read_open = ltt_buffer_read_open,
+		.buffer_has_read_closed_stream =
+			ltt_buffer_has_read_closed_stream,
+		.buffer_read_close = ltt_buffer_read_close,
+		.event_reserve = ltt_event_reserve,
+		.event_commit = ltt_event_commit,
+		.event_write = ltt_event_write,
+		.event_write_from_user = ltt_event_write_from_user,
+		.event_memset = ltt_event_memset,
+		.packet_avail_size = NULL,	/* Would be racy anyway */
+		.get_writer_buf_wait_queue = ltt_get_writer_buf_wait_queue,
+		.get_hp_wait_queue = ltt_get_hp_wait_queue,
+		.is_finalized = ltt_is_finalized,
+		.is_disabled = ltt_is_disabled,
+	},
+};
+
+static int __init ltt_ring_buffer_client_init(void)
+{
+	/*
+	 * This vmalloc sync all also takes care of the lib ring buffer
+	 * vmalloc'd module pages when it is built as a module into LTTng.
+	 */
+	wrapper_vmalloc_sync_all();
+	ltt_transport_register(&ltt_relay_transport);
+	return 0;
+}
+
+module_init(ltt_ring_buffer_client_init);
+
+static void __exit ltt_ring_buffer_client_exit(void)
+{
+	ltt_transport_unregister(&ltt_relay_transport);
+}
+
+module_exit(ltt_ring_buffer_client_exit);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
+		   " client");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c
new file mode 100644
index 0000000..ac6fe78
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-metadata-client.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer metadta client.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_DISCARD
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"metadata"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_SPLICE
+#include "ltt-ring-buffer-metadata-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h
new file mode 100644
index 0000000..529bbb1
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h
@@ -0,0 +1,330 @@
+/*
+ * ltt-ring-buffer-client.h
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer client template.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include "wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "ltt-events.h"
+#include "ltt-tracer.h"
+
+struct metadata_packet_header {
+	uint32_t magic;			/* 0x75D11D57 */
+	uint8_t  uuid[16];		/* Unique Universal Identifier */
+	uint32_t checksum;		/* 0 if unused */
+	uint32_t content_size;		/* in bits */
+	uint32_t packet_size;		/* in bits */
+	uint8_t  compression_scheme;	/* 0 if unused */
+	uint8_t  encryption_scheme;	/* 0 if unused */
+	uint8_t  checksum_scheme;	/* 0 if unused */
+	uint8_t  major;			/* CTF spec major version number */
+	uint8_t  minor;			/* CTF spec minor version number */
+	uint8_t  header_end[0];
+};
+
+struct metadata_record_header {
+	uint8_t header_end[0];		/* End of header */
+};
+
+static const struct lib_ring_buffer_config client_config;
+
+static inline
+u64 lib_ring_buffer_clock_read(struct channel *chan)
+{
+	return 0;
+}
+
+static inline
+unsigned char record_header_size(const struct lib_ring_buffer_config *config,
+				 struct channel *chan, size_t offset,
+				 size_t *pre_header_padding,
+				 struct lib_ring_buffer_ctx *ctx)
+{
+	return 0;
+}
+
+#include "wrapper/ringbuffer/api.h"
+
+static u64 client_ring_buffer_clock_read(struct channel *chan)
+{
+	return 0;
+}
+
+static
+size_t client_record_header_size(const struct lib_ring_buffer_config *config,
+				 struct channel *chan, size_t offset,
+				 size_t *pre_header_padding,
+				 struct lib_ring_buffer_ctx *ctx)
+{
+	return 0;
+}
+
+/**
+ * client_packet_header_size - called on buffer-switch to a new sub-buffer
+ *
+ * Return header size without padding after the structure. Don't use packed
+ * structure because gcc generates inefficient code on some architectures
+ * (powerpc, mips..)
+ */
+static size_t client_packet_header_size(void)
+{
+	return offsetof(struct metadata_packet_header, header_end);
+}
+
+static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc,
+				unsigned int subbuf_idx)
+{
+	struct channel *chan = buf->backend.chan;
+	struct metadata_packet_header *header =
+		(struct metadata_packet_header *)
+			lib_ring_buffer_offset_address(&buf->backend,
+				subbuf_idx * chan->backend.subbuf_size);
+	struct ltt_channel *ltt_chan = channel_get_private(chan);
+	struct ltt_session *session = ltt_chan->session;
+
+	header->magic = TSDL_MAGIC_NUMBER;
+	memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
+	header->checksum = 0;		/* 0 if unused */
+	header->content_size = 0xFFFFFFFF; /* in bits, for debugging */
+	header->packet_size = 0xFFFFFFFF;  /* in bits, for debugging */
+	header->compression_scheme = 0;	/* 0 if unused */
+	header->encryption_scheme = 0;	/* 0 if unused */
+	header->checksum_scheme = 0;	/* 0 if unused */
+	header->major = CTF_SPEC_MAJOR;
+	header->minor = CTF_SPEC_MINOR;
+}
+
+/*
+ * offset is assumed to never be 0 here : never deliver a completely empty
+ * subbuffer. data_size is between 1 and subbuf_size.
+ */
+static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc,
+			      unsigned int subbuf_idx, unsigned long data_size)
+{
+	struct channel *chan = buf->backend.chan;
+	struct metadata_packet_header *header =
+		(struct metadata_packet_header *)
+			lib_ring_buffer_offset_address(&buf->backend,
+				subbuf_idx * chan->backend.subbuf_size);
+	unsigned long records_lost = 0;
+
+	header->content_size = data_size * CHAR_BIT;		/* in bits */
+	header->packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */
+	/*
+	 * We do not care about the records lost count, because the metadata
+	 * channel waits and retry.
+	 */
+	(void) lib_ring_buffer_get_records_lost_full(&client_config, buf);
+	records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf);
+	records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf);
+	WARN_ON_ONCE(records_lost != 0);
+}
+
+static int client_buffer_create(struct lib_ring_buffer *buf, void *priv,
+				int cpu, const char *name)
+{
+	return 0;
+}
+
+static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu)
+{
+}
+
+static const struct lib_ring_buffer_config client_config = {
+	.cb.ring_buffer_clock_read = client_ring_buffer_clock_read,
+	.cb.record_header_size = client_record_header_size,
+	.cb.subbuffer_header_size = client_packet_header_size,
+	.cb.buffer_begin = client_buffer_begin,
+	.cb.buffer_end = client_buffer_end,
+	.cb.buffer_create = client_buffer_create,
+	.cb.buffer_finalize = client_buffer_finalize,
+
+	.tsc_bits = 0,
+	.alloc = RING_BUFFER_ALLOC_GLOBAL,
+	.sync = RING_BUFFER_SYNC_GLOBAL,
+	.mode = RING_BUFFER_MODE_TEMPLATE,
+	.backend = RING_BUFFER_PAGE,
+	.output = RING_BUFFER_OUTPUT_TEMPLATE,
+	.oops = RING_BUFFER_OOPS_CONSISTENCY,
+	.ipi = RING_BUFFER_IPI_BARRIER,
+	.wakeup = RING_BUFFER_WAKEUP_BY_TIMER,
+};
+
+static
+struct channel *_channel_create(const char *name,
+				struct ltt_channel *ltt_chan, void *buf_addr,
+				size_t subbuf_size, size_t num_subbuf,
+				unsigned int switch_timer_interval,
+				unsigned int read_timer_interval)
+{
+	return channel_create(&client_config, name, ltt_chan, buf_addr,
+			      subbuf_size, num_subbuf, switch_timer_interval,
+			      read_timer_interval);
+}
+
+static
+void ltt_channel_destroy(struct channel *chan)
+{
+	channel_destroy(chan);
+}
+
+static
+struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan)
+{
+	struct lib_ring_buffer *buf;
+
+	buf = channel_get_ring_buffer(&client_config, chan, 0);
+	if (!lib_ring_buffer_open_read(buf))
+		return buf;
+	return NULL;
+}
+
+static
+int ltt_buffer_has_read_closed_stream(struct channel *chan)
+{
+	struct lib_ring_buffer *buf;
+	int cpu;
+
+	for_each_channel_cpu(cpu, chan) {
+		buf = channel_get_ring_buffer(&client_config, chan, cpu);
+		if (!atomic_long_read(&buf->active_readers))
+			return 1;
+	}
+	return 0;
+}
+
+static
+void ltt_buffer_read_close(struct lib_ring_buffer *buf)
+{
+	lib_ring_buffer_release_read(buf);
+}
+
+static
+int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx, uint32_t event_id)
+{
+	return lib_ring_buffer_reserve(&client_config, ctx);
+}
+
+static
+void ltt_event_commit(struct lib_ring_buffer_ctx *ctx)
+{
+	lib_ring_buffer_commit(&client_config, ctx);
+}
+
+static
+void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src,
+		     size_t len)
+{
+	lib_ring_buffer_write(&client_config, ctx, src, len);
+}
+
+static
+void ltt_event_write_from_user(struct lib_ring_buffer_ctx *ctx,
+			       const void __user *src, size_t len)
+{
+	lib_ring_buffer_copy_from_user(&client_config, ctx, src, len);
+}
+
+static
+void ltt_event_memset(struct lib_ring_buffer_ctx *ctx,
+		int c, size_t len)
+{
+	lib_ring_buffer_memset(&client_config, ctx, c, len);
+}
+
+static
+size_t ltt_packet_avail_size(struct channel *chan)
+			     
+{
+	unsigned long o_begin;
+	struct lib_ring_buffer *buf;
+
+	buf = chan->backend.buf;	/* Only for global buffer ! */
+	o_begin = v_read(&client_config, &buf->offset);
+	if (subbuf_offset(o_begin, chan) != 0) {
+		return chan->backend.subbuf_size - subbuf_offset(o_begin, chan);
+	} else {
+		return chan->backend.subbuf_size - subbuf_offset(o_begin, chan)
+			- sizeof(struct metadata_packet_header);
+	}
+}
+
+static
+wait_queue_head_t *ltt_get_writer_buf_wait_queue(struct channel *chan, int cpu)
+{
+	struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config,
+					chan, cpu);
+	return &buf->write_wait;
+}
+
+static
+wait_queue_head_t *ltt_get_hp_wait_queue(struct channel *chan)
+{
+	return &chan->hp_wait;
+}
+
+static
+int ltt_is_finalized(struct channel *chan)
+{
+	return lib_ring_buffer_channel_is_finalized(chan);
+}
+
+static
+int ltt_is_disabled(struct channel *chan)
+{
+	return lib_ring_buffer_channel_is_disabled(chan);
+}
+
+static struct ltt_transport ltt_relay_transport = {
+	.name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
+	.owner = THIS_MODULE,
+	.ops = {
+		.channel_create = _channel_create,
+		.channel_destroy = ltt_channel_destroy,
+		.buffer_read_open = ltt_buffer_read_open,
+		.buffer_has_read_closed_stream =
+			ltt_buffer_has_read_closed_stream,
+		.buffer_read_close = ltt_buffer_read_close,
+		.event_reserve = ltt_event_reserve,
+		.event_commit = ltt_event_commit,
+		.event_write_from_user = ltt_event_write_from_user,
+		.event_memset = ltt_event_memset,
+		.event_write = ltt_event_write,
+		.packet_avail_size = ltt_packet_avail_size,
+		.get_writer_buf_wait_queue = ltt_get_writer_buf_wait_queue,
+		.get_hp_wait_queue = ltt_get_hp_wait_queue,
+		.is_finalized = ltt_is_finalized,
+		.is_disabled = ltt_is_disabled,
+	},
+};
+
+static int __init ltt_ring_buffer_client_init(void)
+{
+	/*
+	 * This vmalloc sync all also takes care of the lib ring buffer
+	 * vmalloc'd module pages when it is built as a module into LTTng.
+	 */
+	wrapper_vmalloc_sync_all();
+	ltt_transport_register(&ltt_relay_transport);
+	return 0;
+}
+
+module_init(ltt_ring_buffer_client_init);
+
+static void __exit ltt_ring_buffer_client_exit(void)
+{
+	ltt_transport_unregister(&ltt_relay_transport);
+}
+
+module_exit(ltt_ring_buffer_client_exit);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING
+		   " client");
diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c b/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c
new file mode 100644
index 0000000..5cad3f9
--- /dev/null
+++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c
@@ -0,0 +1,21 @@
+/*
+ * ltt-ring-buffer-metadata-client.c
+ *
+ * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng lib ring buffer metadta client.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include "ltt-tracer.h"
+
+#define RING_BUFFER_MODE_TEMPLATE		RING_BUFFER_DISCARD
+#define RING_BUFFER_MODE_TEMPLATE_STRING	"metadata-mmap"
+#define RING_BUFFER_OUTPUT_TEMPLATE		RING_BUFFER_MMAP
+#include "ltt-ring-buffer-metadata-client.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client");
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 10/19] lttng: tracer control and core structures
  2011-11-26 15:03                 ` [lttng-dev] [PATCH 09/19] lttng: lib ring buffer clients Mathieu Desnoyers
@ 2011-11-26 15:03                   ` Mathieu Desnoyers
  2011-11-26 15:03                     ` [lttng-dev] [PATCH 11/19] lttng: dynamically selectable context information Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/ltt-endian.h      |   31 +
 drivers/staging/lttng/ltt-events.c      | 1009 +++++++++++++++++++++++++++++++
 drivers/staging/lttng/ltt-events.h      |  452 ++++++++++++++
 drivers/staging/lttng/ltt-probes.c      |  164 +++++
 drivers/staging/lttng/ltt-tracer-core.h |   28 +
 drivers/staging/lttng/ltt-tracer.h      |   67 ++
 6 files changed, 1751 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/ltt-endian.h
 create mode 100644 drivers/staging/lttng/ltt-events.c
 create mode 100644 drivers/staging/lttng/ltt-events.h
 create mode 100644 drivers/staging/lttng/ltt-probes.c
 create mode 100644 drivers/staging/lttng/ltt-tracer-core.h
 create mode 100644 drivers/staging/lttng/ltt-tracer.h

diff --git a/drivers/staging/lttng/ltt-endian.h b/drivers/staging/lttng/ltt-endian.h
new file mode 100644
index 0000000..9a0512d
--- /dev/null
+++ b/drivers/staging/lttng/ltt-endian.h
@@ -0,0 +1,31 @@
+#ifndef _LTT_ENDIAN_H
+#define _LTT_ENDIAN_H
+
+/*
+ * ltt-endian.h
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#ifdef __KERNEL__
+# include <asm/byteorder.h>
+# ifdef __BIG_ENDIAN
+#  define __BYTE_ORDER __BIG_ENDIAN
+# elif defined(__LITTLE_ENDIAN)
+#  define __BYTE_ORDER __LITTLE_ENDIAN
+# else
+#  error "unknown endianness"
+# endif
+#ifndef __BIG_ENDIAN
+# define __BIG_ENDIAN 4321
+#endif
+#ifndef __LITTLE_ENDIAN
+# define __LITTLE_ENDIAN 1234
+#endif
+#else
+# include <endian.h>
+#endif
+
+#endif /* _LTT_ENDIAN_H */
diff --git a/drivers/staging/lttng/ltt-events.c b/drivers/staging/lttng/ltt-events.c
new file mode 100644
index 0000000..4229914
--- /dev/null
+++ b/drivers/staging/lttng/ltt-events.c
@@ -0,0 +1,1009 @@
+/*
+ * ltt-events.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Holds LTTng per-session event registry.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include "wrapper/uuid.h"
+#include "wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "ltt-events.h"
+#include "ltt-tracer.h"
+
+static LIST_HEAD(sessions);
+static LIST_HEAD(ltt_transport_list);
+static DEFINE_MUTEX(sessions_mutex);
+static struct kmem_cache *event_cache;
+
+static void _ltt_event_destroy(struct ltt_event *event);
+static void _ltt_channel_destroy(struct ltt_channel *chan);
+static int _ltt_event_unregister(struct ltt_event *event);
+static
+int _ltt_event_metadata_statedump(struct ltt_session *session,
+				  struct ltt_channel *chan,
+				  struct ltt_event *event);
+static
+int _ltt_session_metadata_statedump(struct ltt_session *session);
+
+void synchronize_trace(void)
+{
+	synchronize_sched();
+#ifdef CONFIG_PREEMPT_RT
+	synchronize_rcu();
+#endif
+}
+
+struct ltt_session *ltt_session_create(void)
+{
+	struct ltt_session *session;
+
+	mutex_lock(&sessions_mutex);
+	session = kzalloc(sizeof(struct ltt_session), GFP_KERNEL);
+	if (!session)
+		return NULL;
+	INIT_LIST_HEAD(&session->chan);
+	INIT_LIST_HEAD(&session->events);
+	uuid_le_gen(&session->uuid);
+	list_add(&session->list, &sessions);
+	mutex_unlock(&sessions_mutex);
+	return session;
+}
+
+void ltt_session_destroy(struct ltt_session *session)
+{
+	struct ltt_channel *chan, *tmpchan;
+	struct ltt_event *event, *tmpevent;
+	int ret;
+
+	mutex_lock(&sessions_mutex);
+	ACCESS_ONCE(session->active) = 0;
+	list_for_each_entry(chan, &session->chan, list) {
+		ret = lttng_syscalls_unregister(chan);
+		WARN_ON(ret);
+	}
+	list_for_each_entry(event, &session->events, list) {
+		ret = _ltt_event_unregister(event);
+		WARN_ON(ret);
+	}
+	synchronize_trace();	/* Wait for in-flight events to complete */
+	list_for_each_entry_safe(event, tmpevent, &session->events, list)
+		_ltt_event_destroy(event);
+	list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
+		_ltt_channel_destroy(chan);
+	list_del(&session->list);
+	mutex_unlock(&sessions_mutex);
+	kfree(session);
+}
+
+int ltt_session_enable(struct ltt_session *session)
+{
+	int ret = 0;
+	struct ltt_channel *chan;
+
+	mutex_lock(&sessions_mutex);
+	if (session->active) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	/*
+	 * Snapshot the number of events per channel to know the type of header
+	 * we need to use.
+	 */
+	list_for_each_entry(chan, &session->chan, list) {
+		if (chan->header_type)
+			continue;		/* don't change it if session stop/restart */
+		if (chan->free_event_id < 31)
+			chan->header_type = 1;	/* compact */
+		else
+			chan->header_type = 2;	/* large */
+	}
+
+	ACCESS_ONCE(session->active) = 1;
+	ACCESS_ONCE(session->been_active) = 1;
+	ret = _ltt_session_metadata_statedump(session);
+	if (ret)
+		ACCESS_ONCE(session->active) = 0;
+end:
+	mutex_unlock(&sessions_mutex);
+	return ret;
+}
+
+int ltt_session_disable(struct ltt_session *session)
+{
+	int ret = 0;
+
+	mutex_lock(&sessions_mutex);
+	if (!session->active) {
+		ret = -EBUSY;
+		goto end;
+	}
+	ACCESS_ONCE(session->active) = 0;
+end:
+	mutex_unlock(&sessions_mutex);
+	return ret;
+}
+
+int ltt_channel_enable(struct ltt_channel *channel)
+{
+	int old;
+
+	if (channel == channel->session->metadata)
+		return -EPERM;
+	old = xchg(&channel->enabled, 1);
+	if (old)
+		return -EEXIST;
+	return 0;
+}
+
+int ltt_channel_disable(struct ltt_channel *channel)
+{
+	int old;
+
+	if (channel == channel->session->metadata)
+		return -EPERM;
+	old = xchg(&channel->enabled, 0);
+	if (!old)
+		return -EEXIST;
+	return 0;
+}
+
+int ltt_event_enable(struct ltt_event *event)
+{
+	int old;
+
+	if (event->chan == event->chan->session->metadata)
+		return -EPERM;
+	old = xchg(&event->enabled, 1);
+	if (old)
+		return -EEXIST;
+	return 0;
+}
+
+int ltt_event_disable(struct ltt_event *event)
+{
+	int old;
+
+	if (event->chan == event->chan->session->metadata)
+		return -EPERM;
+	old = xchg(&event->enabled, 0);
+	if (!old)
+		return -EEXIST;
+	return 0;
+}
+
+static struct ltt_transport *ltt_transport_find(const char *name)
+{
+	struct ltt_transport *transport;
+
+	list_for_each_entry(transport, &ltt_transport_list, node) {
+		if (!strcmp(transport->name, name))
+			return transport;
+	}
+	return NULL;
+}
+
+struct ltt_channel *ltt_channel_create(struct ltt_session *session,
+				       const char *transport_name,
+				       void *buf_addr,
+				       size_t subbuf_size, size_t num_subbuf,
+				       unsigned int switch_timer_interval,
+				       unsigned int read_timer_interval)
+{
+	struct ltt_channel *chan;
+	struct ltt_transport *transport = NULL;
+
+	mutex_lock(&sessions_mutex);
+	if (session->been_active)
+		goto active;	/* Refuse to add channel to active session */
+	transport = ltt_transport_find(transport_name);
+	if (!transport) {
+		printk(KERN_WARNING "LTTng transport %s not found\n",
+		       transport_name);
+		goto notransport;
+	}
+	if (!try_module_get(transport->owner)) {
+		printk(KERN_WARNING "LTT : Can't lock transport module.\n");
+		goto notransport;
+	}
+	chan = kzalloc(sizeof(struct ltt_channel), GFP_KERNEL);
+	if (!chan)
+		goto nomem;
+	chan->session = session;
+	chan->id = session->free_chan_id++;
+	/*
+	 * Note: the channel creation op already writes into the packet
+	 * headers. Therefore the "chan" information used as input
+	 * should be already accessible.
+	 */
+	chan->chan = transport->ops.channel_create("[lttng]", chan, buf_addr,
+			subbuf_size, num_subbuf, switch_timer_interval,
+			read_timer_interval);
+	if (!chan->chan)
+		goto create_error;
+	chan->enabled = 1;
+	chan->ops = &transport->ops;
+	chan->transport = transport;
+	list_add(&chan->list, &session->chan);
+	mutex_unlock(&sessions_mutex);
+	return chan;
+
+create_error:
+	kfree(chan);
+nomem:
+	if (transport)
+		module_put(transport->owner);
+notransport:
+active:
+	mutex_unlock(&sessions_mutex);
+	return NULL;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+static
+void _ltt_channel_destroy(struct ltt_channel *chan)
+{
+	chan->ops->channel_destroy(chan->chan);
+	module_put(chan->transport->owner);
+	list_del(&chan->list);
+	lttng_destroy_context(chan->ctx);
+	kfree(chan);
+}
+
+/*
+ * Supports event creation while tracing session is active.
+ */
+struct ltt_event *ltt_event_create(struct ltt_channel *chan,
+				   struct lttng_kernel_event *event_param,
+				   void *filter,
+				   const struct lttng_event_desc *internal_desc)
+{
+	struct ltt_event *event;
+	int ret;
+
+	mutex_lock(&sessions_mutex);
+	if (chan->free_event_id == -1UL)
+		goto full;
+	/*
+	 * This is O(n^2) (for each event, the loop is called at event
+	 * creation). Might require a hash if we have lots of events.
+	 */
+	list_for_each_entry(event, &chan->session->events, list)
+		if (!strcmp(event->desc->name, event_param->name))
+			goto exist;
+	event = kmem_cache_zalloc(event_cache, GFP_KERNEL);
+	if (!event)
+		goto cache_error;
+	event->chan = chan;
+	event->filter = filter;
+	event->id = chan->free_event_id++;
+	event->enabled = 1;
+	event->instrumentation = event_param->instrumentation;
+	/* Populate ltt_event structure before tracepoint registration. */
+	smp_wmb();
+	switch (event_param->instrumentation) {
+	case LTTNG_KERNEL_TRACEPOINT:
+		event->desc = ltt_event_get(event_param->name);
+		if (!event->desc)
+			goto register_error;
+		ret = tracepoint_probe_register(event_param->name,
+				event->desc->probe_callback,
+				event);
+		if (ret)
+			goto register_error;
+		break;
+	case LTTNG_KERNEL_KPROBE:
+		ret = lttng_kprobes_register(event_param->name,
+				event_param->u.kprobe.symbol_name,
+				event_param->u.kprobe.offset,
+				event_param->u.kprobe.addr,
+				event);
+		if (ret)
+			goto register_error;
+		ret = try_module_get(event->desc->owner);
+		WARN_ON_ONCE(!ret);
+		break;
+	case LTTNG_KERNEL_KRETPROBE:
+	{
+		struct ltt_event *event_return;
+
+		/* kretprobe defines 2 events */
+		event_return =
+			kmem_cache_zalloc(event_cache, GFP_KERNEL);
+		if (!event_return)
+			goto register_error;
+		event_return->chan = chan;
+		event_return->filter = filter;
+		event_return->id = chan->free_event_id++;
+		event_return->enabled = 1;
+		event_return->instrumentation = event_param->instrumentation;
+		/*
+		 * Populate ltt_event structure before kretprobe registration.
+		 */
+		smp_wmb();
+		ret = lttng_kretprobes_register(event_param->name,
+				event_param->u.kretprobe.symbol_name,
+				event_param->u.kretprobe.offset,
+				event_param->u.kretprobe.addr,
+				event, event_return);
+		if (ret) {
+			kmem_cache_free(event_cache, event_return);
+			goto register_error;
+		}
+		/* Take 2 refs on the module: one per event. */
+		ret = try_module_get(event->desc->owner);
+		WARN_ON_ONCE(!ret);
+		ret = try_module_get(event->desc->owner);
+		WARN_ON_ONCE(!ret);
+		ret = _ltt_event_metadata_statedump(chan->session, chan,
+						    event_return);
+		if (ret) {
+			kmem_cache_free(event_cache, event_return);
+			module_put(event->desc->owner);
+			module_put(event->desc->owner);
+			goto statedump_error;
+		}
+		list_add(&event_return->list, &chan->session->events);
+		break;
+	}
+	case LTTNG_KERNEL_FUNCTION:
+		ret = lttng_ftrace_register(event_param->name,
+				event_param->u.ftrace.symbol_name,
+				event);
+		if (ret)
+			goto register_error;
+		ret = try_module_get(event->desc->owner);
+		WARN_ON_ONCE(!ret);
+		break;
+	case LTTNG_KERNEL_NOOP:
+		event->desc = internal_desc;
+		if (!event->desc)
+			goto register_error;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+	ret = _ltt_event_metadata_statedump(chan->session, chan, event);
+	if (ret)
+		goto statedump_error;
+	list_add(&event->list, &chan->session->events);
+	mutex_unlock(&sessions_mutex);
+	return event;
+
+statedump_error:
+	/* If a statedump error occurs, events will not be readable. */
+register_error:
+	kmem_cache_free(event_cache, event);
+cache_error:
+exist:
+full:
+	mutex_unlock(&sessions_mutex);
+	return NULL;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+int _ltt_event_unregister(struct ltt_event *event)
+{
+	int ret = -EINVAL;
+
+	switch (event->instrumentation) {
+	case LTTNG_KERNEL_TRACEPOINT:
+		ret = tracepoint_probe_unregister(event->desc->name,
+						  event->desc->probe_callback,
+						  event);
+		if (ret)
+			return ret;
+		break;
+	case LTTNG_KERNEL_KPROBE:
+		lttng_kprobes_unregister(event);
+		ret = 0;
+		break;
+	case LTTNG_KERNEL_KRETPROBE:
+		lttng_kretprobes_unregister(event);
+		ret = 0;
+		break;
+	case LTTNG_KERNEL_FUNCTION:
+		lttng_ftrace_unregister(event);
+		ret = 0;
+		break;
+	case LTTNG_KERNEL_NOOP:
+		ret = 0;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+	return ret;
+}
+
+/*
+ * Only used internally at session destruction.
+ */
+static
+void _ltt_event_destroy(struct ltt_event *event)
+{
+	switch (event->instrumentation) {
+	case LTTNG_KERNEL_TRACEPOINT:
+		ltt_event_put(event->desc);
+		break;
+	case LTTNG_KERNEL_KPROBE:
+		module_put(event->desc->owner);
+		lttng_kprobes_destroy_private(event);
+		break;
+	case LTTNG_KERNEL_KRETPROBE:
+		module_put(event->desc->owner);
+		lttng_kretprobes_destroy_private(event);
+		break;
+	case LTTNG_KERNEL_FUNCTION:
+		module_put(event->desc->owner);
+		lttng_ftrace_destroy_private(event);
+		break;
+	case LTTNG_KERNEL_NOOP:
+		break;
+	default:
+		WARN_ON_ONCE(1);
+	}
+	list_del(&event->list);
+	lttng_destroy_context(event->ctx);
+	kmem_cache_free(event_cache, event);
+}
+
+/*
+ * We have exclusive access to our metadata buffer (protected by the
+ * sessions_mutex), so we can do racy operations such as looking for
+ * remaining space left in packet and write, since mutual exclusion
+ * protects us from concurrent writes.
+ */
+int lttng_metadata_printf(struct ltt_session *session,
+			  const char *fmt, ...)
+{
+	struct lib_ring_buffer_ctx ctx;
+	struct ltt_channel *chan = session->metadata;
+	char *str;
+	int ret = 0, waitret;
+	size_t len, reserve_len, pos;
+	va_list ap;
+
+	WARN_ON_ONCE(!ACCESS_ONCE(session->active));
+
+	va_start(ap, fmt);
+	str = kvasprintf(GFP_KERNEL, fmt, ap);
+	va_end(ap);
+	if (!str)
+		return -ENOMEM;
+
+	len = strlen(str);
+	pos = 0;
+
+	for (pos = 0; pos < len; pos += reserve_len) {
+		reserve_len = min_t(size_t,
+				chan->ops->packet_avail_size(chan->chan),
+				len - pos);
+		lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
+					 sizeof(char), -1);
+		/*
+		 * We don't care about metadata buffer's records lost
+		 * count, because we always retry here. Report error if
+		 * we need to bail out after timeout or being
+		 * interrupted.
+		 */
+		waitret = wait_event_interruptible_timeout(*chan->ops->get_writer_buf_wait_queue(chan->chan, -1),
+			({
+				ret = chan->ops->event_reserve(&ctx, 0);
+				ret != -ENOBUFS || !ret;
+			}),
+			msecs_to_jiffies(LTTNG_METADATA_TIMEOUT_MSEC));
+		if (!waitret || waitret == -ERESTARTSYS || ret) {
+			printk(KERN_WARNING "LTTng: Failure to write metadata to buffers (%s)\n",
+				waitret == -ERESTARTSYS ? "interrupted" :
+					(ret == -ENOBUFS ? "timeout" : "I/O error"));
+			if (waitret == -ERESTARTSYS)
+				ret = waitret;
+			goto end;
+		}
+		chan->ops->event_write(&ctx, &str[pos], reserve_len);
+		chan->ops->event_commit(&ctx);
+	}
+end:
+	kfree(str);
+	return ret;
+}
+
+static
+int _ltt_field_statedump(struct ltt_session *session,
+			 const struct lttng_event_field *field)
+{
+	int ret = 0;
+
+	switch (field->type.atype) {
+	case atype_integer:
+		ret = lttng_metadata_printf(session,
+			"		integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
+			field->type.u.basic.integer.size,
+			field->type.u.basic.integer.alignment,
+			field->type.u.basic.integer.signedness,
+			(field->type.u.basic.integer.encoding == lttng_encode_none)
+				? "none"
+				: (field->type.u.basic.integer.encoding == lttng_encode_UTF8)
+					? "UTF8"
+					: "ASCII",
+			field->type.u.basic.integer.base,
+#ifdef __BIG_ENDIAN
+			field->type.u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+			field->type.u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+			field->name);
+		break;
+	case atype_enum:
+		ret = lttng_metadata_printf(session,
+			"		%s _%s;\n",
+			field->type.u.basic.enumeration.name,
+			field->name);
+		break;
+	case atype_array:
+	{
+		const struct lttng_basic_type *elem_type;
+
+		elem_type = &field->type.u.array.elem_type;
+		ret = lttng_metadata_printf(session,
+			"		integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
+			elem_type->u.basic.integer.size,
+			elem_type->u.basic.integer.alignment,
+			elem_type->u.basic.integer.signedness,
+			(elem_type->u.basic.integer.encoding == lttng_encode_none)
+				? "none"
+				: (elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
+					? "UTF8"
+					: "ASCII",
+			elem_type->u.basic.integer.base,
+#ifdef __BIG_ENDIAN
+			elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+			elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+			field->name, field->type.u.array.length);
+		break;
+	}
+	case atype_sequence:
+	{
+		const struct lttng_basic_type *elem_type;
+		const struct lttng_basic_type *length_type;
+
+		elem_type = &field->type.u.sequence.elem_type;
+		length_type = &field->type.u.sequence.length_type;
+		ret = lttng_metadata_printf(session,
+			"		integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
+			length_type->u.basic.integer.size,
+			(unsigned int) length_type->u.basic.integer.alignment,
+			length_type->u.basic.integer.signedness,
+			(length_type->u.basic.integer.encoding == lttng_encode_none)
+				? "none"
+				: ((length_type->u.basic.integer.encoding == lttng_encode_UTF8)
+					? "UTF8"
+					: "ASCII"),
+			length_type->u.basic.integer.base,
+#ifdef __BIG_ENDIAN
+			length_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+			length_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+			field->name);
+		if (ret)
+			return ret;
+
+		ret = lttng_metadata_printf(session,
+			"		integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ __%s_length ];\n",
+			elem_type->u.basic.integer.size,
+			(unsigned int) elem_type->u.basic.integer.alignment,
+			elem_type->u.basic.integer.signedness,
+			(elem_type->u.basic.integer.encoding == lttng_encode_none)
+				? "none"
+				: ((elem_type->u.basic.integer.encoding == lttng_encode_UTF8)
+					? "UTF8"
+					: "ASCII"),
+			elem_type->u.basic.integer.base,
+#ifdef __BIG_ENDIAN
+			elem_type->u.basic.integer.reverse_byte_order ? " byte_order = le;" : "",
+#else
+			elem_type->u.basic.integer.reverse_byte_order ? " byte_order = be;" : "",
+#endif
+			field->name,
+			field->name);
+		break;
+	}
+
+	case atype_string:
+		/* Default encoding is UTF8 */
+		ret = lttng_metadata_printf(session,
+			"		string%s _%s;\n",
+			field->type.u.basic.string.encoding == lttng_encode_ASCII ?
+				" { encoding = ASCII; }" : "",
+			field->name);
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return -EINVAL;
+	}
+	return ret;
+}
+
+static
+int _ltt_context_metadata_statedump(struct ltt_session *session,
+				    struct lttng_ctx *ctx)
+{
+	int ret = 0;
+	int i;
+
+	if (!ctx)
+		return 0;
+	for (i = 0; i < ctx->nr_fields; i++) {
+		const struct lttng_ctx_field *field = &ctx->fields[i];
+
+		ret = _ltt_field_statedump(session, &field->event_field);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static
+int _ltt_fields_metadata_statedump(struct ltt_session *session,
+				   struct ltt_event *event)
+{
+	const struct lttng_event_desc *desc = event->desc;
+	int ret = 0;
+	int i;
+
+	for (i = 0; i < desc->nr_fields; i++) {
+		const struct lttng_event_field *field = &desc->fields[i];
+
+		ret = _ltt_field_statedump(session, field);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+static
+int _ltt_event_metadata_statedump(struct ltt_session *session,
+				  struct ltt_channel *chan,
+				  struct ltt_event *event)
+{
+	int ret = 0;
+
+	if (event->metadata_dumped || !ACCESS_ONCE(session->active))
+		return 0;
+	if (chan == session->metadata)
+		return 0;
+
+	ret = lttng_metadata_printf(session,
+		"event {\n"
+		"	name = %s;\n"
+		"	id = %u;\n"
+		"	stream_id = %u;\n",
+		event->desc->name,
+		event->id,
+		event->chan->id);
+	if (ret)
+		goto end;
+
+	if (event->ctx) {
+		ret = lttng_metadata_printf(session,
+			"	context := struct {\n");
+		if (ret)
+			goto end;
+	}
+	ret = _ltt_context_metadata_statedump(session, event->ctx);
+	if (ret)
+		goto end;
+	if (event->ctx) {
+		ret = lttng_metadata_printf(session,
+			"	};\n");
+		if (ret)
+			goto end;
+	}
+
+	ret = lttng_metadata_printf(session,
+		"	fields := struct {\n"
+		);
+	if (ret)
+		goto end;
+
+	ret = _ltt_fields_metadata_statedump(session, event);
+	if (ret)
+		goto end;
+
+	/*
+	 * LTTng space reservation can only reserve multiples of the
+	 * byte size.
+	 */
+	ret = lttng_metadata_printf(session,
+		"	};\n"
+		"};\n\n");
+	if (ret)
+		goto end;
+
+	event->metadata_dumped = 1;
+end:
+	return ret;
+
+}
+
+static
+int _ltt_channel_metadata_statedump(struct ltt_session *session,
+				    struct ltt_channel *chan)
+{
+	int ret = 0;
+
+	if (chan->metadata_dumped || !ACCESS_ONCE(session->active))
+		return 0;
+	if (chan == session->metadata)
+		return 0;
+
+	WARN_ON_ONCE(!chan->header_type);
+	ret = lttng_metadata_printf(session,
+		"stream {\n"
+		"	id = %u;\n"
+		"	event.header := %s;\n"
+		"	packet.context := struct packet_context;\n",
+		chan->id,
+		chan->header_type == 1 ? "struct event_header_compact" :
+			"struct event_header_large");
+	if (ret)
+		goto end;
+
+	if (chan->ctx) {
+		ret = lttng_metadata_printf(session,
+			"	event.context := struct {\n");
+		if (ret)
+			goto end;
+	}
+	ret = _ltt_context_metadata_statedump(session, chan->ctx);
+	if (ret)
+		goto end;
+	if (chan->ctx) {
+		ret = lttng_metadata_printf(session,
+			"	};\n");
+		if (ret)
+			goto end;
+	}
+
+	ret = lttng_metadata_printf(session,
+		"};\n\n");
+
+	chan->metadata_dumped = 1;
+end:
+	return ret;
+}
+
+static
+int _ltt_stream_packet_context_declare(struct ltt_session *session)
+{
+	return lttng_metadata_printf(session,
+		"struct packet_context {\n"
+		"	uint64_t timestamp_begin;\n"
+		"	uint64_t timestamp_end;\n"
+		"	uint32_t events_discarded;\n"
+		"	uint32_t content_size;\n"
+		"	uint32_t packet_size;\n"
+		"	uint32_t cpu_id;\n"
+		"};\n\n"
+		);
+}
+
+/*
+ * Compact header:
+ * id: range: 0 - 30.
+ * id 31 is reserved to indicate an extended header.
+ *
+ * Large header:
+ * id: range: 0 - 65534.
+ * id 65535 is reserved to indicate an extended header.
+ */
+static
+int _ltt_event_header_declare(struct ltt_session *session)
+{
+	return lttng_metadata_printf(session,
+	"struct event_header_compact {\n"
+	"	enum : uint5_t { compact = 0 ... 30, extended = 31 } id;\n"
+	"	variant <id> {\n"
+	"		struct {\n"
+	"			uint27_t timestamp;\n"
+	"		} compact;\n"
+	"		struct {\n"
+	"			uint32_t id;\n"
+	"			uint64_t timestamp;\n"
+	"		} extended;\n"
+	"	} v;\n"
+	"} align(%u);\n"
+	"\n"
+	"struct event_header_large {\n"
+	"	enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;\n"
+	"	variant <id> {\n"
+	"		struct {\n"
+	"			uint32_t timestamp;\n"
+	"		} compact;\n"
+	"		struct {\n"
+	"			uint32_t id;\n"
+	"			uint64_t timestamp;\n"
+	"		} extended;\n"
+	"	} v;\n"
+	"} align(%u);\n\n",
+	ltt_alignof(uint32_t) * CHAR_BIT,
+	ltt_alignof(uint16_t) * CHAR_BIT
+	);
+}
+
+/*
+ * Output metadata into this session's metadata buffers.
+ */
+static
+int _ltt_session_metadata_statedump(struct ltt_session *session)
+{
+	unsigned char *uuid_c = session->uuid.b;
+	unsigned char uuid_s[37];
+	struct ltt_channel *chan;
+	struct ltt_event *event;
+	int ret = 0;
+
+	if (!ACCESS_ONCE(session->active))
+		return 0;
+	if (session->metadata_dumped)
+		goto skip_session;
+	if (!session->metadata) {
+		printk(KERN_WARNING "LTTng: attempt to start tracing, but metadata channel is not found. Operation abort.\n");
+		return -EPERM;
+	}
+
+	snprintf(uuid_s, sizeof(uuid_s),
+		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		uuid_c[0], uuid_c[1], uuid_c[2], uuid_c[3],
+		uuid_c[4], uuid_c[5], uuid_c[6], uuid_c[7],
+		uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11],
+		uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]);
+
+	ret = lttng_metadata_printf(session,
+		"typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n"
+		"typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n"
+		"typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n"
+		"typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n"
+		"typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n"
+		"typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n"
+		"\n"
+		"trace {\n"
+		"	major = %u;\n"
+		"	minor = %u;\n"
+		"	uuid = \"%s\";\n"
+		"	byte_order = %s;\n"
+		"	packet.header := struct {\n"
+		"		uint32_t magic;\n"
+		"		uint8_t  uuid[16];\n"
+		"		uint32_t stream_id;\n"
+		"	};\n"
+		"};\n\n",
+		ltt_alignof(uint8_t) * CHAR_BIT,
+		ltt_alignof(uint16_t) * CHAR_BIT,
+		ltt_alignof(uint32_t) * CHAR_BIT,
+		ltt_alignof(uint64_t) * CHAR_BIT,
+		CTF_VERSION_MAJOR,
+		CTF_VERSION_MINOR,
+		uuid_s,
+#ifdef __BIG_ENDIAN
+		"be"
+#else
+		"le"
+#endif
+		);
+	if (ret)
+		goto end;
+
+	ret = _ltt_stream_packet_context_declare(session);
+	if (ret)
+		goto end;
+
+	ret = _ltt_event_header_declare(session);
+	if (ret)
+		goto end;
+
+skip_session:
+	list_for_each_entry(chan, &session->chan, list) {
+		ret = _ltt_channel_metadata_statedump(session, chan);
+		if (ret)
+			goto end;
+	}
+
+	list_for_each_entry(event, &session->events, list) {
+		ret = _ltt_event_metadata_statedump(session, event->chan, event);
+		if (ret)
+			goto end;
+	}
+	session->metadata_dumped = 1;
+end:
+	return ret;
+}
+
+/**
+ * ltt_transport_register - LTT transport registration
+ * @transport: transport structure
+ *
+ * Registers a transport which can be used as output to extract the data out of
+ * LTTng. The module calling this registration function must ensure that no
+ * trap-inducing code will be executed by the transport functions. E.g.
+ * vmalloc_sync_all() must be called between a vmalloc and the moment the memory
+ * is made visible to the transport function. This registration acts as a
+ * vmalloc_sync_all. Therefore, only if the module allocates virtual memory
+ * after its registration must it synchronize the TLBs.
+ */
+void ltt_transport_register(struct ltt_transport *transport)
+{
+	/*
+	 * Make sure no page fault can be triggered by the module about to be
+	 * registered. We deal with this here so we don't have to call
+	 * vmalloc_sync_all() in each module's init.
+	 */
+	wrapper_vmalloc_sync_all();
+
+	mutex_lock(&sessions_mutex);
+	list_add_tail(&transport->node, &ltt_transport_list);
+	mutex_unlock(&sessions_mutex);
+}
+EXPORT_SYMBOL_GPL(ltt_transport_register);
+
+/**
+ * ltt_transport_unregister - LTT transport unregistration
+ * @transport: transport structure
+ */
+void ltt_transport_unregister(struct ltt_transport *transport)
+{
+	mutex_lock(&sessions_mutex);
+	list_del(&transport->node);
+	mutex_unlock(&sessions_mutex);
+}
+EXPORT_SYMBOL_GPL(ltt_transport_unregister);
+
+static int __init ltt_events_init(void)
+{
+	int ret;
+
+	event_cache = KMEM_CACHE(ltt_event, 0);
+	if (!event_cache)
+		return -ENOMEM;
+	ret = ltt_debugfs_abi_init();
+	if (ret)
+		goto error_abi;
+	return 0;
+error_abi:
+	kmem_cache_destroy(event_cache);
+	return ret;
+}
+
+module_init(ltt_events_init);
+
+static void __exit ltt_events_exit(void)
+{
+	struct ltt_session *session, *tmpsession;
+
+	ltt_debugfs_abi_exit();
+	list_for_each_entry_safe(session, tmpsession, &sessions, list)
+		ltt_session_destroy(session);
+	kmem_cache_destroy(event_cache);
+}
+
+module_exit(ltt_events_exit);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng Events");
diff --git a/drivers/staging/lttng/ltt-events.h b/drivers/staging/lttng/ltt-events.h
new file mode 100644
index 0000000..36b281a
--- /dev/null
+++ b/drivers/staging/lttng/ltt-events.h
@@ -0,0 +1,452 @@
+#ifndef _LTT_EVENTS_H
+#define _LTT_EVENTS_H
+
+/*
+ * ltt-events.h
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Holds LTTng per-session event registry.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/list.h>
+#include <linux/kprobes.h>
+#include "wrapper/uuid.h"
+#include "ltt-debugfs-abi.h"
+
+#undef is_signed_type
+#define is_signed_type(type)		(((type)(-1)) < 0)
+
+struct ltt_channel;
+struct ltt_session;
+struct lib_ring_buffer_ctx;
+struct perf_event;
+struct perf_event_attr;
+
+/* Type description */
+
+/* Update the astract_types name table in lttng-types.c along with this enum */
+enum abstract_types {
+	atype_integer,
+	atype_enum,
+	atype_array,
+	atype_sequence,
+	atype_string,
+	NR_ABSTRACT_TYPES,
+};
+
+/* Update the string_encodings name table in lttng-types.c along with this enum */
+enum lttng_string_encodings {
+	lttng_encode_none = 0,
+	lttng_encode_UTF8 = 1,
+	lttng_encode_ASCII = 2,
+	NR_STRING_ENCODINGS,
+};
+
+struct lttng_enum_entry {
+	unsigned long long start, end;	/* start and end are inclusive */
+	const char *string;
+};
+
+#define __type_integer(_type, _byte_order, _base, _encoding)	\
+	{							\
+	    .atype = atype_integer,				\
+	    .u.basic.integer =					\
+		{						\
+		  .size = sizeof(_type) * CHAR_BIT,		\
+		  .alignment = ltt_alignof(_type) * CHAR_BIT,	\
+		  .signedness = is_signed_type(_type),		\
+		  .reverse_byte_order = _byte_order != __BYTE_ORDER,	\
+		  .base = _base,				\
+		  .encoding = lttng_encode_##_encoding,		\
+		},						\
+	}							\
+
+struct lttng_integer_type {
+	unsigned int size;		/* in bits */
+	unsigned short alignment;	/* in bits */
+	unsigned int signedness:1;
+	unsigned int reverse_byte_order:1;
+	unsigned int base;		/* 2, 8, 10, 16, for pretty print */
+	enum lttng_string_encodings encoding;
+};
+
+union _lttng_basic_type {
+	struct lttng_integer_type integer;
+	struct {
+		const char *name;
+	} enumeration;
+	struct {
+		enum lttng_string_encodings encoding;
+	} string;
+};
+
+struct lttng_basic_type {
+	enum abstract_types atype;
+	union {
+		union _lttng_basic_type basic;
+	} u;
+};
+
+struct lttng_type {
+	enum abstract_types atype;
+	union {
+		union _lttng_basic_type basic;
+		struct {
+			struct lttng_basic_type elem_type;
+			unsigned int length;		/* num. elems. */
+		} array;
+		struct {
+			struct lttng_basic_type length_type;
+			struct lttng_basic_type elem_type;
+		} sequence;
+	} u;
+};
+
+struct lttng_enum {
+	const char *name;
+	struct lttng_type container_type;
+	const struct lttng_enum_entry *entries;
+	unsigned int len;
+};
+
+/* Event field description */
+
+struct lttng_event_field {
+	const char *name;
+	struct lttng_type type;
+};
+
+/*
+ * We need to keep this perf counter field separately from struct
+ * lttng_ctx_field because cpu hotplug needs fixed-location addresses.
+ */
+struct lttng_perf_counter_field {
+	struct notifier_block nb;
+	int hp_enable;
+	struct perf_event_attr *attr;
+	struct perf_event **e;	/* per-cpu array */
+};
+
+struct lttng_ctx_field {
+	struct lttng_event_field event_field;
+	size_t (*get_size)(size_t offset);
+	void (*record)(struct lttng_ctx_field *field,
+		       struct lib_ring_buffer_ctx *ctx,
+		       struct ltt_channel *chan);
+	union {
+		struct lttng_perf_counter_field *perf_counter;
+	} u;
+	void (*destroy)(struct lttng_ctx_field *field);
+};
+
+struct lttng_ctx {
+	struct lttng_ctx_field *fields;
+	unsigned int nr_fields;
+	unsigned int allocated_fields;
+};
+
+struct lttng_event_desc {
+	const char *name;
+	void *probe_callback;
+	const struct lttng_event_ctx *ctx;	/* context */
+	const struct lttng_event_field *fields;	/* event payload */
+	unsigned int nr_fields;
+	struct module *owner;
+};
+
+struct lttng_probe_desc {
+	const struct lttng_event_desc **event_desc;
+	unsigned int nr_events;
+	struct list_head head;			/* chain registered probes */
+};
+
+struct lttng_krp;				/* Kretprobe handling */
+
+/*
+ * ltt_event structure is referred to by the tracing fast path. It must be
+ * kept small.
+ */
+struct ltt_event {
+	unsigned int id;
+	struct ltt_channel *chan;
+	int enabled;
+	const struct lttng_event_desc *desc;
+	void *filter;
+	struct lttng_ctx *ctx;
+	enum lttng_kernel_instrumentation instrumentation;
+	union {
+		struct {
+			struct kprobe kp;
+			char *symbol_name;
+		} kprobe;
+		struct {
+			struct lttng_krp *lttng_krp;
+			char *symbol_name;
+		} kretprobe;
+		struct {
+			char *symbol_name;
+		} ftrace;
+	} u;
+	struct list_head list;		/* Event list */
+	int metadata_dumped:1;
+};
+
+struct ltt_channel_ops {
+	struct channel *(*channel_create)(const char *name,
+				struct ltt_channel *ltt_chan,
+				void *buf_addr,
+				size_t subbuf_size, size_t num_subbuf,
+				unsigned int switch_timer_interval,
+				unsigned int read_timer_interval);
+	void (*channel_destroy)(struct channel *chan);
+	struct lib_ring_buffer *(*buffer_read_open)(struct channel *chan);
+	int (*buffer_has_read_closed_stream)(struct channel *chan);
+	void (*buffer_read_close)(struct lib_ring_buffer *buf);
+	int (*event_reserve)(struct lib_ring_buffer_ctx *ctx,
+			     uint32_t event_id);
+	void (*event_commit)(struct lib_ring_buffer_ctx *ctx);
+	void (*event_write)(struct lib_ring_buffer_ctx *ctx, const void *src,
+			    size_t len);
+	void (*event_write_from_user)(struct lib_ring_buffer_ctx *ctx,
+				      const void *src, size_t len);
+	void (*event_memset)(struct lib_ring_buffer_ctx *ctx,
+			     int c, size_t len);
+	/*
+	 * packet_avail_size returns the available size in the current
+	 * packet. Note that the size returned is only a hint, since it
+	 * may change due to concurrent writes.
+	 */
+	size_t (*packet_avail_size)(struct channel *chan);
+	wait_queue_head_t *(*get_writer_buf_wait_queue)(struct channel *chan, int cpu);
+	wait_queue_head_t *(*get_hp_wait_queue)(struct channel *chan);
+	int (*is_finalized)(struct channel *chan);
+	int (*is_disabled)(struct channel *chan);
+};
+
+struct ltt_transport {
+	char *name;
+	struct module *owner;
+	struct list_head node;
+	struct ltt_channel_ops ops;
+};
+
+struct ltt_channel {
+	unsigned int id;
+	struct channel *chan;		/* Channel buffers */
+	int enabled;
+	struct lttng_ctx *ctx;
+	/* Event ID management */
+	struct ltt_session *session;
+	struct file *file;		/* File associated to channel */
+	unsigned int free_event_id;	/* Next event ID to allocate */
+	struct list_head list;		/* Channel list */
+	struct ltt_channel_ops *ops;
+	struct ltt_transport *transport;
+	struct ltt_event **sc_table;	/* for syscall tracing */
+	struct ltt_event **compat_sc_table;
+	struct ltt_event *sc_unknown;	/* for unknown syscalls */
+	struct ltt_event *sc_compat_unknown;
+	struct ltt_event *sc_exit;	/* for syscall exit */
+	int header_type;		/* 0: unset, 1: compact, 2: large */
+	int metadata_dumped:1;
+};
+
+struct ltt_session {
+	int active;			/* Is trace session active ? */
+	int been_active;		/* Has trace session been active ? */
+	struct file *file;		/* File associated to session */
+	struct ltt_channel *metadata;	/* Metadata channel */
+	struct list_head chan;		/* Channel list head */
+	struct list_head events;	/* Event list head */
+	struct list_head list;		/* Session list */
+	unsigned int free_chan_id;	/* Next chan ID to allocate */
+	uuid_le uuid;			/* Trace session unique ID */
+	int metadata_dumped:1;
+};
+
+struct ltt_session *ltt_session_create(void);
+int ltt_session_enable(struct ltt_session *session);
+int ltt_session_disable(struct ltt_session *session);
+void ltt_session_destroy(struct ltt_session *session);
+
+struct ltt_channel *ltt_channel_create(struct ltt_session *session,
+				       const char *transport_name,
+				       void *buf_addr,
+				       size_t subbuf_size, size_t num_subbuf,
+				       unsigned int switch_timer_interval,
+				       unsigned int read_timer_interval);
+struct ltt_channel *ltt_global_channel_create(struct ltt_session *session,
+				       int overwrite, void *buf_addr,
+				       size_t subbuf_size, size_t num_subbuf,
+				       unsigned int switch_timer_interval,
+				       unsigned int read_timer_interval);
+
+struct ltt_event *ltt_event_create(struct ltt_channel *chan,
+				   struct lttng_kernel_event *event_param,
+				   void *filter,
+				   const struct lttng_event_desc *internal_desc);
+
+int ltt_channel_enable(struct ltt_channel *channel);
+int ltt_channel_disable(struct ltt_channel *channel);
+int ltt_event_enable(struct ltt_event *event);
+int ltt_event_disable(struct ltt_event *event);
+
+void ltt_transport_register(struct ltt_transport *transport);
+void ltt_transport_unregister(struct ltt_transport *transport);
+
+void synchronize_trace(void);
+int ltt_debugfs_abi_init(void);
+void ltt_debugfs_abi_exit(void);
+
+int ltt_probe_register(struct lttng_probe_desc *desc);
+void ltt_probe_unregister(struct lttng_probe_desc *desc);
+const struct lttng_event_desc *ltt_event_get(const char *name);
+void ltt_event_put(const struct lttng_event_desc *desc);
+int ltt_probes_init(void);
+void ltt_probes_exit(void);
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+int lttng_syscalls_register(struct ltt_channel *chan, void *filter);
+int lttng_syscalls_unregister(struct ltt_channel *chan);
+#else
+static inline int lttng_syscalls_register(struct ltt_channel *chan, void *filter)
+{
+	return -ENOSYS;
+}
+
+static inline int lttng_syscalls_unregister(struct ltt_channel *chan)
+{
+	return 0;
+}
+#endif
+
+struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx);
+int lttng_find_context(struct lttng_ctx *ctx, const char *name);
+void lttng_remove_context_field(struct lttng_ctx **ctx,
+				struct lttng_ctx_field *field);
+void lttng_destroy_context(struct lttng_ctx *ctx);
+int lttng_add_pid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_procname_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_prio_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_nice_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_tid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx);
+#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+int lttng_add_perf_counter_to_ctx(uint32_t type,
+				  uint64_t config,
+				  const char *name,
+				  struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_perf_counter_to_ctx(uint32_t type,
+				  uint64_t config,
+				  const char *name,
+				  struct lttng_ctx **ctx)
+{
+	return -ENOSYS;
+}
+#endif
+
+#ifdef CONFIG_KPROBES
+int lttng_kprobes_register(const char *name,
+		const char *symbol_name,
+		uint64_t offset,
+		uint64_t addr,
+		struct ltt_event *event);
+void lttng_kprobes_unregister(struct ltt_event *event);
+void lttng_kprobes_destroy_private(struct ltt_event *event);
+#else
+static inline
+int lttng_kprobes_register(const char *name,
+		const char *symbol_name,
+		uint64_t offset,
+		uint64_t addr,
+		struct ltt_event *event)
+{
+	return -ENOSYS;
+}
+
+static inline
+void lttng_kprobes_unregister(struct ltt_event *event)
+{
+}
+
+static inline
+void lttng_kprobes_destroy_private(struct ltt_event *event)
+{
+}
+#endif
+
+#ifdef CONFIG_KRETPROBES
+int lttng_kretprobes_register(const char *name,
+		const char *symbol_name,
+		uint64_t offset,
+		uint64_t addr,
+		struct ltt_event *event_entry,
+		struct ltt_event *event_exit);
+void lttng_kretprobes_unregister(struct ltt_event *event);
+void lttng_kretprobes_destroy_private(struct ltt_event *event);
+#else
+static inline
+int lttng_kretprobes_register(const char *name,
+		const char *symbol_name,
+		uint64_t offset,
+		uint64_t addr,
+		struct ltt_event *event_entry,
+		struct ltt_event *event_exit)
+{
+	return -ENOSYS;
+}
+
+static inline
+void lttng_kretprobes_unregister(struct ltt_event *event)
+{
+}
+
+static inline
+void lttng_kretprobes_destroy_private(struct ltt_event *event)
+{
+}
+#endif
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+int lttng_ftrace_register(const char *name,
+			  const char *symbol_name,
+			  struct ltt_event *event);
+void lttng_ftrace_unregister(struct ltt_event *event);
+void lttng_ftrace_destroy_private(struct ltt_event *event);
+#else
+static inline
+int lttng_ftrace_register(const char *name,
+			  const char *symbol_name,
+			  struct ltt_event *event)
+{
+	return -ENOSYS;
+}
+
+static inline
+void lttng_ftrace_unregister(struct ltt_event *event)
+{
+}
+
+static inline
+void lttng_ftrace_destroy_private(struct ltt_event *event)
+{
+}
+#endif
+
+int lttng_calibrate(struct lttng_kernel_calibrate *calibrate);
+
+extern const struct file_operations lttng_tracepoint_list_fops;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+#define TRACEPOINT_HAS_DATA_ARG
+#endif
+
+#endif /* _LTT_EVENTS_H */
diff --git a/drivers/staging/lttng/ltt-probes.c b/drivers/staging/lttng/ltt-probes.c
new file mode 100644
index 0000000..81dcbd7
--- /dev/null
+++ b/drivers/staging/lttng/ltt-probes.c
@@ -0,0 +1,164 @@
+/*
+ * ltt-probes.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Holds LTTng probes registry.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/seq_file.h>
+
+#include "ltt-events.h"
+
+static LIST_HEAD(probe_list);
+static DEFINE_MUTEX(probe_mutex);
+
+static
+const struct lttng_event_desc *find_event(const char *name)
+{
+	struct lttng_probe_desc *probe_desc;
+	int i;
+
+	list_for_each_entry(probe_desc, &probe_list, head) {
+		for (i = 0; i < probe_desc->nr_events; i++) {
+			if (!strcmp(probe_desc->event_desc[i]->name, name))
+				return probe_desc->event_desc[i];
+		}
+	}
+	return NULL;
+}
+
+int ltt_probe_register(struct lttng_probe_desc *desc)
+{
+	int ret = 0;
+	int i;
+
+	mutex_lock(&probe_mutex);
+	/*
+	 * TODO: This is O(N^2). Turn into a hash table when probe registration
+	 * overhead becomes an issue.
+	 */
+	for (i = 0; i < desc->nr_events; i++) {
+		if (find_event(desc->event_desc[i]->name)) {
+			ret = -EEXIST;
+			goto end;
+		}
+	}
+	list_add(&desc->head, &probe_list);
+end:
+	mutex_unlock(&probe_mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ltt_probe_register);
+
+void ltt_probe_unregister(struct lttng_probe_desc *desc)
+{
+	mutex_lock(&probe_mutex);
+	list_del(&desc->head);
+	mutex_unlock(&probe_mutex);
+}
+EXPORT_SYMBOL_GPL(ltt_probe_unregister);
+
+const struct lttng_event_desc *ltt_event_get(const char *name)
+{
+	const struct lttng_event_desc *event;
+	int ret;
+
+	mutex_lock(&probe_mutex);
+	event = find_event(name);
+	mutex_unlock(&probe_mutex);
+	if (!event)
+		return NULL;
+	ret = try_module_get(event->owner);
+	WARN_ON_ONCE(!ret);
+	return event;
+}
+EXPORT_SYMBOL_GPL(ltt_event_get);
+
+void ltt_event_put(const struct lttng_event_desc *event)
+{
+	module_put(event->owner);
+}
+EXPORT_SYMBOL_GPL(ltt_event_put);
+
+static
+void *tp_list_start(struct seq_file *m, loff_t *pos)
+{
+	struct lttng_probe_desc *probe_desc;
+	int iter = 0, i;
+
+	mutex_lock(&probe_mutex);
+	list_for_each_entry(probe_desc, &probe_list, head) {
+		for (i = 0; i < probe_desc->nr_events; i++) {
+			if (iter++ >= *pos)
+				return (void *) probe_desc->event_desc[i];
+		}
+	}
+	/* End of list */
+	return NULL;
+}
+
+static
+void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos)
+{
+	struct lttng_probe_desc *probe_desc;
+	int iter = 0, i;
+
+	(*ppos)++;
+	list_for_each_entry(probe_desc, &probe_list, head) {
+		for (i = 0; i < probe_desc->nr_events; i++) {
+			if (iter++ >= *ppos)
+				return (void *) probe_desc->event_desc[i];
+		}
+	}
+	/* End of list */
+	return NULL;
+}
+
+static
+void tp_list_stop(struct seq_file *m, void *p)
+{
+	mutex_unlock(&probe_mutex);
+}
+
+static
+int tp_list_show(struct seq_file *m, void *p)
+{
+	const struct lttng_event_desc *probe_desc = p;
+
+	/*
+	 * Don't export lttng internal events (metadata).
+	 */
+	if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1))
+		return 0;
+	seq_printf(m,	"event { name = %s; };\n",
+		   probe_desc->name);
+	return 0;
+}
+
+static
+const struct seq_operations lttng_tracepoint_list_seq_ops = {
+	.start = tp_list_start,
+	.next = tp_list_next,
+	.stop = tp_list_stop,
+	.show = tp_list_show,
+};
+
+static
+int lttng_tracepoint_list_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &lttng_tracepoint_list_seq_ops);
+}
+
+const struct file_operations lttng_tracepoint_list_fops = {
+	.owner = THIS_MODULE,
+	.open = lttng_tracepoint_list_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
diff --git a/drivers/staging/lttng/ltt-tracer-core.h b/drivers/staging/lttng/ltt-tracer-core.h
new file mode 100644
index 0000000..5abc432
--- /dev/null
+++ b/drivers/staging/lttng/ltt-tracer-core.h
@@ -0,0 +1,28 @@
+#ifndef LTT_TRACER_CORE_H
+#define LTT_TRACER_CORE_H
+
+/*
+ * ltt-tracer-core.h
+ *
+ * Copyright (C) 2005-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * This contains the core definitions for the Linux Trace Toolkit.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/list.h>
+#include <linux/percpu.h>
+
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+/* Align data on its natural alignment */
+#define RING_BUFFER_ALIGN
+#endif
+
+#include "wrapper/ringbuffer/config.h"
+
+struct ltt_session;
+struct ltt_channel;
+struct ltt_event;
+
+#endif /* LTT_TRACER_CORE_H */
diff --git a/drivers/staging/lttng/ltt-tracer.h b/drivers/staging/lttng/ltt-tracer.h
new file mode 100644
index 0000000..a21c38c
--- /dev/null
+++ b/drivers/staging/lttng/ltt-tracer.h
@@ -0,0 +1,67 @@
+#ifndef _LTT_TRACER_H
+#define _LTT_TRACER_H
+
+/*
+ * ltt-tracer.h
+ *
+ * Copyright (C) 2005-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * This contains the definitions for the Linux Trace Toolkit tracer.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/limits.h>
+#include <linux/list.h>
+#include <linux/cache.h>
+#include <linux/timex.h>
+#include <linux/wait.h>
+#include <asm/atomic.h>
+#include <asm/local.h>
+
+#include "wrapper/trace-clock.h"
+#include "ltt-tracer-core.h"
+#include "ltt-events.h"
+
+#define LTTNG_VERSION 0
+#define LTTNG_PATCHLEVEL 9
+#define LTTNG_SUBLEVEL 1
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+/* Number of bytes to log with a read/write event */
+#define LTT_LOG_RW_SIZE			32L
+#define LTT_MAX_SMALL_SIZE		0xFFFFU
+
+#ifdef RING_BUFFER_ALIGN
+#define ltt_alignof(type)	__alignof__(type)
+#else
+#define ltt_alignof(type)	1
+#endif
+
+/* Tracer properties */
+#define CTF_MAGIC_NUMBER		0xC1FC1FC1
+#define TSDL_MAGIC_NUMBER		0x75D11D57
+
+/* CTF specification version followed */
+#define CTF_SPEC_MAJOR			1
+#define CTF_SPEC_MINOR			8
+
+/* Tracer major/minor versions */
+#define CTF_VERSION_MAJOR		0
+#define CTF_VERSION_MINOR		1
+
+/*
+ * Number of milliseconds to retry before failing metadata writes on buffer full
+ * condition. (10 seconds)
+ */
+#define LTTNG_METADATA_TIMEOUT_MSEC	10000
+
+#define LTT_RFLAG_EXTENDED		RING_BUFFER_RFLAG_END
+#define LTT_RFLAG_END			(LTT_RFLAG_EXTENDED << 1)
+
+#endif /* _LTT_TRACER_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 11/19] lttng: dynamically selectable context information
  2011-11-26 15:03                   ` [lttng-dev] [PATCH 10/19] lttng: tracer control and core structures Mathieu Desnoyers
@ 2011-11-26 15:03                     ` Mathieu Desnoyers
  2011-11-26 15:03                       ` [lttng-dev] [PATCH 12/19] lttng: timing calibration feature Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Events can be augmented with context information. This is dynamically
configurable from the command line.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/ltt-context.c                |   93 +++++++
 drivers/staging/lttng/lttng-context-nice.c         |   68 +++++
 .../staging/lttng/lttng-context-perf-counters.c    |  271 ++++++++++++++++++++
 drivers/staging/lttng/lttng-context-pid.c          |   68 +++++
 drivers/staging/lttng/lttng-context-ppid.c         |   71 +++++
 drivers/staging/lttng/lttng-context-prio.c         |   89 +++++++
 drivers/staging/lttng/lttng-context-procname.c     |   72 +++++
 drivers/staging/lttng/lttng-context-tid.c          |   68 +++++
 drivers/staging/lttng/lttng-context-vpid.c         |   74 ++++++
 drivers/staging/lttng/lttng-context-vppid.c        |   79 ++++++
 drivers/staging/lttng/lttng-context-vtid.c         |   74 ++++++
 11 files changed, 1027 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/ltt-context.c
 create mode 100644 drivers/staging/lttng/lttng-context-nice.c
 create mode 100644 drivers/staging/lttng/lttng-context-perf-counters.c
 create mode 100644 drivers/staging/lttng/lttng-context-pid.c
 create mode 100644 drivers/staging/lttng/lttng-context-ppid.c
 create mode 100644 drivers/staging/lttng/lttng-context-prio.c
 create mode 100644 drivers/staging/lttng/lttng-context-procname.c
 create mode 100644 drivers/staging/lttng/lttng-context-tid.c
 create mode 100644 drivers/staging/lttng/lttng-context-vpid.c
 create mode 100644 drivers/staging/lttng/lttng-context-vppid.c
 create mode 100644 drivers/staging/lttng/lttng-context-vtid.c

diff --git a/drivers/staging/lttng/ltt-context.c b/drivers/staging/lttng/ltt-context.c
new file mode 100644
index 0000000..60ea525
--- /dev/null
+++ b/drivers/staging/lttng/ltt-context.c
@@ -0,0 +1,93 @@
+/*
+ * ltt-context.c
+ *
+ * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng trace/channel/event context management.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include "wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "ltt-events.h"
+#include "ltt-tracer.h"
+
+int lttng_find_context(struct lttng_ctx *ctx, const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < ctx->nr_fields; i++) {
+		/* Skip allocated (but non-initialized) contexts */
+		if (!ctx->fields[i].event_field.name)
+			continue;
+		if (!strcmp(ctx->fields[i].event_field.name, name))
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_find_context);
+
+/*
+ * Note: as we append context information, the pointer location may change.
+ */
+struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p)
+{
+	struct lttng_ctx_field *field;
+	struct lttng_ctx *ctx;
+
+	if (!*ctx_p) {
+		*ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL);
+		if (!*ctx_p)
+			return NULL;
+	}
+	ctx = *ctx_p;
+	if (ctx->nr_fields + 1 > ctx->allocated_fields) {
+		struct lttng_ctx_field *new_fields;
+
+		ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields);
+		new_fields = kzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL);
+		if (!new_fields)
+			return NULL;
+		if (ctx->fields)
+			memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields);
+		kfree(ctx->fields);
+		ctx->fields = new_fields;
+	}
+	field = &ctx->fields[ctx->nr_fields];
+	ctx->nr_fields++;
+	return field;
+}
+EXPORT_SYMBOL_GPL(lttng_append_context);
+
+/*
+ * Remove last context field.
+ */
+void lttng_remove_context_field(struct lttng_ctx **ctx_p,
+				struct lttng_ctx_field *field)
+{
+	struct lttng_ctx *ctx;
+
+	ctx = *ctx_p;
+	ctx->nr_fields--;
+	WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field);
+	memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field));
+}
+EXPORT_SYMBOL_GPL(lttng_remove_context_field);
+
+void lttng_destroy_context(struct lttng_ctx *ctx)
+{
+	int i;
+
+	if (!ctx)
+		return;
+	for (i = 0; i < ctx->nr_fields; i++) {
+		if (ctx->fields[i].destroy)
+			ctx->fields[i].destroy(&ctx->fields[i]);
+	}
+	kfree(ctx->fields);
+	kfree(ctx);
+}
diff --git a/drivers/staging/lttng/lttng-context-nice.c b/drivers/staging/lttng/lttng-context-nice.c
new file mode 100644
index 0000000..9b99b54
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-nice.c
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng nice context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t nice_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(int));
+	size += sizeof(int);
+	return size;
+}
+
+static
+void nice_record(struct lttng_ctx_field *field,
+		struct lib_ring_buffer_ctx *ctx,
+		struct ltt_channel *chan)
+{
+	int nice;
+
+	nice = task_nice(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(nice));
+	chan->ops->event_write(ctx, &nice, sizeof(nice));
+}
+
+int lttng_add_nice_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "nice")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "nice";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = nice_get_size;
+	field->record = nice_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_nice_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Nice Context");
diff --git a/drivers/staging/lttng/lttng-context-perf-counters.c b/drivers/staging/lttng/lttng-context-perf-counters.c
new file mode 100644
index 0000000..3ae2266
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-perf-counters.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng performance monitoring counters (perf-counters) integration module.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/perf_event.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "wrapper/perf.h"
+#include "ltt-tracer.h"
+
+static
+size_t perf_counter_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(uint64_t));
+	size += sizeof(uint64_t);
+	return size;
+}
+
+static
+void perf_counter_record(struct lttng_ctx_field *field,
+			 struct lib_ring_buffer_ctx *ctx,
+			 struct ltt_channel *chan)
+{
+	struct perf_event *event;
+	uint64_t value;
+
+	event = field->u.perf_counter->e[ctx->cpu];
+	if (likely(event)) {
+		if (unlikely(event->state == PERF_EVENT_STATE_ERROR)) {
+			value = 0;
+		} else {
+			event->pmu->read(event);
+			value = local64_read(&event->count);
+		}
+	} else {
+		/*
+		 * Perf chooses not to be clever and not to support enabling a
+		 * perf counter before the cpu is brought up. Therefore, we need
+		 * to support having events coming (e.g. scheduler events)
+		 * before the counter is setup. Write an arbitrary 0 in this
+		 * case.
+		 */
+		value = 0;
+	}
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(value));
+	chan->ops->event_write(ctx, &value, sizeof(value));
+}
+
+#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99))
+static
+void overflow_callback(struct perf_event *event,
+		       struct perf_sample_data *data,
+		       struct pt_regs *regs)
+{
+}
+#else
+static
+void overflow_callback(struct perf_event *event, int nmi,
+		       struct perf_sample_data *data,
+		       struct pt_regs *regs)
+{
+}
+#endif
+
+static
+void lttng_destroy_perf_counter_field(struct lttng_ctx_field *field)
+{
+	struct perf_event **events = field->u.perf_counter->e;
+	int cpu;
+
+	get_online_cpus();
+	for_each_online_cpu(cpu)
+		perf_event_release_kernel(events[cpu]);
+	put_online_cpus();
+#ifdef CONFIG_HOTPLUG_CPU
+	unregister_cpu_notifier(&field->u.perf_counter->nb);
+#endif
+	kfree(field->event_field.name);
+	kfree(field->u.perf_counter->attr);
+	kfree(events);
+	kfree(field->u.perf_counter);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/**
+ *	lttng_perf_counter_hp_callback - CPU hotplug callback
+ *	@nb: notifier block
+ *	@action: hotplug action to take
+ *	@hcpu: CPU number
+ *
+ *	Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
+ *
+ * We can setup perf counters when the cpu is online (up prepare seems to be too
+ * soon).
+ */
+static
+int __cpuinit lttng_perf_counter_cpu_hp_callback(struct notifier_block *nb,
+						 unsigned long action,
+						 void *hcpu)
+{
+	unsigned int cpu = (unsigned long) hcpu;
+	struct lttng_perf_counter_field *perf_field =
+		container_of(nb, struct lttng_perf_counter_field, nb);
+	struct perf_event **events = perf_field->e;
+	struct perf_event_attr *attr = perf_field->attr;
+	struct perf_event *pevent;
+
+	if (!perf_field->hp_enable)
+		return NOTIFY_OK;
+
+	switch (action) {
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+		pevent = wrapper_perf_event_create_kernel_counter(attr,
+				cpu, NULL, overflow_callback);
+		if (!pevent || IS_ERR(pevent))
+			return NOTIFY_BAD;
+		if (pevent->state == PERF_EVENT_STATE_ERROR) {
+			perf_event_release_kernel(pevent);
+			return NOTIFY_BAD;
+		}
+		barrier();	/* Create perf counter before setting event */
+		events[cpu] = pevent;
+		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		pevent = events[cpu];
+		events[cpu] = NULL;
+		barrier();	/* NULLify event before perf counter teardown */
+		perf_event_release_kernel(pevent);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+#endif
+
+int lttng_add_perf_counter_to_ctx(uint32_t type,
+				  uint64_t config,
+				  const char *name,
+				  struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+	struct lttng_perf_counter_field *perf_field;
+	struct perf_event **events;
+	struct perf_event_attr *attr;
+	int ret;
+	int cpu;
+	char *name_alloc;
+
+	events = kzalloc(num_possible_cpus() * sizeof(*events), GFP_KERNEL);
+	if (!events)
+		return -ENOMEM;
+
+	attr = kzalloc(sizeof(struct perf_event_attr), GFP_KERNEL);
+	if (!attr) {
+		ret = -ENOMEM;
+		goto error_attr;
+	}
+
+	attr->type = type;
+	attr->config = config;
+	attr->size = sizeof(struct perf_event_attr);
+	attr->pinned = 1;
+	attr->disabled = 0;
+
+	perf_field = kzalloc(sizeof(struct lttng_perf_counter_field), GFP_KERNEL);
+	if (!perf_field) {
+		ret = -ENOMEM;
+		goto error_alloc_perf_field;
+	}
+	perf_field->e = events;
+	perf_field->attr = attr;
+
+	name_alloc = kstrdup(name, GFP_KERNEL);
+	if (!name_alloc) {
+		ret = -ENOMEM;
+		goto name_alloc_error;
+	}
+
+	field = lttng_append_context(ctx);
+	if (!field) {
+		ret = -ENOMEM;
+		goto append_context_error;
+	}
+	if (lttng_find_context(*ctx, name_alloc)) {
+		ret = -EEXIST;
+		goto find_error;
+	}
+
+#ifdef CONFIG_HOTPLUG_CPU
+	perf_field->nb.notifier_call =
+		lttng_perf_counter_cpu_hp_callback;
+	perf_field->nb.priority = 0;
+	register_cpu_notifier(&perf_field->nb);
+#endif
+
+	get_online_cpus();
+	for_each_online_cpu(cpu) {
+		events[cpu] = wrapper_perf_event_create_kernel_counter(attr,
+					cpu, NULL, overflow_callback);
+		if (!events[cpu] || IS_ERR(events[cpu])) {
+			ret = -EINVAL;
+			goto counter_error;
+		}
+		if (events[cpu]->state == PERF_EVENT_STATE_ERROR) {
+			ret = -EBUSY;
+			goto counter_busy;
+		}
+	}
+	put_online_cpus();
+
+	field->destroy = lttng_destroy_perf_counter_field;
+
+	field->event_field.name = name_alloc;
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(uint64_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(uint64_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(uint64_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = perf_counter_get_size;
+	field->record = perf_counter_record;
+	field->u.perf_counter = perf_field;
+	perf_field->hp_enable = 1;
+
+	wrapper_vmalloc_sync_all();
+	return 0;
+
+counter_busy:
+counter_error:
+	for_each_online_cpu(cpu) {
+		if (events[cpu] && !IS_ERR(events[cpu]))
+			perf_event_release_kernel(events[cpu]);
+	}
+	put_online_cpus();
+#ifdef CONFIG_HOTPLUG_CPU
+	unregister_cpu_notifier(&perf_field->nb);
+#endif
+find_error:
+	lttng_remove_context_field(ctx, field);
+append_context_error:
+	kfree(name_alloc);
+name_alloc_error:
+	kfree(perf_field);
+error_alloc_perf_field:
+	kfree(attr);
+error_attr:
+	kfree(events);
+	return ret;
+}
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Perf Support");
diff --git a/drivers/staging/lttng/lttng-context-pid.c b/drivers/staging/lttng/lttng-context-pid.c
new file mode 100644
index 0000000..698b242
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-pid.c
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng PID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t pid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void pid_record(struct lttng_ctx_field *field,
+		struct lib_ring_buffer_ctx *ctx,
+		struct ltt_channel *chan)
+{
+	pid_t pid;
+
+	pid = task_tgid_nr(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(pid));
+	chan->ops->event_write(ctx, &pid, sizeof(pid));
+}
+
+int lttng_add_pid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "pid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "pid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = pid_get_size;
+	field->record = pid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_pid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit PID Context");
diff --git a/drivers/staging/lttng/lttng-context-ppid.c b/drivers/staging/lttng/lttng-context-ppid.c
new file mode 100644
index 0000000..738f7e6
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-ppid.c
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng PPID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t ppid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void ppid_record(struct lttng_ctx_field *field,
+		 struct lib_ring_buffer_ctx *ctx,
+		 struct ltt_channel *chan)
+{
+	pid_t ppid;
+
+	rcu_read_lock();
+	ppid = task_tgid_nr(current->real_parent);
+	rcu_read_unlock();
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(ppid));
+	chan->ops->event_write(ctx, &ppid, sizeof(ppid));
+}
+
+int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "ppid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "ppid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = ppid_get_size;
+	field->record = ppid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_ppid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit PPID Context");
diff --git a/drivers/staging/lttng/lttng-context-prio.c b/drivers/staging/lttng/lttng-context-prio.c
new file mode 100644
index 0000000..1ee3a54
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-prio.c
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng priority context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "wrapper/kallsyms.h"
+#include "ltt-tracer.h"
+
+static
+int (*wrapper_task_prio_sym)(struct task_struct *t);
+
+int wrapper_task_prio_init(void)
+{
+	wrapper_task_prio_sym = (void *) kallsyms_lookup_funcptr("task_prio");
+	if (!wrapper_task_prio_sym) {
+		printk(KERN_WARNING "LTTng: task_prio symbol lookup failed.\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static
+size_t prio_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(int));
+	size += sizeof(int);
+	return size;
+}
+
+static
+void prio_record(struct lttng_ctx_field *field,
+		struct lib_ring_buffer_ctx *ctx,
+		struct ltt_channel *chan)
+{
+	int prio;
+
+	prio = wrapper_task_prio_sym(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(prio));
+	chan->ops->event_write(ctx, &prio, sizeof(prio));
+}
+
+int lttng_add_prio_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+	int ret;
+
+	if (!wrapper_task_prio_sym) {
+		ret = wrapper_task_prio_init();
+		if (ret)
+			return ret;
+	}
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "prio")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "prio";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(int);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = prio_get_size;
+	field->record = prio_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_prio_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Priority Context");
diff --git a/drivers/staging/lttng/lttng-context-procname.c b/drivers/staging/lttng/lttng-context-procname.c
new file mode 100644
index 0000000..c6bc646
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-procname.c
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng procname context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t procname_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += sizeof(current->comm);
+	return size;
+}
+
+/*
+ * Racy read of procname. We simply copy its whole array size.
+ * Races with /proc/<task>/procname write only.
+ * Otherwise having to take a mutex for each event is cumbersome and
+ * could lead to crash in IRQ context and deadlock of the lockdep tracer.
+ */
+static
+void procname_record(struct lttng_ctx_field *field,
+		 struct lib_ring_buffer_ctx *ctx,
+		 struct ltt_channel *chan)
+{
+	chan->ops->event_write(ctx, current->comm, sizeof(current->comm));
+}
+
+int lttng_add_procname_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "procname")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "procname";
+	field->event_field.type.atype = atype_array;
+	field->event_field.type.u.array.elem_type.atype = atype_integer;
+	field->event_field.type.u.array.elem_type.u.basic.integer.size = sizeof(char) * CHAR_BIT;
+	field->event_field.type.u.array.elem_type.u.basic.integer.alignment = ltt_alignof(char) * CHAR_BIT;
+	field->event_field.type.u.array.elem_type.u.basic.integer.signedness = is_signed_type(char);
+	field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.array.elem_type.u.basic.integer.base = 10;
+	field->event_field.type.u.array.elem_type.u.basic.integer.encoding = lttng_encode_UTF8;
+	field->event_field.type.u.array.length = sizeof(current->comm);
+
+	field->get_size = procname_get_size;
+	field->record = procname_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_procname_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Perf Support");
diff --git a/drivers/staging/lttng/lttng-context-tid.c b/drivers/staging/lttng/lttng-context-tid.c
new file mode 100644
index 0000000..d5ccdb6
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-tid.c
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng TID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t tid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void tid_record(struct lttng_ctx_field *field,
+		 struct lib_ring_buffer_ctx *ctx,
+		 struct ltt_channel *chan)
+{
+	pid_t tid;
+
+	tid = task_pid_nr(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(tid));
+	chan->ops->event_write(ctx, &tid, sizeof(tid));
+}
+
+int lttng_add_tid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "tid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "tid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = tid_get_size;
+	field->record = tid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_tid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit TID Context");
diff --git a/drivers/staging/lttng/lttng-context-vpid.c b/drivers/staging/lttng/lttng-context-vpid.c
new file mode 100644
index 0000000..3f16e03
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-vpid.c
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng vPID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t vpid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void vpid_record(struct lttng_ctx_field *field,
+		 struct lib_ring_buffer_ctx *ctx,
+		 struct ltt_channel *chan)
+{
+	pid_t vpid;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		vpid = 0;
+	else
+		vpid = task_tgid_vnr(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(vpid));
+	chan->ops->event_write(ctx, &vpid, sizeof(vpid));
+}
+
+int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vpid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vpid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vpid_get_size;
+	field->record = vpid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_vpid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit vPID Context");
diff --git a/drivers/staging/lttng/lttng-context-vppid.c b/drivers/staging/lttng/lttng-context-vppid.c
new file mode 100644
index 0000000..f01b020
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-vppid.c
@@ -0,0 +1,79 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng vPPID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t vppid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void vppid_record(struct lttng_ctx_field *field,
+		  struct lib_ring_buffer_ctx *ctx,
+		  struct ltt_channel *chan)
+{
+	struct task_struct *parent;
+	pid_t vppid;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	rcu_read_lock();
+	parent = rcu_dereference(current->real_parent);
+	if (!parent->nsproxy)
+		vppid = 0;
+	else
+		vppid = task_tgid_vnr(parent);
+	rcu_read_unlock();
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(vppid));
+	chan->ops->event_write(ctx, &vppid, sizeof(vppid));
+}
+
+int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vppid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vppid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vppid_get_size;
+	field->record = vppid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_vppid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit vPPID Context");
diff --git a/drivers/staging/lttng/lttng-context-vtid.c b/drivers/staging/lttng/lttng-context-vtid.c
new file mode 100644
index 0000000..264bbb3
--- /dev/null
+++ b/drivers/staging/lttng/lttng-context-vtid.c
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng vTID context.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "ltt-events.h"
+#include "wrapper/ringbuffer/frontend_types.h"
+#include "wrapper/vmalloc.h"
+#include "ltt-tracer.h"
+
+static
+size_t vtid_get_size(size_t offset)
+{
+	size_t size = 0;
+
+	size += lib_ring_buffer_align(offset, ltt_alignof(pid_t));
+	size += sizeof(pid_t);
+	return size;
+}
+
+static
+void vtid_record(struct lttng_ctx_field *field,
+		 struct lib_ring_buffer_ctx *ctx,
+		 struct ltt_channel *chan)
+{
+	pid_t vtid;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		vtid = 0;
+	else
+		vtid = task_pid_vnr(current);
+	lib_ring_buffer_align_ctx(ctx, ltt_alignof(vtid));
+	chan->ops->event_write(ctx, &vtid, sizeof(vtid));
+}
+
+int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx)
+{
+	struct lttng_ctx_field *field;
+
+	field = lttng_append_context(ctx);
+	if (!field)
+		return -ENOMEM;
+	if (lttng_find_context(*ctx, "vtid")) {
+		lttng_remove_context_field(ctx, field);
+		return -EEXIST;
+	}
+	field->event_field.name = "vtid";
+	field->event_field.type.atype = atype_integer;
+	field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT;
+	field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t);
+	field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+	field->event_field.type.u.basic.integer.base = 10;
+	field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+	field->get_size = vtid_get_size;
+	field->record = vtid_record;
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_vtid_to_ctx);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit vTID Context");
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 12/19] lttng: timing calibration feature
  2011-11-26 15:03                     ` [lttng-dev] [PATCH 11/19] lttng: dynamically selectable context information Mathieu Desnoyers
@ 2011-11-26 15:03                       ` Mathieu Desnoyers
  2011-11-26 15:03                         ` [lttng-dev] [PATCH 13/19] lttng: debugfs and procfs ABI Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


This calibration feature is fairly limited for now, but provides an
example of how this can be performed.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lttng-calibrate.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lttng-calibrate.c

diff --git a/drivers/staging/lttng/lttng-calibrate.c b/drivers/staging/lttng/lttng-calibrate.c
new file mode 100644
index 0000000..07e3c5b
--- /dev/null
+++ b/drivers/staging/lttng/lttng-calibrate.c
@@ -0,0 +1,30 @@
+/*
+ * lttng-calibrate.c
+ *
+ * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng probe calibration.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include "ltt-debugfs-abi.h"
+#include "ltt-events.h"
+
+noinline
+void lttng_calibrate_kretprobe(void)
+{
+	asm volatile ("");
+}
+
+int lttng_calibrate(struct lttng_kernel_calibrate *calibrate)
+{
+	switch (calibrate->type) {
+	case LTTNG_KERNEL_CALIBRATE_KRETPROBE:
+		lttng_calibrate_kretprobe();
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 13/19] lttng: debugfs and procfs ABI
  2011-11-26 15:03                       ` [lttng-dev] [PATCH 12/19] lttng: timing calibration feature Mathieu Desnoyers
@ 2011-11-26 15:03                         ` Mathieu Desnoyers
  2011-11-26 15:03                           ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Add the "lttng" virtual file to debugfs and procfs. All operations are
performed through ioctls (LTTng ioctl range is already reserved
upstream) on this virtual file and on anonymous file descriptors
returned by these ioctls. Each file descriptor is associated with a
tracer "object" (session, channel, stream, event, context).

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/ltt-debugfs-abi.c |  777 +++++++++++++++++++++++++++++++
 drivers/staging/lttng/ltt-debugfs-abi.h |  153 ++++++
 2 files changed, 930 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/ltt-debugfs-abi.c
 create mode 100644 drivers/staging/lttng/ltt-debugfs-abi.h

diff --git a/drivers/staging/lttng/ltt-debugfs-abi.c b/drivers/staging/lttng/ltt-debugfs-abi.c
new file mode 100644
index 0000000..37cccfa
--- /dev/null
+++ b/drivers/staging/lttng/ltt-debugfs-abi.c
@@ -0,0 +1,777 @@
+/*
+ * ltt-debugfs-abi.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng debugfs ABI
+ *
+ * Mimic system calls for:
+ * - session creation, returns a file descriptor or failure.
+ *   - channel creation, returns a file descriptor or failure.
+ *     - Operates on a session file descriptor
+ *     - Takes all channel options as parameters.
+ *   - stream get, returns a file descriptor or failure.
+ *     - Operates on a channel file descriptor.
+ *   - stream notifier get, returns a file descriptor or failure.
+ *     - Operates on a channel file descriptor.
+ *   - event creation, returns a file descriptor or failure.
+ *     - Operates on a channel file descriptor
+ *     - Takes an event name as parameter
+ *     - Takes an instrumentation source as parameter
+ *       - e.g. tracepoints, dynamic_probes...
+ *     - Takes instrumentation source specific arguments.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/proc_fs.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include "wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "wrapper/ringbuffer/vfs.h"
+#include "wrapper/poll.h"
+#include "ltt-debugfs-abi.h"
+#include "ltt-events.h"
+#include "ltt-tracer.h"
+
+/*
+ * This is LTTng's own personal way to create a system call as an external
+ * module. We use ioctl() on /sys/kernel/debug/lttng.
+ */
+
+static struct dentry *lttng_dentry;
+static struct proc_dir_entry *lttng_proc_dentry;
+static const struct file_operations lttng_fops;
+static const struct file_operations lttng_session_fops;
+static const struct file_operations lttng_channel_fops;
+static const struct file_operations lttng_metadata_fops;
+static const struct file_operations lttng_event_fops;
+
+/*
+ * Teardown management: opened file descriptors keep a refcount on the module,
+ * so it can only exit when all file descriptors are closed.
+ */
+
+enum channel_type {
+	PER_CPU_CHANNEL,
+	METADATA_CHANNEL,
+};
+
+static
+int lttng_abi_create_session(void)
+{
+	struct ltt_session *session;
+	struct file *session_file;
+	int session_fd, ret;
+
+	session = ltt_session_create();
+	if (!session)
+		return -ENOMEM;
+	session_fd = get_unused_fd();
+	if (session_fd < 0) {
+		ret = session_fd;
+		goto fd_error;
+	}
+	session_file = anon_inode_getfile("[lttng_session]",
+					  &lttng_session_fops,
+					  session, O_RDWR);
+	if (IS_ERR(session_file)) {
+		ret = PTR_ERR(session_file);
+		goto file_error;
+	}
+	session->file = session_file;
+	fd_install(session_fd, session_file);
+	return session_fd;
+
+file_error:
+	put_unused_fd(session_fd);
+fd_error:
+	ltt_session_destroy(session);
+	return ret;
+}
+
+static
+int lttng_abi_tracepoint_list(void)
+{
+	struct file *tracepoint_list_file;
+	int file_fd, ret;
+
+	file_fd = get_unused_fd();
+	if (file_fd < 0) {
+		ret = file_fd;
+		goto fd_error;
+	}
+
+	tracepoint_list_file = anon_inode_getfile("[lttng_session]",
+					  &lttng_tracepoint_list_fops,
+					  NULL, O_RDWR);
+	if (IS_ERR(tracepoint_list_file)) {
+		ret = PTR_ERR(tracepoint_list_file);
+		goto file_error;
+	}
+	ret = lttng_tracepoint_list_fops.open(NULL, tracepoint_list_file);
+	if (ret < 0)
+		goto open_error;
+	fd_install(file_fd, tracepoint_list_file);
+	if (file_fd < 0) {
+		ret = file_fd;
+		goto fd_error;
+	}
+	return file_fd;
+
+open_error:
+	fput(tracepoint_list_file);
+file_error:
+	put_unused_fd(file_fd);
+fd_error:
+	return ret;
+}
+
+static
+long lttng_abi_tracer_version(struct file *file, 
+	struct lttng_kernel_tracer_version __user *uversion_param)
+{
+	struct lttng_kernel_tracer_version v;
+
+	v.version = LTTNG_VERSION;
+	v.patchlevel = LTTNG_PATCHLEVEL;
+	v.sublevel = LTTNG_SUBLEVEL;
+
+	if (copy_to_user(uversion_param, &v, sizeof(v)))
+		return -EFAULT;
+	return 0;
+}
+
+static
+long lttng_abi_add_context(struct file *file,
+	struct lttng_kernel_context __user *ucontext_param,
+	struct lttng_ctx **ctx, struct ltt_session *session)
+{
+	struct lttng_kernel_context context_param;
+
+	if (session->been_active)
+		return -EPERM;
+
+	if (copy_from_user(&context_param, ucontext_param, sizeof(context_param)))
+		return -EFAULT;
+
+	switch (context_param.ctx) {
+	case LTTNG_KERNEL_CONTEXT_PID:
+		return lttng_add_pid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_PRIO:
+		return lttng_add_prio_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_NICE:
+		return lttng_add_nice_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_VPID:
+		return lttng_add_vpid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_TID:
+		return lttng_add_tid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_VTID:
+		return lttng_add_vtid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_PPID:
+		return lttng_add_ppid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_VPPID:
+		return lttng_add_vppid_to_ctx(ctx);
+	case LTTNG_KERNEL_CONTEXT_PERF_COUNTER:
+		context_param.u.perf_counter.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		return lttng_add_perf_counter_to_ctx(context_param.u.perf_counter.type,
+				context_param.u.perf_counter.config,
+				context_param.u.perf_counter.name,
+				ctx);
+	case LTTNG_KERNEL_CONTEXT_PROCNAME:
+		return lttng_add_procname_to_ctx(ctx);
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ *	lttng_ioctl - lttng syscall through ioctl
+ *
+ *	@file: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements lttng commands:
+ *	LTTNG_KERNEL_SESSION
+ *		Returns a LTTng trace session file descriptor
+ *	LTTNG_KERNEL_TRACER_VERSION
+ *		Returns the LTTng kernel tracer version
+ *	LTTNG_KERNEL_TRACEPOINT_LIST
+ *		Returns a file descriptor listing available tracepoints
+ *	LTTNG_KERNEL_WAIT_QUIESCENT
+ *		Returns after all previously running probes have completed
+ *
+ * The returned session will be deleted when its file descriptor is closed.
+ */
+static
+long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case LTTNG_KERNEL_SESSION:
+		return lttng_abi_create_session();
+	case LTTNG_KERNEL_TRACER_VERSION:
+		return lttng_abi_tracer_version(file,
+				(struct lttng_kernel_tracer_version __user *) arg);
+	case LTTNG_KERNEL_TRACEPOINT_LIST:
+		return lttng_abi_tracepoint_list();
+	case LTTNG_KERNEL_WAIT_QUIESCENT:
+		synchronize_trace();
+		return 0;
+	case LTTNG_KERNEL_CALIBRATE:
+	{
+		struct lttng_kernel_calibrate __user *ucalibrate =
+			(struct lttng_kernel_calibrate __user *) arg;
+		struct lttng_kernel_calibrate calibrate;
+		int ret;
+
+		if (copy_from_user(&calibrate, ucalibrate, sizeof(calibrate)))
+			return -EFAULT;
+		ret = lttng_calibrate(&calibrate);
+		if (copy_to_user(ucalibrate, &calibrate, sizeof(calibrate)))
+			return -EFAULT;
+		return ret;
+	}
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static const struct file_operations lttng_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = lttng_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lttng_ioctl,
+#endif
+};
+
+/*
+ * We tolerate no failure in this function (if one happens, we print a dmesg
+ * error, but cannot return any error, because the channel information is
+ * invariant.
+ */
+static
+void lttng_metadata_create_events(struct file *channel_file)
+{
+	struct ltt_channel *channel = channel_file->private_data;
+	static struct lttng_kernel_event metadata_params = {
+		.instrumentation = LTTNG_KERNEL_TRACEPOINT,
+		.name = "lttng_metadata",
+	};
+	struct ltt_event *event;
+
+	/*
+	 * We tolerate no failure path after event creation. It will stay
+	 * invariant for the rest of the session.
+	 */
+	event = ltt_event_create(channel, &metadata_params, NULL, NULL);
+	if (!event) {
+		goto create_error;
+	}
+	return;
+
+create_error:
+	WARN_ON(1);
+	return;		/* not allowed to return error */
+}
+
+static
+int lttng_abi_create_channel(struct file *session_file,
+			     struct lttng_kernel_channel __user *uchan_param,
+			     enum channel_type channel_type)
+{
+	struct ltt_session *session = session_file->private_data;
+	const struct file_operations *fops = NULL;
+	const char *transport_name;
+	struct ltt_channel *chan;
+	struct file *chan_file;
+	struct lttng_kernel_channel chan_param;
+	int chan_fd;
+	int ret = 0;
+
+	if (copy_from_user(&chan_param, uchan_param, sizeof(chan_param)))
+		return -EFAULT;
+	chan_fd = get_unused_fd();
+	if (chan_fd < 0) {
+		ret = chan_fd;
+		goto fd_error;
+	}
+	switch (channel_type) {
+	case PER_CPU_CHANNEL:
+		fops = &lttng_channel_fops;
+		break;
+	case METADATA_CHANNEL:
+		fops = &lttng_metadata_fops;
+		break;
+	}
+		
+	chan_file = anon_inode_getfile("[lttng_channel]",
+				       fops,
+				       NULL, O_RDWR);
+	if (IS_ERR(chan_file)) {
+		ret = PTR_ERR(chan_file);
+		goto file_error;
+	}
+	switch (channel_type) {
+	case PER_CPU_CHANNEL:
+		if (chan_param.output == LTTNG_KERNEL_SPLICE) {
+			transport_name = chan_param.overwrite ?
+				"relay-overwrite" : "relay-discard";
+		} else if (chan_param.output == LTTNG_KERNEL_MMAP) {
+			transport_name = chan_param.overwrite ?
+				"relay-overwrite-mmap" : "relay-discard-mmap";
+		} else {
+			return -EINVAL;
+		}
+		break;
+	case METADATA_CHANNEL:
+		if (chan_param.output == LTTNG_KERNEL_SPLICE)
+			transport_name = "relay-metadata";
+		else if (chan_param.output == LTTNG_KERNEL_MMAP)
+			transport_name = "relay-metadata-mmap";
+		else
+			return -EINVAL;
+		break;
+	default:
+		transport_name = "<unknown>";
+		break;
+	}
+	/*
+	 * We tolerate no failure path after channel creation. It will stay
+	 * invariant for the rest of the session.
+	 */
+	chan = ltt_channel_create(session, transport_name, NULL,
+				  chan_param.subbuf_size,
+				  chan_param.num_subbuf,
+				  chan_param.switch_timer_interval,
+				  chan_param.read_timer_interval);
+	if (!chan) {
+		ret = -EINVAL;
+		goto chan_error;
+	}
+	chan->file = chan_file;
+	chan_file->private_data = chan;
+	fd_install(chan_fd, chan_file);
+	if (channel_type == METADATA_CHANNEL) {
+		session->metadata = chan;
+		lttng_metadata_create_events(chan_file);
+	}
+
+	/* The channel created holds a reference on the session */
+	atomic_long_inc(&session_file->f_count);
+
+	return chan_fd;
+
+chan_error:
+	fput(chan_file);
+file_error:
+	put_unused_fd(chan_fd);
+fd_error:
+	return ret;
+}
+
+/**
+ *	lttng_session_ioctl - lttng session fd ioctl
+ *
+ *	@file: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements lttng commands:
+ *	LTTNG_KERNEL_CHANNEL
+ *		Returns a LTTng channel file descriptor
+ *	LTTNG_KERNEL_ENABLE
+ *		Enables tracing for a session (weak enable)
+ *	LTTNG_KERNEL_DISABLE
+ *		Disables tracing for a session (strong disable)
+ *	LTTNG_KERNEL_METADATA
+ *		Returns a LTTng metadata file descriptor
+ *
+ * The returned channel will be deleted when its file descriptor is closed.
+ */
+static
+long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct ltt_session *session = file->private_data;
+
+	switch (cmd) {
+	case LTTNG_KERNEL_CHANNEL:
+		return lttng_abi_create_channel(file,
+				(struct lttng_kernel_channel __user *) arg,
+				PER_CPU_CHANNEL);
+	case LTTNG_KERNEL_SESSION_START:
+	case LTTNG_KERNEL_ENABLE:
+		return ltt_session_enable(session);
+	case LTTNG_KERNEL_SESSION_STOP:
+	case LTTNG_KERNEL_DISABLE:
+		return ltt_session_disable(session);
+	case LTTNG_KERNEL_METADATA:
+		return lttng_abi_create_channel(file,
+				(struct lttng_kernel_channel __user *) arg,
+				METADATA_CHANNEL);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+/*
+ * Called when the last file reference is dropped.
+ *
+ * Big fat note: channels and events are invariant for the whole session after
+ * their creation. So this session destruction also destroys all channel and
+ * event structures specific to this session (they are not destroyed when their
+ * individual file is released).
+ */
+static
+int lttng_session_release(struct inode *inode, struct file *file)
+{
+	struct ltt_session *session = file->private_data;
+
+	if (session)
+		ltt_session_destroy(session);
+	return 0;
+}
+
+static const struct file_operations lttng_session_fops = {
+	.owner = THIS_MODULE,
+	.release = lttng_session_release,
+	.unlocked_ioctl = lttng_session_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lttng_session_ioctl,
+#endif
+};
+
+static
+int lttng_abi_open_stream(struct file *channel_file)
+{
+	struct ltt_channel *channel = channel_file->private_data;
+	struct lib_ring_buffer *buf;
+	int stream_fd, ret;
+	struct file *stream_file;
+
+	buf = channel->ops->buffer_read_open(channel->chan);
+	if (!buf)
+		return -ENOENT;
+
+	stream_fd = get_unused_fd();
+	if (stream_fd < 0) {
+		ret = stream_fd;
+		goto fd_error;
+	}
+	stream_file = anon_inode_getfile("[lttng_stream]",
+					 &lib_ring_buffer_file_operations,
+					 buf, O_RDWR);
+	if (IS_ERR(stream_file)) {
+		ret = PTR_ERR(stream_file);
+		goto file_error;
+	}
+	/*
+	 * OPEN_FMODE, called within anon_inode_getfile/alloc_file, don't honor
+	 * FMODE_LSEEK, FMODE_PREAD nor FMODE_PWRITE. We need to read from this
+	 * file descriptor, so we set FMODE_PREAD here.
+	 */
+	stream_file->f_mode |= FMODE_PREAD;
+	fd_install(stream_fd, stream_file);
+	/*
+	 * The stream holds a reference to the channel within the generic ring
+	 * buffer library, so no need to hold a refcount on the channel and
+	 * session files here.
+	 */
+	return stream_fd;
+
+file_error:
+	put_unused_fd(stream_fd);
+fd_error:
+	channel->ops->buffer_read_close(buf);
+	return ret;
+}
+
+static
+int lttng_abi_create_event(struct file *channel_file,
+			   struct lttng_kernel_event __user *uevent_param)
+{
+	struct ltt_channel *channel = channel_file->private_data;
+	struct ltt_event *event;
+	struct lttng_kernel_event event_param;
+	int event_fd, ret;
+	struct file *event_file;
+
+	if (copy_from_user(&event_param, uevent_param, sizeof(event_param)))
+		return -EFAULT;
+	event_param.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+	switch (event_param.instrumentation) {
+	case LTTNG_KERNEL_KRETPROBE:
+		event_param.u.kretprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		break;
+	case LTTNG_KERNEL_KPROBE:
+		event_param.u.kprobe.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		break;
+	case LTTNG_KERNEL_FUNCTION:
+		event_param.u.ftrace.symbol_name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		break;
+	default:
+		break;
+	}
+	switch (event_param.instrumentation) {
+	default:
+		event_fd = get_unused_fd();
+		if (event_fd < 0) {
+			ret = event_fd;
+			goto fd_error;
+		}
+		event_file = anon_inode_getfile("[lttng_event]",
+						&lttng_event_fops,
+						NULL, O_RDWR);
+		if (IS_ERR(event_file)) {
+			ret = PTR_ERR(event_file);
+			goto file_error;
+		}
+		/*
+		 * We tolerate no failure path after event creation. It
+		 * will stay invariant for the rest of the session.
+		 */
+		event = ltt_event_create(channel, &event_param, NULL, NULL);
+		if (!event) {
+			ret = -EINVAL;
+			goto event_error;
+		}
+		event_file->private_data = event;
+		fd_install(event_fd, event_file);
+		/* The event holds a reference on the channel */
+		atomic_long_inc(&channel_file->f_count);
+		break;
+	case LTTNG_KERNEL_SYSCALL:
+		/*
+		 * Only all-syscall tracing supported for now.
+		 */
+		if (event_param.name[0] != '\0')
+			return -EINVAL;
+		ret = lttng_syscalls_register(channel, NULL);
+		if (ret)
+			goto fd_error;
+		event_fd = 0;
+		break;
+	}
+	return event_fd;
+
+event_error:
+	fput(event_file);
+file_error:
+	put_unused_fd(event_fd);
+fd_error:
+	return ret;
+}
+
+/**
+ *	lttng_channel_ioctl - lttng syscall through ioctl
+ *
+ *	@file: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements lttng commands:
+ *      LTTNG_KERNEL_STREAM
+ *              Returns an event stream file descriptor or failure.
+ *              (typically, one event stream records events from one CPU)
+ *	LTTNG_KERNEL_EVENT
+ *		Returns an event file descriptor or failure.
+ *	LTTNG_KERNEL_CONTEXT
+ *		Prepend a context field to each event in the channel
+ *	LTTNG_KERNEL_ENABLE
+ *		Enable recording for events in this channel (weak enable)
+ *	LTTNG_KERNEL_DISABLE
+ *		Disable recording for events in this channel (strong disable)
+ *
+ * Channel and event file descriptors also hold a reference on the session.
+ */
+static
+long lttng_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct ltt_channel *channel = file->private_data;
+
+	switch (cmd) {
+	case LTTNG_KERNEL_STREAM:
+		return lttng_abi_open_stream(file);
+	case LTTNG_KERNEL_EVENT:
+		return lttng_abi_create_event(file, (struct lttng_kernel_event __user *) arg);
+	case LTTNG_KERNEL_CONTEXT:
+		return lttng_abi_add_context(file,
+				(struct lttng_kernel_context __user *) arg,
+				&channel->ctx, channel->session);
+	case LTTNG_KERNEL_ENABLE:
+		return ltt_channel_enable(channel);
+	case LTTNG_KERNEL_DISABLE:
+		return ltt_channel_disable(channel);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+/**
+ *	lttng_metadata_ioctl - lttng syscall through ioctl
+ *
+ *	@file: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements lttng commands:
+ *      LTTNG_KERNEL_STREAM
+ *              Returns an event stream file descriptor or failure.
+ *
+ * Channel and event file descriptors also hold a reference on the session.
+ */
+static
+long lttng_metadata_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case LTTNG_KERNEL_STREAM:
+		return lttng_abi_open_stream(file);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+/**
+ *	lttng_channel_poll - lttng stream addition/removal monitoring
+ *
+ *	@file: the file
+ *	@wait: poll table
+ */
+unsigned int lttng_channel_poll(struct file *file, poll_table *wait)
+{
+	struct ltt_channel *channel = file->private_data;
+	unsigned int mask = 0;
+
+	if (file->f_mode & FMODE_READ) {
+		poll_wait_set_exclusive(wait);
+		poll_wait(file, channel->ops->get_hp_wait_queue(channel->chan),
+			  wait);
+
+		if (channel->ops->is_disabled(channel->chan))
+			return POLLERR;
+		if (channel->ops->is_finalized(channel->chan))
+			return POLLHUP;
+		if (channel->ops->buffer_has_read_closed_stream(channel->chan))
+			return POLLIN | POLLRDNORM;
+		return 0;
+	}
+	return mask;
+
+}
+
+static
+int lttng_channel_release(struct inode *inode, struct file *file)
+{
+	struct ltt_channel *channel = file->private_data;
+
+	if (channel)
+		fput(channel->session->file);
+	return 0;
+}
+
+static const struct file_operations lttng_channel_fops = {
+	.owner = THIS_MODULE,
+	.release = lttng_channel_release,
+	.poll = lttng_channel_poll,
+	.unlocked_ioctl = lttng_channel_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lttng_channel_ioctl,
+#endif
+};
+
+static const struct file_operations lttng_metadata_fops = {
+	.owner = THIS_MODULE,
+	.release = lttng_channel_release,
+	.unlocked_ioctl = lttng_metadata_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lttng_metadata_ioctl,
+#endif
+};
+
+/**
+ *	lttng_event_ioctl - lttng syscall through ioctl
+ *
+ *	@file: the file
+ *	@cmd: the command
+ *	@arg: command arg
+ *
+ *	This ioctl implements lttng commands:
+ *	LTTNG_KERNEL_CONTEXT
+ *		Prepend a context field to each record of this event
+ *	LTTNG_KERNEL_ENABLE
+ *		Enable recording for this event (weak enable)
+ *	LTTNG_KERNEL_DISABLE
+ *		Disable recording for this event (strong disable)
+ */
+static
+long lttng_event_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct ltt_event *event = file->private_data;
+
+	switch (cmd) {
+	case LTTNG_KERNEL_CONTEXT:
+		return lttng_abi_add_context(file,
+				(struct lttng_kernel_context __user *) arg,
+				&event->ctx, event->chan->session);
+	case LTTNG_KERNEL_ENABLE:
+		return ltt_event_enable(event);
+	case LTTNG_KERNEL_DISABLE:
+		return ltt_event_disable(event);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static
+int lttng_event_release(struct inode *inode, struct file *file)
+{
+	struct ltt_event *event = file->private_data;
+
+	if (event)
+		fput(event->chan->file);
+	return 0;
+}
+
+/* TODO: filter control ioctl */
+static const struct file_operations lttng_event_fops = {
+	.owner = THIS_MODULE,
+	.release = lttng_event_release,
+	.unlocked_ioctl = lttng_event_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = lttng_event_ioctl,
+#endif
+};
+
+int __init ltt_debugfs_abi_init(void)
+{
+	int ret = 0;
+
+	wrapper_vmalloc_sync_all();
+	lttng_dentry = debugfs_create_file("lttng", S_IWUSR, NULL, NULL,
+					&lttng_fops);
+	if (IS_ERR(lttng_dentry))
+		lttng_dentry = NULL;
+
+	lttng_proc_dentry = proc_create_data("lttng", S_IWUSR, NULL,
+					&lttng_fops, NULL);
+	
+	if (!lttng_dentry && !lttng_proc_dentry) {
+		printk(KERN_ERR "Error creating LTTng control file\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+error:
+	return ret;
+}
+
+void __exit ltt_debugfs_abi_exit(void)
+{
+	if (lttng_dentry)
+		debugfs_remove(lttng_dentry);
+	if (lttng_proc_dentry)
+		remove_proc_entry("lttng", NULL);
+}
diff --git a/drivers/staging/lttng/ltt-debugfs-abi.h b/drivers/staging/lttng/ltt-debugfs-abi.h
new file mode 100644
index 0000000..42bc9fd
--- /dev/null
+++ b/drivers/staging/lttng/ltt-debugfs-abi.h
@@ -0,0 +1,153 @@
+#ifndef _LTT_DEBUGFS_ABI_H
+#define _LTT_DEBUGFS_ABI_H
+
+/*
+ * ltt-debugfs-abi.h
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng debugfs ABI header
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/fs.h>
+
+#define LTTNG_SYM_NAME_LEN	128
+
+enum lttng_kernel_instrumentation {
+	LTTNG_KERNEL_TRACEPOINT	= 0,
+	LTTNG_KERNEL_KPROBE	= 1,
+	LTTNG_KERNEL_FUNCTION	= 2,
+	LTTNG_KERNEL_KRETPROBE	= 3,
+	LTTNG_KERNEL_NOOP	= 4,	/* not hooked */
+	LTTNG_KERNEL_SYSCALL	= 5,
+};
+
+/*
+ * LTTng consumer mode
+ */
+enum lttng_kernel_output {
+	LTTNG_KERNEL_SPLICE	= 0,
+	LTTNG_KERNEL_MMAP	= 1,
+};
+
+/*
+ * LTTng DebugFS ABI structures.
+ */
+
+struct lttng_kernel_channel {
+	int overwrite;				/* 1: overwrite, 0: discard */
+	uint64_t subbuf_size;			/* in bytes */
+	uint64_t num_subbuf;
+	unsigned int switch_timer_interval;	/* usecs */
+	unsigned int read_timer_interval;	/* usecs */
+	enum lttng_kernel_output output;	/* splice, mmap */
+};
+
+struct lttng_kernel_kretprobe {
+	uint64_t addr;
+
+	uint64_t offset;
+	char symbol_name[LTTNG_SYM_NAME_LEN];
+};
+
+/*
+ * Either addr is used, or symbol_name and offset.
+ */
+struct lttng_kernel_kprobe {
+	uint64_t addr;
+
+	uint64_t offset;
+	char symbol_name[LTTNG_SYM_NAME_LEN];
+};
+
+struct lttng_kernel_function_tracer {
+	char symbol_name[LTTNG_SYM_NAME_LEN];
+};
+
+/*
+ * For syscall tracing, name = '\0' means "enable all".
+ */
+struct lttng_kernel_event {
+	char name[LTTNG_SYM_NAME_LEN];	/* event name */
+	enum lttng_kernel_instrumentation instrumentation;
+	/* Per instrumentation type configuration */
+	union {
+		struct lttng_kernel_kretprobe kretprobe;
+		struct lttng_kernel_kprobe kprobe;
+		struct lttng_kernel_function_tracer ftrace;
+	} u;
+};
+
+struct lttng_kernel_tracer_version {
+	uint32_t version;
+	uint32_t patchlevel;
+	uint32_t sublevel;
+};
+
+enum lttng_kernel_calibrate_type {
+	LTTNG_KERNEL_CALIBRATE_KRETPROBE,
+};
+
+struct lttng_kernel_calibrate {
+	enum lttng_kernel_calibrate_type type;	/* type (input) */
+};
+
+enum lttng_kernel_context_type {
+	LTTNG_KERNEL_CONTEXT_PID		= 0,
+	LTTNG_KERNEL_CONTEXT_PERF_COUNTER	= 1,
+	LTTNG_KERNEL_CONTEXT_PROCNAME		= 2,
+	LTTNG_KERNEL_CONTEXT_PRIO		= 3,
+	LTTNG_KERNEL_CONTEXT_NICE		= 4,
+	LTTNG_KERNEL_CONTEXT_VPID		= 5,
+	LTTNG_KERNEL_CONTEXT_TID		= 6,
+	LTTNG_KERNEL_CONTEXT_VTID		= 7,
+	LTTNG_KERNEL_CONTEXT_PPID		= 8,
+	LTTNG_KERNEL_CONTEXT_VPPID		= 9,
+};
+
+struct lttng_kernel_perf_counter_ctx {
+	uint32_t type;
+	uint64_t config;
+	char name[LTTNG_SYM_NAME_LEN];
+};
+
+struct lttng_kernel_context {
+	enum lttng_kernel_context_type ctx;
+	union {
+		struct lttng_kernel_perf_counter_ctx perf_counter;
+	} u;
+};
+
+/* LTTng file descriptor ioctl */
+#define LTTNG_KERNEL_SESSION			_IO(0xF6, 0x40)
+#define LTTNG_KERNEL_TRACER_VERSION		\
+	_IOR(0xF6, 0x41, struct lttng_kernel_tracer_version)
+#define LTTNG_KERNEL_TRACEPOINT_LIST		_IO(0xF6, 0x42)
+#define LTTNG_KERNEL_WAIT_QUIESCENT		_IO(0xF6, 0x43)
+#define LTTNG_KERNEL_CALIBRATE			\
+	_IOWR(0xF6, 0x44, struct lttng_kernel_calibrate)
+
+/* Session FD ioctl */
+#define LTTNG_KERNEL_METADATA			\
+	_IOW(0xF6, 0x50, struct lttng_kernel_channel)
+#define LTTNG_KERNEL_CHANNEL			\
+	_IOW(0xF6, 0x51, struct lttng_kernel_channel)
+#define LTTNG_KERNEL_SESSION_START		_IO(0xF6, 0x52)
+#define LTTNG_KERNEL_SESSION_STOP		_IO(0xF6, 0x53)
+
+/* Channel FD ioctl */
+#define LTTNG_KERNEL_STREAM			_IO(0xF6, 0x60)
+#define LTTNG_KERNEL_EVENT			\
+	_IOW(0xF6, 0x61, struct lttng_kernel_event)
+
+/* Event and Channel FD ioctl */
+#define LTTNG_KERNEL_CONTEXT			\
+	_IOW(0xF6, 0x70, struct lttng_kernel_context)
+
+/* Event, Channel and Session ioctl */
+#define LTTNG_KERNEL_ENABLE			_IO(0xF6, 0x80)
+#define LTTNG_KERNEL_DISABLE			_IO(0xF6, 0x81)
+
+#endif /* _LTT_DEBUGFS_ABI_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files
  2011-11-26 15:03                         ` [lttng-dev] [PATCH 13/19] lttng: debugfs and procfs ABI Mathieu Desnoyers
@ 2011-11-26 15:03                           ` Mathieu Desnoyers
  2011-11-26 15:03                             ` [lttng-dev] [PATCH 15/19] lttng: add system call instrumentation probe Mathieu Desnoyers
  2011-11-27  2:24                             ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Greg KH
  0 siblings, 2 replies; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/ChangeLog    |   75 ++++++
 drivers/staging/lttng/LICENSE      |   27 ++
 drivers/staging/lttng/README       |   46 ++++
 drivers/staging/lttng/gpl-2.0.txt  |  339 ++++++++++++++++++++++++
 drivers/staging/lttng/lgpl-2.1.txt |  504 ++++++++++++++++++++++++++++++++++++
 5 files changed, 991 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/ChangeLog
 create mode 100644 drivers/staging/lttng/LICENSE
 create mode 100644 drivers/staging/lttng/README
 create mode 100644 drivers/staging/lttng/gpl-2.0.txt
 create mode 100644 drivers/staging/lttng/lgpl-2.1.txt

diff --git a/drivers/staging/lttng/ChangeLog b/drivers/staging/lttng/ChangeLog
new file mode 100644
index 0000000..982d391
--- /dev/null
+++ b/drivers/staging/lttng/ChangeLog
@@ -0,0 +1,75 @@
+2011-09-30 LTTng modules 2.0-pre10
+	* x86-32: override sys_mmap syscall instrumentation
+	* Fix cast warning
+
+2011-09-29 LTTng modules 2.0-pre9
+	* x86 32 syscalls: fix !CONFIG_UID16
+	* Use __string_from_user
+	* Add __string_from_user
+	* Rename "comm" context to "procname"
+	* Fetch "type" name field for mount syscall
+	* Create common override file for all architectures
+	* Shrink stack size usage
+	* Cleanup: remove unused lttng-compat-syscalls.c file
+	* Support detailed compat syscalls on x86_64
+	* Fix syscall table
+	* Add disabled compat syscalls detail (work in progress)
+	* Add config compat support for detailed x86_32 syscalls
+	* Handle newer 3.1+ perf API
+	* Add dummy x86-32 override headers
+	* Bind x86-32 syscall headers
+	* Add x86-32 syscall headers
+	* Add check for KALLSYMS_ALL in syscall extraction script
+	* Automate string extraction for syscalls
+	* Automate syscall filename/pathname extraction
+	* Add exit to ring_buffer_frontend so module is unloadable
+	* Add sys_open filename (x86_64)
+	* Add missing memcpy callback
+	* copy_from_user and memset
+	* Add missing alignment after header write
+	* lib ring buffer: add frontend init as module_init
+	* lib ring buffer frontend: add missing lock initialization
+	* ARM: Set bit 0 for thumb mode in kallsyms_lookup_name returned address (missing file)
+	* ARM: Set bit 0 for thumb mode in kallsyms_lookup_name returned address
+	* Create override for sys_mmap
+	* Rename syscalls -> syscall in LTTng ABI
+	* Use different event name for compat syscalls
+	* Allow trace syscall table override
+	* Add dummy override files
+	* syscall detail: add override capability
+	* Add pointer pretty-print heuristics
+	* Add __field_hex
+	* Rename sys exit errno into ret
+	* Enable detailed syscalls only for native x86_64
+	* Use "unknown" for compat syscalls
+	* Disable x86-64 specific detailed syscalls for now, until we deal with 32-bit compat
+	* Fix syscall exit
+	* Fix sys exit
+	* Only enable detailed syscalls for x86_64 for now
+	* Merge unknown syscall method with extended detail method
+	* Add underscore prefix before event names
+	* Add syscalls pointers detailed syscall tracing
+	* Use perl for regexp
+	* Support generation of syscall probes for those with pointers
+	* Support detailed syscalls with 0 arguments
+	* detailed syscall tracing (work in progress)
+	* Expose /proc/lttng file
+	* Implement detailed syscall event probe
+	* Disable perf build for < 2.6.33 kernels
+	* Syscall detail mode: generate syscall table
+	* block instrumentation: write cmd as hex sequence
+	* lttng-events TRACE_EVENT generator cleanup
+	* block layer instrumentation: fix cmd field
+	* Remove 0 args syscalls for now from type-aware syscall cb generator
+	* Generate trace syscall table macros
+	* Put syscall tracing without arg types back in place
+	* Detailed system call tracing (TRACE_EVENT() generation for integer support)
+	* lttng events probes: don't clash with "ctx" variable name
+	* lib ring buffer must take private pointer copy before decrementing refcount
+
+2011-08-16 LTTng modules 2.0-pre8
+	* Fix metadata buffer wait/wakeup
+
+2011-08-12 LTTng modules 2.0-pre7
+	* Add missing module refcount to lttng_tracepoint_list_fops
+	* Add license info about lib/ringbuffer/ring_buffer_mmap.c being GPLv2
diff --git a/drivers/staging/lttng/LICENSE b/drivers/staging/lttng/LICENSE
new file mode 100644
index 0000000..bb880bf
--- /dev/null
+++ b/drivers/staging/lttng/LICENSE
@@ -0,0 +1,27 @@
+LTTng modules licensing
+Mathieu Desnoyers
+June 2, 2011
+
+* LGPLv2.1/GPLv2 dual-license
+
+The files contained within this package are licensed under
+LGPLv2.1/GPLv2 dual-license (see lgpl-2.1.txt and gpl-2.0.txt for
+details), except for files identified by the following sections.
+
+* GPLv2 license
+
+These files are licensed exclusively under the GPLv2 license. See
+gpl-2.0.txt for details.
+
+lib/ringbuffer/ring_buffer_splice.c
+lib/ringbuffer/ring_buffer_mmap.c
+instrumentation/events/mainline/*.h
+instrumentation/events/lttng-modules/*.h
+
+* MIT-style license
+
+These files are licensed under an MIT-style license:
+
+lib/prio_heap/lttng_prio_heap.h
+lib/prio_heap/lttng_prio_heap.c
+lib/bitfield.h
diff --git a/drivers/staging/lttng/README b/drivers/staging/lttng/README
new file mode 100644
index 0000000..90cf200
--- /dev/null
+++ b/drivers/staging/lttng/README
@@ -0,0 +1,46 @@
+LTTng 2.0 modules
+
+Mathieu Desnoyers
+November 1st, 2011
+
+LTTng 2.0 kernel modules is currently part of the Linux kernel staging
+tree. It features (new features since LTTng 0.x):
+
+- Produces CTF (Common Trace Format) natively,
+  (http://www.efficios.com/ctf)
+- Tracepoints, Function tracer, CPU Performance Monitoring Unit (PMU)
+  counters, kprobes, and kretprobes support,
+- Integrated interface for both kernel and userspace tracing,
+- Have the ability to attach "context" information to events in the
+  trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc).
+  All the extra information fields to be collected with events are
+  optional, specified on a per-tracing-session basis (except for
+  timestamp and event id, which are mandatory).
+
+To build and install, you need to select "Staging" modules, and the
+LTTng kernel tracer.
+
+Use lttng-tools to control the tracer. LTTng tools should automatically load
+the kernel modules when needed. Use Babeltrace to print traces as a
+human-readable text log. These tools are available at the following URL:
+http://lttng.org/lttng2.0
+
+Please note that the LTTng-UST 2.0 (user-space tracing counterpart of LTTng 2.0)
+is still in active development and not released yet.
+
+So far, it has been tested on vanilla Linux kernels 2.6.38, 2.6.39 and 3.0 (on
+x86 32/64-bit, and powerpc 32-bit at the moment, build tested on ARM). It should
+work fine with newer kernels and other architectures, but expect build issues
+with kernels older than 2.6.36. The clock source currently used is the standard
+gettimeofday (slower, less scalable and less precise than the LTTng 0.x clocks).
+Support for LTTng 0.x clocks will be added back soon into LTTng 2.0.  Please
+note that lttng-modules 2.0 can build on a Linux kernel patched with the LTTng
+0.x patchset, but the lttng-modules 2.0 replace the lttng-modules 0.x, so both
+tracers cannot be installed at the same time for a given kernel version.
+
+* Note about Perf PMU counters support
+
+Each PMU counter has its zero value set when it is attached to a context with
+add-context. Therefore, it is normal that the same counters attached to both the
+stream context and event context show different values for a given event; what
+matters is that they increment at the same rate.
diff --git a/drivers/staging/lttng/gpl-2.0.txt b/drivers/staging/lttng/gpl-2.0.txt
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/drivers/staging/lttng/gpl-2.0.txt
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/drivers/staging/lttng/lgpl-2.1.txt b/drivers/staging/lttng/lgpl-2.1.txt
new file mode 100644
index 0000000..602bfc9
--- /dev/null
+++ b/drivers/staging/lttng/lgpl-2.1.txt
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 15/19] lttng: add system call instrumentation probe
  2011-11-26 15:03                           ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Mathieu Desnoyers
@ 2011-11-26 15:03                             ` Mathieu Desnoyers
  2011-11-26 15:03                               ` [lttng-dev] [PATCH 16/19] lttng: probe callbacks Mathieu Desnoyers
  2011-11-27  2:24                             ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Greg KH
  1 sibling, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/lttng-syscalls.c |  437 ++++++++++++++++++++++++++++++++
 1 files changed, 437 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/lttng-syscalls.c

diff --git a/drivers/staging/lttng/lttng-syscalls.c b/drivers/staging/lttng/lttng-syscalls.c
new file mode 100644
index 0000000..9de3c07
--- /dev/null
+++ b/drivers/staging/lttng/lttng-syscalls.c
@@ -0,0 +1,437 @@
+/*
+ * lttng-syscalls.c
+ *
+ * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng syscall probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/compat.h>
+#include <asm/ptrace.h>
+#include <asm/syscall.h>
+
+#include "ltt-events.h"
+
+#ifndef CONFIG_COMPAT
+static inline int is_compat_task(void)
+{
+	return 0;
+}
+#endif
+
+static
+void syscall_entry_probe(void *__data, struct pt_regs *regs, long id);
+
+/*
+ * Take care of NOARGS not supported by mainline.
+ */
+#define DECLARE_EVENT_CLASS_NOARGS(name, tstruct, assign, print)
+#define DEFINE_EVENT_NOARGS(template, name)
+#define TRACE_EVENT_NOARGS(name, struct, assign, print)
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TP_MODULE_OVERRIDE
+#define TRACE_INCLUDE_PATH ../instrumentation/syscalls/headers
+
+#define PARAMS(args...)	args
+
+/* Hijack probe callback for system calls */
+#undef TP_PROBE_CB
+#define TP_PROBE_CB(_template)		&syscall_entry_probe
+#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk)	\
+	TRACE_EVENT(_name, PARAMS(_proto), PARAMS(_args),\
+		PARAMS(_struct), PARAMS(_assign), PARAMS(_printk))
+#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk)	\
+	DECLARE_EVENT_CLASS_NOARGS(_name, PARAMS(_struct), PARAMS(_assign),\
+		PARAMS(_printk))
+#define SC_DEFINE_EVENT_NOARGS(_template, _name)			\
+	DEFINE_EVENT_NOARGS(_template, _name)
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM syscalls_integers
+#include "instrumentation/syscalls/headers/syscalls_integers.h"
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM syscalls_pointers
+#include "instrumentation/syscalls/headers/syscalls_pointers.h"
+#undef TRACE_SYSTEM
+#undef SC_TRACE_EVENT
+#undef SC_DECLARE_EVENT_CLASS_NOARGS
+#undef SC_DEFINE_EVENT_NOARGS
+
+#define TRACE_SYSTEM syscalls_unknown
+#include "instrumentation/syscalls/headers/syscalls_unknown.h"
+#undef TRACE_SYSTEM
+
+/* For compat syscalls */
+#undef _TRACE_SYSCALLS_integers_H
+#undef _TRACE_SYSCALLS_pointers_H
+
+/* Hijack probe callback for system calls */
+#undef TP_PROBE_CB
+#define TP_PROBE_CB(_template)		&syscall_entry_probe
+#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk)	\
+	TRACE_EVENT(compat_##_name, PARAMS(_proto), PARAMS(_args),	\
+		PARAMS(_struct), PARAMS(_assign),			\
+		PARAMS(_printk))
+#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \
+	DECLARE_EVENT_CLASS_NOARGS(compat_##_name, PARAMS(_struct),	\
+		PARAMS(_assign), PARAMS(_printk))
+#define SC_DEFINE_EVENT_NOARGS(_template, _name)			\
+	DEFINE_EVENT_NOARGS(compat_##_template, compat_##_name)
+#define TRACE_SYSTEM compat_syscalls_integers
+#include "instrumentation/syscalls/headers/compat_syscalls_integers.h"
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM compat_syscalls_pointers
+#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h"
+#undef TRACE_SYSTEM
+#undef SC_TRACE_EVENT
+#undef SC_DECLARE_EVENT_CLASS_NOARGS
+#undef SC_DEFINE_EVENT_NOARGS
+#undef TP_PROBE_CB
+
+#undef TP_MODULE_OVERRIDE
+#undef LTTNG_PACKAGE_BUILD
+#undef CREATE_TRACE_POINTS
+
+struct trace_syscall_entry {
+	void *func;
+	const struct lttng_event_desc *desc;
+	const struct lttng_event_field *fields;
+	unsigned int nrargs;
+};
+
+#define CREATE_SYSCALL_TABLE
+
+#undef TRACE_SYSCALL_TABLE
+#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs)	\
+	[ _nr ] = {						\
+		.func = __event_probe__##_template,		\
+		.nrargs = (_nrargs),				\
+		.fields = __event_fields___##_template,		\
+		.desc = &__event_desc___##_name,		\
+	},
+
+static const struct trace_syscall_entry sc_table[] = {
+#include "instrumentation/syscalls/headers/syscalls_integers.h"
+#include "instrumentation/syscalls/headers/syscalls_pointers.h"
+};
+
+#undef TRACE_SYSCALL_TABLE
+#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs)	\
+	[ _nr ] = {						\
+		.func = __event_probe__##compat_##_template,	\
+		.nrargs = (_nrargs),				\
+		.fields = __event_fields___##compat_##_template,\
+		.desc = &__event_desc___##compat_##_name,	\
+	},
+
+/* Create compatibility syscall table */
+const struct trace_syscall_entry compat_sc_table[] = {
+#include "instrumentation/syscalls/headers/compat_syscalls_integers.h"
+#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h"
+};
+
+#undef CREATE_SYSCALL_TABLE
+
+static void syscall_entry_unknown(struct ltt_event *event,
+	struct pt_regs *regs, unsigned int id)
+{
+	unsigned long args[UNKNOWN_SYSCALL_NRARGS];
+
+	syscall_get_arguments(current, regs, 0, UNKNOWN_SYSCALL_NRARGS, args);
+	if (unlikely(is_compat_task()))
+		__event_probe__compat_sys_unknown(event, id, args);
+	else
+		__event_probe__sys_unknown(event, id, args);
+}
+
+void syscall_entry_probe(void *__data, struct pt_regs *regs, long id)
+{
+	struct ltt_channel *chan = __data;
+	struct ltt_event *event, *unknown_event;
+	const struct trace_syscall_entry *table, *entry;
+	size_t table_len;
+
+	if (unlikely(is_compat_task())) {
+		table = compat_sc_table;
+		table_len = ARRAY_SIZE(compat_sc_table);
+		unknown_event = chan->sc_compat_unknown;
+	} else {
+		table = sc_table;
+		table_len = ARRAY_SIZE(sc_table);
+		unknown_event = chan->sc_unknown;
+	}
+	if (unlikely(id >= table_len)) {
+		syscall_entry_unknown(unknown_event, regs, id);
+		return;
+	}
+	if (unlikely(is_compat_task()))
+		event = chan->compat_sc_table[id];
+	else
+		event = chan->sc_table[id];
+	if (unlikely(!event)) {
+		syscall_entry_unknown(unknown_event, regs, id);
+		return;
+	}
+	entry = &table[id];
+	WARN_ON_ONCE(!entry);
+
+	switch (entry->nrargs) {
+	case 0:
+	{
+		void (*fptr)(void *__data) = entry->func;
+
+		fptr(event);
+		break;
+	}
+	case 1:
+	{
+		void (*fptr)(void *__data, unsigned long arg0) = entry->func;
+		unsigned long args[1];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0]);
+		break;
+	}
+	case 2:
+	{
+		void (*fptr)(void *__data,
+			unsigned long arg0,
+			unsigned long arg1) = entry->func;
+		unsigned long args[2];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0], args[1]);
+		break;
+	}
+	case 3:
+	{
+		void (*fptr)(void *__data,
+			unsigned long arg0,
+			unsigned long arg1,
+			unsigned long arg2) = entry->func;
+		unsigned long args[3];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0], args[1], args[2]);
+		break;
+	}
+	case 4:
+	{
+		void (*fptr)(void *__data,
+			unsigned long arg0,
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3) = entry->func;
+		unsigned long args[4];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0], args[1], args[2], args[3]);
+		break;
+	}
+	case 5:
+	{
+		void (*fptr)(void *__data,
+			unsigned long arg0,
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3,
+			unsigned long arg4) = entry->func;
+		unsigned long args[5];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0], args[1], args[2], args[3], args[4]);
+		break;
+	}
+	case 6:
+	{
+		void (*fptr)(void *__data,
+			unsigned long arg0,
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3,
+			unsigned long arg4,
+			unsigned long arg5) = entry->func;
+		unsigned long args[6];
+
+		syscall_get_arguments(current, regs, 0, entry->nrargs, args);
+		fptr(event, args[0], args[1], args[2],
+			args[3], args[4], args[5]);
+		break;
+	}
+	default:
+		break;
+	}
+}
+
+/* noinline to diminish caller stack size */
+static
+int fill_table(const struct trace_syscall_entry *table, size_t table_len,
+	struct ltt_event **chan_table, struct ltt_channel *chan, void *filter)
+{
+	const struct lttng_event_desc *desc;
+	unsigned int i;
+
+	/* Allocate events for each syscall, insert into table */
+	for (i = 0; i < table_len; i++) {
+		struct lttng_kernel_event ev;
+		desc = table[i].desc;
+
+		if (!desc) {
+			/* Unknown syscall */
+			continue;
+		}
+		/*
+		 * Skip those already populated by previous failed
+		 * register for this channel.
+		 */
+		if (chan_table[i])
+			continue;
+		memset(&ev, 0, sizeof(ev));
+		strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
+		ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		ev.instrumentation = LTTNG_KERNEL_NOOP;
+		chan_table[i] = ltt_event_create(chan, &ev, filter,
+						desc);
+		if (!chan_table[i]) {
+			/*
+			 * If something goes wrong in event registration
+			 * after the first one, we have no choice but to
+			 * leave the previous events in there, until
+			 * deleted by session teardown.
+			 */
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+int lttng_syscalls_register(struct ltt_channel *chan, void *filter)
+{
+	struct lttng_kernel_event ev;
+	int ret;
+
+	wrapper_vmalloc_sync_all();
+
+	if (!chan->sc_table) {
+		/* create syscall table mapping syscall to events */
+		chan->sc_table = kzalloc(sizeof(struct ltt_event *)
+					* ARRAY_SIZE(sc_table), GFP_KERNEL);
+		if (!chan->sc_table)
+			return -ENOMEM;
+	}
+
+#ifdef CONFIG_COMPAT
+	if (!chan->compat_sc_table) {
+		/* create syscall table mapping compat syscall to events */
+		chan->compat_sc_table = kzalloc(sizeof(struct ltt_event *)
+					* ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
+		if (!chan->compat_sc_table)
+			return -ENOMEM;
+	}
+#endif
+	if (!chan->sc_unknown) {
+		const struct lttng_event_desc *desc =
+			&__event_desc___sys_unknown;
+
+		memset(&ev, 0, sizeof(ev));
+		strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
+		ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		ev.instrumentation = LTTNG_KERNEL_NOOP;
+		chan->sc_unknown = ltt_event_create(chan, &ev, filter,
+						    desc);
+		if (!chan->sc_unknown) {
+			return -EINVAL;
+		}
+	}
+
+	if (!chan->sc_compat_unknown) {
+		const struct lttng_event_desc *desc =
+			&__event_desc___compat_sys_unknown;
+
+		memset(&ev, 0, sizeof(ev));
+		strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
+		ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		ev.instrumentation = LTTNG_KERNEL_NOOP;
+		chan->sc_compat_unknown = ltt_event_create(chan, &ev, filter,
+							   desc);
+		if (!chan->sc_compat_unknown) {
+			return -EINVAL;
+		}
+	}
+
+	if (!chan->sc_exit) {
+		const struct lttng_event_desc *desc =
+			&__event_desc___exit_syscall;
+
+		memset(&ev, 0, sizeof(ev));
+		strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN);
+		ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0';
+		ev.instrumentation = LTTNG_KERNEL_NOOP;
+		chan->sc_exit = ltt_event_create(chan, &ev, filter,
+						 desc);
+		if (!chan->sc_exit) {
+			return -EINVAL;
+		}
+	}
+
+	ret = fill_table(sc_table, ARRAY_SIZE(sc_table),
+			chan->sc_table, chan, filter);
+	if (ret)
+		return ret;
+#ifdef CONFIG_COMPAT
+	ret = fill_table(compat_sc_table, ARRAY_SIZE(compat_sc_table),
+			chan->compat_sc_table, chan, filter);
+	if (ret)
+		return ret;
+#endif
+	ret = tracepoint_probe_register("sys_enter",
+			(void *) syscall_entry_probe, chan);
+	if (ret)
+		return ret;
+	/*
+	 * We change the name of sys_exit tracepoint due to namespace
+	 * conflict with sys_exit syscall entry.
+	 */
+	ret = tracepoint_probe_register("sys_exit",
+			(void *) __event_probe__exit_syscall,
+			chan->sc_exit);
+	if (ret) {
+		WARN_ON_ONCE(tracepoint_probe_unregister("sys_enter",
+			(void *) syscall_entry_probe, chan));
+	}
+	return ret;
+}
+
+/*
+ * Only called at session destruction.
+ */
+int lttng_syscalls_unregister(struct ltt_channel *chan)
+{
+	int ret;
+
+	if (!chan->sc_table)
+		return 0;
+	ret = tracepoint_probe_unregister("sys_exit",
+			(void *) __event_probe__exit_syscall,
+			chan->sc_exit);
+	if (ret)
+		return ret;
+	ret = tracepoint_probe_unregister("sys_enter",
+			(void *) syscall_entry_probe, chan);
+	if (ret)
+		return ret;
+	/* ltt_event destroy will be performed by ltt_session_destroy() */
+	kfree(chan->sc_table);
+#ifdef CONFIG_COMPAT
+	kfree(chan->compat_sc_table);
+#endif
+	return 0;
+}
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 16/19] lttng: probe callbacks
  2011-11-26 15:03                             ` [lttng-dev] [PATCH 15/19] lttng: add system call instrumentation probe Mathieu Desnoyers
@ 2011-11-26 15:03                               ` Mathieu Desnoyers
  2011-11-26 15:03                                 ` [lttng-dev] [PATCH 17/19] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Implement the LTTng probe callbacks. One notable file here is
lttng-events.h, which is the core implementation of the LTTng
TRACE_EVENT macros for generation of probes and tracepoint decription
from the TRACE_EVENT declarations.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/probes/Makefile             |   37 ++
 drivers/staging/lttng/probes/define_trace.h       |  132 ++++
 drivers/staging/lttng/probes/lttng-events-reset.h |   84 +++
 drivers/staging/lttng/probes/lttng-events.h       |  703 +++++++++++++++++++++
 drivers/staging/lttng/probes/lttng-ftrace.c       |  188 ++++++
 drivers/staging/lttng/probes/lttng-kprobes.c      |  164 +++++
 drivers/staging/lttng/probes/lttng-kretprobes.c   |  277 ++++++++
 drivers/staging/lttng/probes/lttng-probe-block.c  |   31 +
 drivers/staging/lttng/probes/lttng-probe-irq.c    |   31 +
 drivers/staging/lttng/probes/lttng-probe-kvm.c    |   31 +
 drivers/staging/lttng/probes/lttng-probe-lttng.c  |   24 +
 drivers/staging/lttng/probes/lttng-probe-sched.c  |   30 +
 drivers/staging/lttng/probes/lttng-type-list.h    |   21 +
 drivers/staging/lttng/probes/lttng-types.c        |   49 ++
 drivers/staging/lttng/probes/lttng-types.h        |   72 +++
 drivers/staging/lttng/probes/lttng.h              |   15 +
 16 files changed, 1889 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/probes/Makefile
 create mode 100644 drivers/staging/lttng/probes/define_trace.h
 create mode 100644 drivers/staging/lttng/probes/lttng-events-reset.h
 create mode 100644 drivers/staging/lttng/probes/lttng-events.h
 create mode 100644 drivers/staging/lttng/probes/lttng-ftrace.c
 create mode 100644 drivers/staging/lttng/probes/lttng-kprobes.c
 create mode 100644 drivers/staging/lttng/probes/lttng-kretprobes.c
 create mode 100644 drivers/staging/lttng/probes/lttng-probe-block.c
 create mode 100644 drivers/staging/lttng/probes/lttng-probe-irq.c
 create mode 100644 drivers/staging/lttng/probes/lttng-probe-kvm.c
 create mode 100644 drivers/staging/lttng/probes/lttng-probe-lttng.c
 create mode 100644 drivers/staging/lttng/probes/lttng-probe-sched.c
 create mode 100644 drivers/staging/lttng/probes/lttng-type-list.h
 create mode 100644 drivers/staging/lttng/probes/lttng-types.c
 create mode 100644 drivers/staging/lttng/probes/lttng-types.h
 create mode 100644 drivers/staging/lttng/probes/lttng.h

diff --git a/drivers/staging/lttng/probes/Makefile b/drivers/staging/lttng/probes/Makefile
new file mode 100644
index 0000000..bdc1179
--- /dev/null
+++ b/drivers/staging/lttng/probes/Makefile
@@ -0,0 +1,37 @@
+#
+# Makefile for the LTT probes.
+#
+
+ccflags-y += -I$(PWD)/probes
+obj-m += lttng-types.o
+
+obj-m += lttng-probe-lttng.o
+
+obj-m += lttng-probe-sched.o
+obj-m += lttng-probe-irq.o
+
+ifneq ($(CONFIG_KVM),)
+obj-m += lttng-probe-kvm.o
+endif
+
+ifneq ($(CONFIG_BLOCK),)
+ifneq ($(CONFIG_EVENT_TRACING),)	# need blk_cmd_buf_len
+obj-m +=  $(shell \
+	if [ $(VERSION) -ge 3 \
+		-o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \
+		echo "lttng-probe-block.o" ; fi;)
+endif
+endif
+
+ifneq ($(CONFIG_KPROBES),)
+obj-m += lttng-kprobes.o
+endif
+
+
+ifneq ($(CONFIG_KRETPROBES),)
+obj-m += lttng-kretprobes.o
+endif
+
+ifneq ($(CONFIG_DYNAMIC_FTRACE),)
+obj-m += lttng-ftrace.o
+endif
diff --git a/drivers/staging/lttng/probes/define_trace.h b/drivers/staging/lttng/probes/define_trace.h
new file mode 100644
index 0000000..3c9a467
--- /dev/null
+++ b/drivers/staging/lttng/probes/define_trace.h
@@ -0,0 +1,132 @@
+/*
+ * define_trace.h
+ *
+ * Copyright (C) 2009 Steven Rostedt <rostedt at goodmis.org>
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+/*
+ * Trace files that want to automate creationg of all tracepoints defined
+ * in their file should include this file. The following are macros that the
+ * trace file may define:
+ *
+ * TRACE_SYSTEM defines the system the tracepoint is for
+ *
+ * TRACE_INCLUDE_FILE if the file name is something other than TRACE_SYSTEM.h
+ *     This macro may be defined to tell define_trace.h what file to include.
+ *     Note, leave off the ".h".
+ *
+ * TRACE_INCLUDE_PATH if the path is something other than core kernel include/trace
+ *     then this macro can define the path to use. Note, the path is relative to
+ *     define_trace.h, not the file including it. Full path names for out of tree
+ *     modules must be used.
+ */
+
+#ifdef CREATE_TRACE_POINTS
+
+/* Prevent recursion */
+#undef CREATE_TRACE_POINTS
+
+#include <linux/stringify.h>
+/*
+ * module.h includes tracepoints, and because ftrace.h
+ * pulls in module.h:
+ *  trace/ftrace.h -> linux/ftrace_event.h -> linux/perf_event.h ->
+ *  linux/ftrace.h -> linux/module.h
+ * we must include module.h here before we play with any of
+ * the TRACE_EVENT() macros, otherwise the tracepoints included
+ * by module.h may break the build.
+ */
+#include <linux/module.h>
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print)	\
+	DEFINE_TRACE(name)
+
+#undef TRACE_EVENT_CONDITION
+#define TRACE_EVENT_CONDITION(name, proto, args, cond, tstruct, assign, print) \
+	TRACE_EVENT(name,						\
+		PARAMS(proto),						\
+		PARAMS(args),						\
+		PARAMS(tstruct),					\
+		PARAMS(assign),						\
+		PARAMS(print))
+
+#undef TRACE_EVENT_FN
+#define TRACE_EVENT_FN(name, proto, args, tstruct,		\
+		assign, print, reg, unreg)			\
+	DEFINE_TRACE_FN(name, reg, unreg)
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, name, proto, args) \
+	DEFINE_TRACE(name)
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
+	DEFINE_TRACE(name)
+
+#undef DEFINE_EVENT_CONDITION
+#define DEFINE_EVENT_CONDITION(template, name, proto, args, cond) \
+	DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
+#undef DECLARE_TRACE
+#define DECLARE_TRACE(name, proto, args)	\
+	DEFINE_TRACE(name)
+
+#undef TRACE_INCLUDE
+#undef __TRACE_INCLUDE
+
+#ifndef TRACE_INCLUDE_FILE
+# define TRACE_INCLUDE_FILE TRACE_SYSTEM
+# define UNDEF_TRACE_INCLUDE_FILE
+#endif
+
+#ifndef TRACE_INCLUDE_PATH
+# define __TRACE_INCLUDE(system) <trace/events/system.h>
+# define UNDEF_TRACE_INCLUDE_PATH
+#else
+# define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
+#endif
+
+# define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
+
+/* Let the trace headers be reread */
+#define TRACE_HEADER_MULTI_READ
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/* Make all open coded DECLARE_TRACE nops */
+#undef DECLARE_TRACE
+#define DECLARE_TRACE(name, proto, args)
+
+#ifdef LTTNG_PACKAGE_BUILD
+#include "lttng-events.h"
+#endif
+
+#undef TRACE_EVENT
+#undef TRACE_EVENT_FN
+#undef TRACE_EVENT_CONDITION
+#undef DECLARE_EVENT_CLASS
+#undef DEFINE_EVENT
+#undef DEFINE_EVENT_PRINT
+#undef DEFINE_EVENT_CONDITION
+#undef TRACE_HEADER_MULTI_READ
+#undef DECLARE_TRACE
+
+/* Only undef what we defined in this file */
+#ifdef UNDEF_TRACE_INCLUDE_FILE
+# undef TRACE_INCLUDE_FILE
+# undef UNDEF_TRACE_INCLUDE_FILE
+#endif
+
+#ifdef UNDEF_TRACE_INCLUDE_PATH
+# undef TRACE_INCLUDE_PATH
+# undef UNDEF_TRACE_INCLUDE_PATH
+#endif
+
+/* We may be processing more files */
+#define CREATE_TRACE_POINTS
+
+#endif /* CREATE_TRACE_POINTS */
diff --git a/drivers/staging/lttng/probes/lttng-events-reset.h b/drivers/staging/lttng/probes/lttng-events-reset.h
new file mode 100644
index 0000000..c8a1046
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-events-reset.h
@@ -0,0 +1,84 @@
+/*
+ * lttng-events-reset.h
+ *
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+/* Reset macros used within TRACE_EVENT to "nothing" */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)
+
+#undef __dynamic_array_len
+#define __dynamic_array_len(_type, _item, _length)
+
+#undef __string
+#define __string(_item, _src)
+
+#undef tp_assign
+#define tp_assign(dest, src)
+
+#undef tp_memcpy
+#define tp_memcpy(dest, src, len)
+
+#undef tp_memcpy_dyn
+#define tp_memcpy_dyn(dest, src, len)
+
+#undef tp_strcpy
+#define tp_strcpy(dest, src)
+
+#undef __get_str
+#define __get_str(field)
+
+#undef __get_dynamic_array
+#define __get_dynamic_array(field)
+
+#undef __get_dynamic_array_len
+#define __get_dynamic_array_len(field)
+
+#undef TP_PROTO
+#define TP_PROTO(args...)
+
+#undef TP_ARGS
+#define TP_ARGS(args...)
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...)
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...)
+
+#undef __perf_count
+#define __perf_count(args...)
+
+#undef __perf_addr
+#define __perf_addr(args...)
+
+#undef TP_perf_assign
+#define TP_perf_assign(args...)
+
+#undef TP_printk
+#define TP_printk(args...)
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)
+
+#undef DECLARE_EVENT_CLASS_NOARGS
+#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print)
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(_template, _name, _proto, _args)
+
+#undef DEFINE_EVENT_NOARGS
+#define DEFINE_EVENT_NOARGS(_template, _name)
+
+#undef TRACE_EVENT_FLAGS
+#define TRACE_EVENT_FLAGS(name, value)
diff --git a/drivers/staging/lttng/probes/lttng-events.h b/drivers/staging/lttng/probes/lttng-events.h
new file mode 100644
index 0000000..ff6273f
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-events.h
@@ -0,0 +1,703 @@
+/*
+ * lttng-events.h
+ *
+ * Copyright (C) 2009 Steven Rostedt <rostedt at goodmis.org>
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/debugfs.h>
+#include "lttng.h"
+#include "lttng-types.h"
+#include "../wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "../wrapper/ringbuffer/frontend_types.h"
+#include "../ltt-events.h"
+#include "../ltt-tracer-core.h"
+
+/*
+ * Macro declarations used for all stages.
+ */
+
+/*
+ * DECLARE_EVENT_CLASS can be used to add a generic function
+ * handlers for events. That is, if all events have the same
+ * parameters and just have distinct trace points.
+ * Each tracepoint can be defined with DEFINE_EVENT and that
+ * will map the DECLARE_EVENT_CLASS to the tracepoint.
+ *
+ * TRACE_EVENT is a one to one mapping between tracepoint and template.
+ */
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
+	DECLARE_EVENT_CLASS(name,			       \
+			     PARAMS(proto),		       \
+			     PARAMS(args),		       \
+			     PARAMS(tstruct),		       \
+			     PARAMS(assign),		       \
+			     PARAMS(print))		       \
+	DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args))
+
+#undef TRACE_EVENT_NOARGS
+#define TRACE_EVENT_NOARGS(name, tstruct, assign, print)       \
+	DECLARE_EVENT_CLASS_NOARGS(name,		       \
+			     PARAMS(tstruct),		       \
+			     PARAMS(assign),		       \
+			     PARAMS(print))		       \
+	DEFINE_EVENT_NOARGS(name, name)
+
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print)	\
+	DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
+
+/* Callbacks are meaningless to LTTng. */
+#undef TRACE_EVENT_FN
+#define TRACE_EVENT_FN(name, proto, args, tstruct,			\
+		assign, print, reg, unreg)				\
+	TRACE_EVENT(name, PARAMS(proto), PARAMS(args),			\
+		PARAMS(tstruct), PARAMS(assign), PARAMS(print))		\
+
+/*
+ * Stage 1 of the trace events.
+ *
+ * Create dummy trace calls for each events, verifying that the LTTng module
+ * TRACE_EVENT headers match the kernel arguments. Will be optimized out by the
+ * compiler.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#undef TP_PROTO
+#define TP_PROTO(args...) args
+
+#undef TP_ARGS
+#define TP_ARGS(args...) args
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(_template, _name, _proto, _args)			\
+void trace_##_name(_proto);
+
+#undef DEFINE_EVENT_NOARGS
+#define DEFINE_EVENT_NOARGS(_template, _name)				\
+void trace_##_name(void *__data);
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 2 of the trace events.
+ *
+ * Create event field type metadata section.
+ * Each event produce an array of fields.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+/* Named field types must be defined in lttng-types.h */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)		\
+	{							\
+	  .name = #_item,					\
+	  .type = __type_integer(_type, _order, _base, none),	\
+	},
+
+#undef __field
+#define __field(_type, _item)					\
+	__field_full(_type, _item, __BYTE_ORDER, 10)
+
+#undef __field_ext
+#define __field_ext(_type, _item, _filter_type)			\
+	__field(_type, _item)
+
+#undef __field_hex
+#define __field_hex(_type, _item)				\
+	__field_full(_type, _item, __BYTE_ORDER, 16)
+
+#undef __field_network
+#define __field_network(_type, _item)				\
+	__field_full(_type, _item, __BIG_ENDIAN, 10)
+
+#undef __field_network_hex
+#define __field_network_hex(_type, _item)				\
+	__field_full(_type, _item, __BIG_ENDIAN, 16)
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	{							\
+	  .name = #_item,					\
+	  .type =						\
+		{						\
+		  .atype = atype_array,				\
+		  .u.array =					\
+			{					\
+			    .length = _length,			\
+			    .elem_type = __type_integer(_type, _order, _base, _encoding), \
+			},					\
+		},						\
+	},
+
+#undef __array
+#define __array(_type, _item, _length)				\
+	__array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, none)
+
+#undef __array_text
+#define __array_text(_type, _item, _length)			\
+	__array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, UTF8)
+
+#undef __array_hex
+#define __array_hex(_type, _item, _length)			\
+	__array_enc_ext(_type, _item, _length, __BYTE_ORDER, 16, none)
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding) \
+	{							\
+	  .name = #_item,					\
+	  .type =						\
+		{						\
+		  .atype = atype_sequence,			\
+		  .u.sequence =					\
+			{					\
+			    .length_type = __type_integer(u32, __BYTE_ORDER, 10, none), \
+			    .elem_type = __type_integer(_type, _order, _base, _encoding), \
+			},					\
+		},						\
+	},
+
+#undef __dynamic_array
+#define __dynamic_array(_type, _item, _length)			\
+	__dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, none)
+
+#undef __dynamic_array_text
+#define __dynamic_array_text(_type, _item, _length)		\
+	__dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, UTF8)
+
+#undef __dynamic_array_hex
+#define __dynamic_array_hex(_type, _item, _length)		\
+	__dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 16, none)
+
+#undef __string
+#define __string(_item, _src)					\
+	{							\
+	  .name = #_item,					\
+	  .type =						\
+		{						\
+		  .atype = atype_string,			\
+		  .u.basic.string.encoding = lttng_encode_UTF8,	\
+		},						\
+	},
+
+#undef __string_from_user
+#define __string_from_user(_item, _src)				\
+	__string(_item, _src)
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args	/* Only one used in this phase */
+
+#undef DECLARE_EVENT_CLASS_NOARGS
+#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \
+	static const struct lttng_event_field __event_fields___##_name[] = { \
+		_tstruct						     \
+	};
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \
+	DECLARE_EVENT_CLASS_NOARGS(_name, PARAMS(_tstruct), PARAMS(_assign), \
+			PARAMS(_print))
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 3 of the trace events.
+ *
+ * Create probe callback prototypes.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#undef TP_PROTO
+#define TP_PROTO(args...) args
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
+static void __event_probe__##_name(void *__data, _proto);
+
+#undef DECLARE_EVENT_CLASS_NOARGS
+#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print)	      \
+static void __event_probe__##_name(void *__data);
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 3.9 of the trace events.
+ *
+ * Create event descriptions.
+ */
+
+/* Named field types must be defined in lttng-types.h */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#ifndef TP_PROBE_CB
+#define TP_PROBE_CB(_template)	&__event_probe__##_template
+#endif
+
+#undef DEFINE_EVENT_NOARGS
+#define DEFINE_EVENT_NOARGS(_template, _name)				\
+static const struct lttng_event_desc __event_desc___##_name = {		\
+	.fields = __event_fields___##_template,		     		\
+	.name = #_name,					     		\
+	.probe_callback = (void *) TP_PROBE_CB(_template),   		\
+	.nr_fields = ARRAY_SIZE(__event_fields___##_template),		\
+	.owner = THIS_MODULE,				     		\
+};
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(_template, _name, _proto, _args)			\
+	DEFINE_EVENT_NOARGS(_template, _name)
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+
+/*
+ * Stage 4 of the trace events.
+ *
+ * Create an array of event description pointers.
+ */
+
+/* Named field types must be defined in lttng-types.h */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#undef DEFINE_EVENT_NOARGS
+#define DEFINE_EVENT_NOARGS(_template, _name)				       \
+		&__event_desc___##_name,
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(_template, _name, _proto, _args)			       \
+	DEFINE_EVENT_NOARGS(_template, _name)
+
+#define TP_ID1(_token, _system)	_token##_system
+#define TP_ID(_token, _system)	TP_ID1(_token, _system)
+
+static const struct lttng_event_desc *TP_ID(__event_desc___, TRACE_SYSTEM)[] = {
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+};
+
+#undef TP_ID1
+#undef TP_ID
+
+
+/*
+ * Stage 5 of the trace events.
+ *
+ * Create a toplevel descriptor for the whole probe.
+ */
+
+#define TP_ID1(_token, _system)	_token##_system
+#define TP_ID(_token, _system)	TP_ID1(_token, _system)
+
+/* non-const because list head will be modified when registered. */
+static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = {
+	.event_desc = TP_ID(__event_desc___, TRACE_SYSTEM),
+	.nr_events = ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)),
+};
+
+#undef TP_ID1
+#undef TP_ID
+
+/*
+ * Stage 6 of the trace events.
+ *
+ * Create static inline function that calculates event size.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+/* Named field types must be defined in lttng-types.h */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)			       \
+	__event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
+	__event_len += sizeof(_type);
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)       \
+	__event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
+	__event_len += sizeof(_type) * (_length);
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	__event_len += lib_ring_buffer_align(__event_len, ltt_alignof(u32));   \
+	__event_len += sizeof(u32);					       \
+	__event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
+	__dynamic_len[__dynamic_len_idx] = (_length);			       \
+	__event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx];       \
+	__dynamic_len_idx++;
+
+#undef __string
+#define __string(_item, _src)						       \
+	__event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1;
+
+/*
+ * strlen_user includes \0. If returns 0, it faulted, so we set size to
+ * 1 (\0 only).
+ */
+#undef __string_from_user
+#define __string_from_user(_item, _src)					       \
+	__event_len += __dynamic_len[__dynamic_len_idx++] =		       \
+		min_t(size_t, strlen_user(_src), 1);
+
+#undef TP_PROTO
+#define TP_PROTO(args...) args
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
+static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \
+{									      \
+	size_t __event_len = 0;						      \
+	unsigned int __dynamic_len_idx = 0;				      \
+									      \
+	if (0)								      \
+		(void) __dynamic_len_idx;	/* don't warn if unused */    \
+	_tstruct							      \
+	return __event_len;						      \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 7 of the trace events.
+ *
+ * Create static inline function that calculates event payload alignment.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+/* Named field types must be defined in lttng-types.h */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)			  \
+	__event_align = max_t(size_t, __event_align, ltt_alignof(_type));
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)  \
+	__event_align = max_t(size_t, __event_align, ltt_alignof(_type));
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	__event_align = max_t(size_t, __event_align, ltt_alignof(u32));	  \
+	__event_align = max_t(size_t, __event_align, ltt_alignof(_type));
+
+#undef __string
+#define __string(_item, _src)
+
+#undef __string_from_user
+#define __string_from_user(_item, _src)
+
+#undef TP_PROTO
+#define TP_PROTO(args...) args
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
+static inline size_t __event_get_align__##_name(_proto)			      \
+{									      \
+	size_t __event_align = 1;					      \
+	_tstruct							      \
+	return __event_align;						      \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+
+/*
+ * Stage 8 of the trace events.
+ *
+ * Create structure declaration that allows the "assign" macros to access the
+ * field types.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+/* Named field types must be defined in lttng-types.h */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)	_type	_item;
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)  \
+	_type	_item;
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	_type	_item;
+
+#undef __string
+#define __string(_item, _src)			char _item;
+
+#undef __string_from_user
+#define __string_from_user(_item, _src)		\
+	__string(_item, _src)
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
+struct __event_typemap__##_name {					      \
+	_tstruct							      \
+};
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+
+/*
+ * Stage 9 of the trace events.
+ *
+ * Create the probe function : call even size calculation and write event data
+ * into the buffer.
+ *
+ * We use both the field and assignment macros to write the fields in the order
+ * defined in the field declaration. The field declarations control the
+ * execution order, jumping to the appropriate assignment block.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#undef __field_full
+#define __field_full(_type, _item, _order, _base)			\
+	goto __assign_##_item;						\
+__end_field_##_item:
+
+#undef __array_enc_ext
+#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	goto __assign_##_item;						\
+__end_field_##_item:
+
+#undef __dynamic_array_enc_ext
+#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\
+	goto __assign_##_item##_1;					\
+__end_field_##_item##_1:						\
+	goto __assign_##_item##_2;					\
+__end_field_##_item##_2:
+
+#undef __string
+#define __string(_item, _src)						\
+	goto __assign_##_item;						\
+__end_field_##_item:
+
+#undef __string_from_user
+#define __string_from_user(_item, _src)					\
+	__string(_item, _src)
+
+/*
+ * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to
+ * strcpy().
+ */
+#undef tp_assign
+#define tp_assign(dest, src)						\
+__assign_##dest:							\
+	{								\
+		__typeof__(__typemap.dest) __tmp = (src);		\
+		lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__tmp));	\
+		__chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
+	}								\
+	goto __end_field_##dest;
+
+#undef tp_memcpy
+#define tp_memcpy(dest, src, len)					\
+__assign_##dest:							\
+	if (0)								\
+		(void) __typemap.dest;					\
+	lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));	\
+	__chan->ops->event_write(&__ctx, src, len);			\
+	goto __end_field_##dest;
+
+#undef tp_memcpy_dyn
+#define tp_memcpy_dyn(dest, src)					\
+__assign_##dest##_1:							\
+	{								\
+		u32 __tmpl = __dynamic_len[__dynamic_len_idx];		\
+		lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(u32));	\
+		__chan->ops->event_write(&__ctx, &__tmpl, sizeof(u32));	\
+	}								\
+	goto __end_field_##dest##_1;					\
+__assign_##dest##_2:							\
+	lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));	\
+	__chan->ops->event_write(&__ctx, src,				\
+		sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\
+	goto __end_field_##dest##_2;
+
+#undef tp_memcpy_from_user
+#define tp_memcpy_from_user(dest, src, len)				\
+	__assign_##dest:						\
+	if (0)								\
+		(void) __typemap.dest;					\
+	lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));	\
+	__chan->ops->event_write_from_user(&__ctx, src, len);		\
+	goto __end_field_##dest;
+
+/*
+ * The string length including the final \0.
+ */
+#undef tp_copy_string_from_user
+#define tp_copy_string_from_user(dest, src)				\
+	__assign_##dest:						\
+	{								\
+		size_t __ustrlen;					\
+									\
+		if (0)							\
+			(void) __typemap.dest;				\
+		lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));\
+		__ustrlen = __get_dynamic_array_len(dest);		\
+		if (likely(__ustrlen) > 1) {				\
+			__chan->ops->event_write_from_user(&__ctx, src,	\
+				__ustrlen - 1);				\
+		}							\
+		__chan->ops->event_memset(&__ctx, 0, 1);		\
+	}								\
+	goto __end_field_##dest;
+#undef tp_strcpy
+#define tp_strcpy(dest, src)						\
+	tp_memcpy(dest, src, __get_dynamic_array_len(dest))
+
+/* Named field types must be defined in lttng-types.h */
+
+#undef __get_str
+#define __get_str(field)		field
+
+#undef __get_dynamic_array
+#define __get_dynamic_array(field)	field
+
+/* Beware: this get len actually consumes the len value */
+#undef __get_dynamic_array_len
+#define __get_dynamic_array_len(field)	__dynamic_len[__dynamic_len_idx++]
+
+#undef TP_PROTO
+#define TP_PROTO(args...) args
+
+#undef TP_ARGS
+#define TP_ARGS(args...) args
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...) args
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print)  \
+static void __event_probe__##_name(void *__data, _proto)		      \
+{									      \
+	struct ltt_event *__event = __data;				      \
+	struct ltt_channel *__chan = __event->chan;			      \
+	struct lib_ring_buffer_ctx __ctx;				      \
+	size_t __event_len, __event_align;				      \
+	size_t __dynamic_len_idx = 0;					      \
+	size_t __dynamic_len[ARRAY_SIZE(__event_fields___##_name)];	      \
+	struct __event_typemap__##_name __typemap;			      \
+	int __ret;							      \
+									      \
+	if (0)								      \
+		(void) __dynamic_len_idx;	/* don't warn if unused */    \
+	if (unlikely(!ACCESS_ONCE(__chan->session->active)))		      \
+		return;							      \
+	if (unlikely(!ACCESS_ONCE(__chan->enabled)))			      \
+		return;							      \
+	if (unlikely(!ACCESS_ONCE(__event->enabled)))			      \
+		return;							      \
+	__event_len = __event_get_size__##_name(__dynamic_len, _args);	      \
+	__event_align = __event_get_align__##_name(_args);		      \
+	lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+				 __event_align, -1);			      \
+	__ret = __chan->ops->event_reserve(&__ctx, __event->id);	      \
+	if (__ret < 0)							      \
+		return;							      \
+	/* Control code (field ordering) */				      \
+	_tstruct							      \
+	__chan->ops->event_commit(&__ctx);				      \
+	return;								      \
+	/* Copy code, steered by control code */			      \
+	_assign								      \
+}
+
+#undef DECLARE_EVENT_CLASS_NOARGS
+#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print)	      \
+static void __event_probe__##_name(void *__data)			      \
+{									      \
+	struct ltt_event *__event = __data;				      \
+	struct ltt_channel *__chan = __event->chan;			      \
+	struct lib_ring_buffer_ctx __ctx;				      \
+	size_t __event_len, __event_align;				      \
+	int __ret;							      \
+									      \
+	if (unlikely(!ACCESS_ONCE(__chan->session->active)))		      \
+		return;							      \
+	if (unlikely(!ACCESS_ONCE(__chan->enabled)))			      \
+		return;							      \
+	if (unlikely(!ACCESS_ONCE(__event->enabled)))			      \
+		return;							      \
+	__event_len = 0;						      \
+	__event_align = 1;						      \
+	lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len,  \
+				 __event_align, -1);			      \
+	__ret = __chan->ops->event_reserve(&__ctx, __event->id);	      \
+	if (__ret < 0)							      \
+		return;							      \
+	/* Control code (field ordering) */				      \
+	_tstruct							      \
+	__chan->ops->event_commit(&__ctx);				      \
+	return;								      \
+	/* Copy code, steered by control code */			      \
+	_assign								      \
+}
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+/*
+ * Stage 10 of the trace events.
+ *
+ * Register/unregister probes at module load/unload.
+ */
+
+#include "lttng-events-reset.h"	/* Reset all macros within TRACE_EVENT */
+
+#define TP_ID1(_token, _system)	_token##_system
+#define TP_ID(_token, _system)	TP_ID1(_token, _system)
+#define module_init_eval1(_token, _system)	module_init(_token##_system)
+#define module_init_eval(_token, _system)	module_init_eval1(_token, _system)
+#define module_exit_eval1(_token, _system)	module_exit(_token##_system)
+#define module_exit_eval(_token, _system)	module_exit_eval1(_token, _system)
+
+#ifndef TP_MODULE_OVERRIDE
+static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void)
+{
+	wrapper_vmalloc_sync_all();
+	return ltt_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM));
+}
+
+module_init_eval(__lttng_events_init__, TRACE_SYSTEM);
+
+static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void)
+{
+	ltt_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM));
+}
+
+module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM);
+#endif
+
+#undef module_init_eval
+#undef module_exit_eval
+#undef TP_ID1
+#undef TP_ID
+
+#undef TP_PROTO
+#undef TP_ARGS
+#undef TRACE_EVENT_FLAGS
diff --git a/drivers/staging/lttng/probes/lttng-ftrace.c b/drivers/staging/lttng/probes/lttng-ftrace.c
new file mode 100644
index 0000000..1aa7183
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-ftrace.c
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng function tracer integration module.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+/*
+ * Ftrace function tracer does not seem to provide synchronization between probe
+ * teardown and callback execution. Therefore, we make this module permanently
+ * loaded (unloadable).
+ *
+ * TODO: Move to register_ftrace_function() (which is exported for
+ * modules) for Linux >= 3.0. It is faster (only enables the selected
+ * functions), and will stay there.
+ */
+
+#include <linux/module.h>
+#include <linux/ftrace.h>
+#include <linux/slab.h>
+#include "../ltt-events.h"
+#include "../wrapper/ringbuffer/frontend_types.h"
+#include "../wrapper/ftrace.h"
+#include "../wrapper/vmalloc.h"
+#include "../ltt-tracer.h"
+
+static
+void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data)
+{
+	struct ltt_event *event = *data;
+	struct ltt_channel *chan = event->chan;
+	struct lib_ring_buffer_ctx ctx;
+	struct {
+		unsigned long ip;
+		unsigned long parent_ip;
+	} payload;
+	int ret;
+
+	if (unlikely(!ACCESS_ONCE(chan->session->active)))
+		return;
+	if (unlikely(!ACCESS_ONCE(chan->enabled)))
+		return;
+	if (unlikely(!ACCESS_ONCE(event->enabled)))
+		return;
+
+	lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
+				 sizeof(payload), ltt_alignof(payload), -1);
+	ret = chan->ops->event_reserve(&ctx, event->id);
+	if (ret < 0)
+		return;
+	payload.ip = ip;
+	payload.parent_ip = parent_ip;
+	lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload));
+	chan->ops->event_write(&ctx, &payload, sizeof(payload));
+	chan->ops->event_commit(&ctx);
+	return;
+}
+
+/*
+ * Create event description
+ */
+static
+int lttng_create_ftrace_event(const char *name, struct ltt_event *event)
+{
+	struct lttng_event_field *fields;
+	struct lttng_event_desc *desc;
+	int ret;
+
+	desc = kzalloc(sizeof(*event->desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+	desc->name = kstrdup(name, GFP_KERNEL);
+	if (!desc->name) {
+		ret = -ENOMEM;
+		goto error_str;
+	}
+	desc->nr_fields = 2;
+	desc->fields = fields =
+		kzalloc(2 * sizeof(struct lttng_event_field), GFP_KERNEL);
+	if (!desc->fields) {
+		ret = -ENOMEM;
+		goto error_fields;
+	}
+	fields[0].name = "ip";
+	fields[0].type.atype = atype_integer;
+	fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
+	fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT;
+	fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long);
+	fields[0].type.u.basic.integer.reverse_byte_order = 0;
+	fields[0].type.u.basic.integer.base = 16;
+	fields[0].type.u.basic.integer.encoding = lttng_encode_none;
+
+	fields[1].name = "parent_ip";
+	fields[1].type.atype = atype_integer;
+	fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
+	fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT;
+	fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long);
+	fields[1].type.u.basic.integer.reverse_byte_order = 0;
+	fields[1].type.u.basic.integer.base = 16;
+	fields[1].type.u.basic.integer.encoding = lttng_encode_none;
+
+	desc->owner = THIS_MODULE;
+	event->desc = desc;
+
+	return 0;
+
+error_fields:
+	kfree(desc->name);
+error_str:
+	kfree(desc);
+	return ret;
+}
+
+static
+struct ftrace_probe_ops lttng_ftrace_ops = {
+	.func = lttng_ftrace_handler,
+};
+
+int lttng_ftrace_register(const char *name,
+			  const char *symbol_name,
+			  struct ltt_event *event)
+{
+	int ret;
+
+	ret = lttng_create_ftrace_event(name, event);
+	if (ret)
+		goto error;
+
+	event->u.ftrace.symbol_name = kstrdup(symbol_name, GFP_KERNEL);
+	if (!event->u.ftrace.symbol_name)
+		goto name_error;
+
+	/* Ensure the memory we just allocated don't trigger page faults */
+	wrapper_vmalloc_sync_all();
+
+	ret = wrapper_register_ftrace_function_probe(event->u.ftrace.symbol_name,
+			&lttng_ftrace_ops, event);
+	if (ret < 0)
+		goto register_error;
+	return 0;
+
+register_error:
+	kfree(event->u.ftrace.symbol_name);
+name_error:
+	kfree(event->desc->name);
+	kfree(event->desc);
+error:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lttng_ftrace_register);
+
+void lttng_ftrace_unregister(struct ltt_event *event)
+{
+	wrapper_unregister_ftrace_function_probe(event->u.ftrace.symbol_name,
+			&lttng_ftrace_ops, event);
+}
+EXPORT_SYMBOL_GPL(lttng_ftrace_unregister);
+
+void lttng_ftrace_destroy_private(struct ltt_event *event)
+{
+	kfree(event->u.ftrace.symbol_name);
+	kfree(event->desc->fields);
+	kfree(event->desc->name);
+	kfree(event->desc);
+}
+EXPORT_SYMBOL_GPL(lttng_ftrace_destroy_private);
+
+int lttng_ftrace_init(void)
+{
+	wrapper_vmalloc_sync_all();
+	return 0;
+}
+module_init(lttng_ftrace_init)
+
+/*
+ * Ftrace takes care of waiting for a grace period (RCU sched) at probe
+ * unregistration, and disables preemption around probe call.
+ */
+void lttng_ftrace_exit(void)
+{
+}
+module_exit(lttng_ftrace_exit)
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Ftrace Support");
diff --git a/drivers/staging/lttng/probes/lttng-kprobes.c b/drivers/staging/lttng/probes/lttng-kprobes.c
new file mode 100644
index 0000000..784002a
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-kprobes.c
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng kprobes integration module.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/slab.h>
+#include "../ltt-events.h"
+#include "../wrapper/ringbuffer/frontend_types.h"
+#include "../wrapper/vmalloc.h"
+#include "../ltt-tracer.h"
+
+static
+int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs)
+{
+	struct ltt_event *event =
+		container_of(p, struct ltt_event, u.kprobe.kp);
+	struct ltt_channel *chan = event->chan;
+	struct lib_ring_buffer_ctx ctx;
+	int ret;
+	unsigned long data = (unsigned long) p->addr;
+
+	if (unlikely(!ACCESS_ONCE(chan->session->active)))
+		return 0;
+	if (unlikely(!ACCESS_ONCE(chan->enabled)))
+		return 0;
+	if (unlikely(!ACCESS_ONCE(event->enabled)))
+		return 0;
+
+	lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
+				 ltt_alignof(data), -1);
+	ret = chan->ops->event_reserve(&ctx, event->id);
+	if (ret < 0)
+		return 0;
+	lib_ring_buffer_align_ctx(&ctx, ltt_alignof(data));
+	chan->ops->event_write(&ctx, &data, sizeof(data));
+	chan->ops->event_commit(&ctx);
+	return 0;
+}
+
+/*
+ * Create event description
+ */
+static
+int lttng_create_kprobe_event(const char *name, struct ltt_event *event)
+{
+	struct lttng_event_field *field;
+	struct lttng_event_desc *desc;
+	int ret;
+
+	desc = kzalloc(sizeof(*event->desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+	desc->name = kstrdup(name, GFP_KERNEL);
+	if (!desc->name) {
+		ret = -ENOMEM;
+		goto error_str;
+	}
+	desc->nr_fields = 1;
+	desc->fields = field =
+		kzalloc(1 * sizeof(struct lttng_event_field), GFP_KERNEL);
+	if (!field) {
+		ret = -ENOMEM;
+		goto error_field;
+	}
+	field->name = "ip";
+	field->type.atype = atype_integer;
+	field->type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
+	field->type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT;
+	field->type.u.basic.integer.signedness = is_signed_type(unsigned long);
+	field->type.u.basic.integer.reverse_byte_order = 0;
+	field->type.u.basic.integer.base = 16;
+	field->type.u.basic.integer.encoding = lttng_encode_none;
+	desc->owner = THIS_MODULE;
+	event->desc = desc;
+
+	return 0;
+
+error_field:
+	kfree(desc->name);
+error_str:
+	kfree(desc);
+	return ret;
+}
+
+int lttng_kprobes_register(const char *name,
+			   const char *symbol_name,
+			   uint64_t offset,
+			   uint64_t addr,
+			   struct ltt_event *event)
+{
+	int ret;
+
+	/* Kprobes expects a NULL symbol name if unused */
+	if (symbol_name[0] == '\0')
+		symbol_name = NULL;
+
+	ret = lttng_create_kprobe_event(name, event);
+	if (ret)
+		goto error;
+	memset(&event->u.kprobe.kp, 0, sizeof(event->u.kprobe.kp));
+	event->u.kprobe.kp.pre_handler = lttng_kprobes_handler_pre;
+	if (symbol_name) {
+		event->u.kprobe.symbol_name =
+			kzalloc(LTTNG_SYM_NAME_LEN * sizeof(char),
+				GFP_KERNEL);
+		if (!event->u.kprobe.symbol_name) {
+			ret = -ENOMEM;
+			goto name_error;
+		}
+		memcpy(event->u.kprobe.symbol_name, symbol_name,
+		       LTTNG_SYM_NAME_LEN * sizeof(char));
+		event->u.kprobe.kp.symbol_name =
+			event->u.kprobe.symbol_name;
+	}
+	event->u.kprobe.kp.offset = offset;
+	event->u.kprobe.kp.addr = (void *) (unsigned long) addr;
+
+	/*
+	 * Ensure the memory we just allocated don't trigger page faults.
+	 * Well.. kprobes itself puts the page fault handler on the blacklist,
+	 * but we can never be too careful.
+	 */
+	wrapper_vmalloc_sync_all();
+
+	ret = register_kprobe(&event->u.kprobe.kp);
+	if (ret)
+		goto register_error;
+	return 0;
+
+register_error:
+	kfree(event->u.kprobe.symbol_name);
+name_error:
+	kfree(event->desc->fields);
+	kfree(event->desc->name);
+	kfree(event->desc);
+error:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lttng_kprobes_register);
+
+void lttng_kprobes_unregister(struct ltt_event *event)
+{
+	unregister_kprobe(&event->u.kprobe.kp);
+}
+EXPORT_SYMBOL_GPL(lttng_kprobes_unregister);
+
+void lttng_kprobes_destroy_private(struct ltt_event *event)
+{
+	kfree(event->u.kprobe.symbol_name);
+	kfree(event->desc->fields);
+	kfree(event->desc->name);
+	kfree(event->desc);
+}
+EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_private);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Kprobes Support");
diff --git a/drivers/staging/lttng/probes/lttng-kretprobes.c b/drivers/staging/lttng/probes/lttng-kretprobes.c
new file mode 100644
index 0000000..6b29101
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-kretprobes.c
@@ -0,0 +1,277 @@
+/*
+ * (C) Copyright	2009-2011 -
+ * 		Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng kretprobes integration module.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/slab.h>
+#include <linux/kref.h>
+#include "../ltt-events.h"
+#include "../wrapper/ringbuffer/frontend_types.h"
+#include "../wrapper/vmalloc.h"
+#include "../ltt-tracer.h"
+
+enum lttng_kretprobe_type {
+	EVENT_ENTRY = 0,
+	EVENT_RETURN = 1,
+};
+
+struct lttng_krp {
+	struct kretprobe krp;
+	struct ltt_event *event[2];	/* ENTRY and RETURN */
+	struct kref kref_register;
+	struct kref kref_alloc;
+};
+
+static
+int _lttng_kretprobes_handler(struct kretprobe_instance *krpi,
+			      struct pt_regs *regs,
+			      enum lttng_kretprobe_type type)
+{
+	struct lttng_krp *lttng_krp =
+		container_of(krpi->rp, struct lttng_krp, krp);
+	struct ltt_event *event =
+		lttng_krp->event[type];
+	struct ltt_channel *chan = event->chan;
+	struct lib_ring_buffer_ctx ctx;
+	int ret;
+	struct {
+		unsigned long ip;
+		unsigned long parent_ip;
+	} payload;
+
+	if (unlikely(!ACCESS_ONCE(chan->session->active)))
+		return 0;
+	if (unlikely(!ACCESS_ONCE(chan->enabled)))
+		return 0;
+	if (unlikely(!ACCESS_ONCE(event->enabled)))
+		return 0;
+
+	payload.ip = (unsigned long) krpi->rp->kp.addr;
+	payload.parent_ip = (unsigned long) krpi->ret_addr;
+
+	lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(payload),
+				 ltt_alignof(payload), -1);
+	ret = chan->ops->event_reserve(&ctx, event->id);
+	if (ret < 0)
+		return 0;
+	lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload));
+	chan->ops->event_write(&ctx, &payload, sizeof(payload));
+	chan->ops->event_commit(&ctx);
+	return 0;
+}
+
+static
+int lttng_kretprobes_handler_entry(struct kretprobe_instance *krpi,
+				   struct pt_regs *regs)
+{
+	return _lttng_kretprobes_handler(krpi, regs, EVENT_ENTRY);
+}
+
+static
+int lttng_kretprobes_handler_return(struct kretprobe_instance *krpi,
+				    struct pt_regs *regs)
+{
+	return _lttng_kretprobes_handler(krpi, regs, EVENT_RETURN);
+}
+
+/*
+ * Create event description
+ */
+static
+int lttng_create_kprobe_event(const char *name, struct ltt_event *event,
+			      enum lttng_kretprobe_type type)
+{
+	struct lttng_event_field *fields;
+	struct lttng_event_desc *desc;
+	int ret;
+	char *alloc_name;
+	size_t name_len;
+	const char *suffix = NULL;
+
+	desc = kzalloc(sizeof(*event->desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+	name_len = strlen(name);
+	switch (type) {
+	case EVENT_ENTRY:
+		suffix = "_entry";
+		break;
+	case EVENT_RETURN:
+		suffix = "_return";
+		break;
+	}
+	name_len += strlen(suffix);
+	alloc_name = kmalloc(name_len + 1, GFP_KERNEL);
+	if (!alloc_name) {
+		ret = -ENOMEM;
+		goto error_str;
+	}
+	strcpy(alloc_name, name);
+	strcat(alloc_name, suffix);
+	desc->name = alloc_name;
+	desc->nr_fields = 2;
+	desc->fields = fields =
+		kzalloc(2 * sizeof(struct lttng_event_field), GFP_KERNEL);
+	if (!desc->fields) {
+		ret = -ENOMEM;
+		goto error_fields;
+	}
+	fields[0].name = "ip";
+	fields[0].type.atype = atype_integer;
+	fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
+	fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT;
+	fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long);
+	fields[0].type.u.basic.integer.reverse_byte_order = 0;
+	fields[0].type.u.basic.integer.base = 16;
+	fields[0].type.u.basic.integer.encoding = lttng_encode_none;
+
+	fields[1].name = "parent_ip";
+	fields[1].type.atype = atype_integer;
+	fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
+	fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT;
+	fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long);
+	fields[1].type.u.basic.integer.reverse_byte_order = 0;
+	fields[1].type.u.basic.integer.base = 16;
+	fields[1].type.u.basic.integer.encoding = lttng_encode_none;
+
+	desc->owner = THIS_MODULE;
+	event->desc = desc;
+
+	return 0;
+
+error_fields:
+	kfree(desc->name);
+error_str:
+	kfree(desc);
+	return ret;
+}
+
+int lttng_kretprobes_register(const char *name,
+			   const char *symbol_name,
+			   uint64_t offset,
+			   uint64_t addr,
+			   struct ltt_event *event_entry,
+			   struct ltt_event *event_return)
+{
+	int ret;
+	struct lttng_krp *lttng_krp;
+
+	/* Kprobes expects a NULL symbol name if unused */
+	if (symbol_name[0] == '\0')
+		symbol_name = NULL;
+
+	ret = lttng_create_kprobe_event(name, event_entry, EVENT_ENTRY);
+	if (ret)
+		goto error;
+	ret = lttng_create_kprobe_event(name, event_return, EVENT_RETURN);
+	if (ret)
+		goto event_return_error;
+	lttng_krp = kzalloc(sizeof(*lttng_krp), GFP_KERNEL);
+	if (!lttng_krp)
+		goto krp_error;
+	lttng_krp->krp.entry_handler = lttng_kretprobes_handler_entry;
+	lttng_krp->krp.handler = lttng_kretprobes_handler_return;
+	if (symbol_name) {
+		char *alloc_symbol;
+
+		alloc_symbol = kstrdup(symbol_name, GFP_KERNEL);
+		if (!alloc_symbol) {
+			ret = -ENOMEM;
+			goto name_error;
+		}
+		lttng_krp->krp.kp.symbol_name =
+			alloc_symbol;
+		event_entry->u.kretprobe.symbol_name =
+			alloc_symbol;
+		event_return->u.kretprobe.symbol_name =
+			alloc_symbol;
+	}
+	lttng_krp->krp.kp.offset = offset;
+	lttng_krp->krp.kp.addr = (void *) (unsigned long) addr;
+
+	/* Allow probe handler to find event structures */
+	lttng_krp->event[EVENT_ENTRY] = event_entry;
+	lttng_krp->event[EVENT_RETURN] = event_return;
+	event_entry->u.kretprobe.lttng_krp = lttng_krp;
+	event_return->u.kretprobe.lttng_krp = lttng_krp;
+
+	/*
+	 * Both events must be unregistered before the kretprobe is
+	 * unregistered. Same for memory allocation.
+	 */
+	kref_init(&lttng_krp->kref_alloc);
+	kref_get(&lttng_krp->kref_alloc);	/* inc refcount to 2 */
+	kref_init(&lttng_krp->kref_register);
+	kref_get(&lttng_krp->kref_register);	/* inc refcount to 2 */
+
+	/*
+	 * Ensure the memory we just allocated don't trigger page faults.
+	 * Well.. kprobes itself puts the page fault handler on the blacklist,
+	 * but we can never be too careful.
+	 */
+	wrapper_vmalloc_sync_all();
+
+	ret = register_kretprobe(&lttng_krp->krp);
+	if (ret)
+		goto register_error;
+	return 0;
+
+register_error:
+	kfree(lttng_krp->krp.kp.symbol_name);
+name_error:
+	kfree(lttng_krp);
+krp_error:
+	kfree(event_return->desc->fields);
+	kfree(event_return->desc->name);
+	kfree(event_return->desc);
+event_return_error:
+	kfree(event_entry->desc->fields);
+	kfree(event_entry->desc->name);
+	kfree(event_entry->desc);
+error:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lttng_kretprobes_register);
+
+static
+void _lttng_kretprobes_unregister_release(struct kref *kref)
+{
+	struct lttng_krp *lttng_krp =
+		container_of(kref, struct lttng_krp, kref_register);
+	unregister_kretprobe(&lttng_krp->krp);
+}
+
+void lttng_kretprobes_unregister(struct ltt_event *event)
+{
+	kref_put(&event->u.kretprobe.lttng_krp->kref_register,
+		_lttng_kretprobes_unregister_release);
+}
+EXPORT_SYMBOL_GPL(lttng_kretprobes_unregister);
+
+static
+void _lttng_kretprobes_release(struct kref *kref)
+{
+	struct lttng_krp *lttng_krp =
+		container_of(kref, struct lttng_krp, kref_alloc);
+	kfree(lttng_krp->krp.kp.symbol_name);
+}
+
+void lttng_kretprobes_destroy_private(struct ltt_event *event)
+{
+	kfree(event->desc->fields);
+	kfree(event->desc->name);
+	kfree(event->desc);
+	kref_put(&event->u.kretprobe.lttng_krp->kref_alloc,
+		_lttng_kretprobes_release);
+}
+EXPORT_SYMBOL_GPL(lttng_kretprobes_destroy_private);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Kretprobes Support");
diff --git a/drivers/staging/lttng/probes/lttng-probe-block.c b/drivers/staging/lttng/probes/lttng-probe-block.c
new file mode 100644
index 0000000..9eeebfc
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-probe-block.c
@@ -0,0 +1,31 @@
+/*
+ * probes/lttng-probe-block.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng block probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/blktrace_api.h>
+
+/*
+ * Create the tracepoint static inlines from the kernel to validate that our
+ * trace event macros match the kernel we run on.
+ */
+#include <trace/events/block.h>
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
+
+#include "../instrumentation/events/lttng-module/block.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng block probes");
diff --git a/drivers/staging/lttng/probes/lttng-probe-irq.c b/drivers/staging/lttng/probes/lttng-probe-irq.c
new file mode 100644
index 0000000..4a6a322
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-probe-irq.c
@@ -0,0 +1,31 @@
+/*
+ * probes/lttng-probe-irq.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng irq probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+/*
+ * Create the tracepoint static inlines from the kernel to validate that our
+ * trace event macros match the kernel we run on.
+ */
+#include <trace/events/irq.h>
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
+
+#include "../instrumentation/events/lttng-module/irq.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng irq probes");
diff --git a/drivers/staging/lttng/probes/lttng-probe-kvm.c b/drivers/staging/lttng/probes/lttng-probe-kvm.c
new file mode 100644
index 0000000..9efc6dd
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-probe-kvm.c
@@ -0,0 +1,31 @@
+/*
+ * probes/lttng-probe-kvm.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng kvm probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/kvm_host.h>
+
+/*
+ * Create the tracepoint static inlines from the kernel to validate that our
+ * trace event macros match the kernel we run on.
+ */
+#include <trace/events/kvm.h>
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
+
+#include "../instrumentation/events/lttng-module/kvm.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng kvm probes");
diff --git a/drivers/staging/lttng/probes/lttng-probe-lttng.c b/drivers/staging/lttng/probes/lttng-probe-lttng.c
new file mode 100644
index 0000000..62aab6c
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-probe-lttng.c
@@ -0,0 +1,24 @@
+/*
+ * probes/lttng-probe-core.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng core probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
+
+#include "../instrumentation/events/lttng-module/lttng.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng core probes");
diff --git a/drivers/staging/lttng/probes/lttng-probe-sched.c b/drivers/staging/lttng/probes/lttng-probe-sched.c
new file mode 100644
index 0000000..18c1521
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-probe-sched.c
@@ -0,0 +1,30 @@
+/*
+ * probes/lttng-probe-sched.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng sched probes.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+
+/*
+ * Create the tracepoint static inlines from the kernel to validate that our
+ * trace event macros match the kernel we run on.
+ */
+#include <trace/events/sched.h>
+
+/*
+ * Create LTTng tracepoint probes.
+ */
+#define LTTNG_PACKAGE_BUILD
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
+
+#include "../instrumentation/events/lttng-module/sched.h"
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng sched probes");
diff --git a/drivers/staging/lttng/probes/lttng-type-list.h b/drivers/staging/lttng/probes/lttng-type-list.h
new file mode 100644
index 0000000..7b953db
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-type-list.h
@@ -0,0 +1,21 @@
+/*
+ * lttng-type-list.h
+ *
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+/* Type list, used to create metadata */
+
+/* Enumerations */
+TRACE_EVENT_ENUM(hrtimer_mode,
+        V(HRTIMER_MODE_ABS),
+        V(HRTIMER_MODE_REL),
+        V(HRTIMER_MODE_PINNED),
+        V(HRTIMER_MODE_ABS_PINNED),
+        V(HRTIMER_MODE_REL_PINNED),
+	R(HRTIMER_MODE_UNDEFINED, 0x04, 0x20),	/* Example (to remove) */
+)
+
+TRACE_EVENT_TYPE(hrtimer_mode, enum, unsigned char)
diff --git a/drivers/staging/lttng/probes/lttng-types.c b/drivers/staging/lttng/probes/lttng-types.c
new file mode 100644
index 0000000..93a9ae5
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-types.c
@@ -0,0 +1,49 @@
+/*
+ * probes/lttng-types.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng types.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include "../wrapper/vmalloc.h"	/* for wrapper_vmalloc_sync_all() */
+#include "../ltt-events.h"
+#include "lttng-types.h"
+#include <linux/hrtimer.h>
+
+#define STAGE_EXPORT_ENUMS
+#include "lttng-types.h"
+#include "lttng-type-list.h"
+#undef STAGE_EXPORT_ENUMS
+
+struct lttng_enum lttng_enums[] = {
+#define STAGE_EXPORT_TYPES
+#include "lttng-types.h"
+#include "lttng-type-list.h"
+#undef STAGE_EXPORT_TYPES
+};
+
+static int lttng_types_init(void)
+{
+	int ret = 0;
+
+	wrapper_vmalloc_sync_all();
+	/* TODO */
+	return ret;
+}
+
+module_init(lttng_types_init);
+
+static void lttng_types_exit(void)
+{
+}
+
+module_exit(lttng_types_exit);
+
+MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>");
+MODULE_DESCRIPTION("LTTng types");
diff --git a/drivers/staging/lttng/probes/lttng-types.h b/drivers/staging/lttng/probes/lttng-types.h
new file mode 100644
index 0000000..1062028
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng-types.h
@@ -0,0 +1,72 @@
+/*
+ * Protect against multiple inclusion of structure declarations, but run the
+ * stages below each time.
+ */
+#ifndef _LTTNG_PROBES_LTTNG_TYPES_H
+#define _LTTNG_PROBES_LTTNG_TYPES_H
+
+/*
+ * probes/lttng-types.h
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * LTTng types.
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#include <linux/seq_file.h>
+#include "lttng.h"
+#include "../ltt-events.h"
+#include "../ltt-tracer.h"
+#include "../ltt-endian.h"
+
+#endif /* _LTTNG_PROBES_LTTNG_TYPES_H */
+
+/* Export enumerations */
+
+#ifdef STAGE_EXPORT_ENUMS
+
+#undef TRACE_EVENT_TYPE
+#define TRACE_EVENT_TYPE(_name, _abstract_type, args...)
+
+#undef TRACE_EVENT_ENUM
+#define TRACE_EVENT_ENUM(_name, _entries...)				\
+	const struct lttng_enum_entry __trace_event_enum_##_name[] = {	\
+		PARAMS(_entries)					\
+	};
+
+/* Enumeration entry (single value) */
+#undef V
+#define V(_string)		{ _string, _string, #_string}
+
+/* Enumeration entry (range) */
+#undef R
+#define R(_string, _range_start, _range_end)				\
+	{ _range_start, _range_end, #_string }
+
+#endif /* STAGE_EXPORT_ENUMS */
+
+
+/* Export named types */
+
+#ifdef STAGE_EXPORT_TYPES
+
+#undef TRACE_EVENT_TYPE___enum
+#define TRACE_EVENT_TYPE___enum(_name, _container_type)			\
+		{							\
+		  .name = #_name,					\
+		  .container_type = __type_integer(_container_type, __BYTE_ORDER, 10, none), \
+		  .entries = __trace_event_enum_##_name, \
+		  .len = ARRAY_SIZE(__trace_event_enum_##_name), \
+		},
+
+/* Local declaration */
+#undef TRACE_EVENT_TYPE
+#define TRACE_EVENT_TYPE(_name, _abstract_type, args...)	\
+		TRACE_EVENT_TYPE___##_abstract_type(_name, args)
+
+#undef TRACE_EVENT_ENUM
+#define TRACE_EVENT_ENUM(_name, _entries...)
+
+#endif /* STAGE_EXPORT_TYPES */
diff --git a/drivers/staging/lttng/probes/lttng.h b/drivers/staging/lttng/probes/lttng.h
new file mode 100644
index 0000000..e16fc2d
--- /dev/null
+++ b/drivers/staging/lttng/probes/lttng.h
@@ -0,0 +1,15 @@
+#ifndef _LTTNG_PROBES_LTTNG_H
+#define _LTTNG_PROBES_LTTNG_H
+
+/*
+ * lttng.h
+ *
+ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *
+ * Dual LGPL v2.1/GPL v2 license.
+ */
+
+#undef PARAMS
+#define PARAMS(args...)		args
+
+#endif /* _LTTNG_PROBES_LTTNG_H */
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 17/19] lttng: toplevel Makefile and Kconfig
  2011-11-26 15:03                               ` [lttng-dev] [PATCH 16/19] lttng: probe callbacks Mathieu Desnoyers
@ 2011-11-26 15:03                                 ` Mathieu Desnoyers
  2011-11-26 15:03                                   ` [lttng-dev] [PATCH 18/19] staging: add LTTng to build Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/lttng/Kconfig  |   35 +++++++++++++++++++++++++++++++++++
 drivers/staging/lttng/Makefile |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/lttng/Kconfig
 create mode 100644 drivers/staging/lttng/Makefile

diff --git a/drivers/staging/lttng/Kconfig b/drivers/staging/lttng/Kconfig
new file mode 100644
index 0000000..34c4a4f
--- /dev/null
+++ b/drivers/staging/lttng/Kconfig
@@ -0,0 +1,35 @@
+config LTTNG
+	tristate "LTTng kernel tracer"
+	depends on TRACEPOINTS
+	help
+	  The LTTng 2.0 Tracer Toolchain allows integrated kernel and
+	  user-space tracing from a single user interface: the "lttng"
+	  command. See http://lttng.org website for the "lttng-tools"
+	  user-space tracer control tools package and the "babeltrace"
+	  package for conversion of trace data to a human-readable
+	  format.
+
+	  LTTng features:
+	  - System-wide tracing across kernel, libraries and
+	    applications,
+	  - Tracepoints, detailed syscall tracing (fast strace replacement),
+	    Function tracer, CPU Performance Monitoring Unit (PMU) counters
+	    and kprobes support,
+	  - Have the ability to attach "context" information to events in the
+	    trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc). All
+	    the extra information fields to be collected with events are
+	    optional, specified on a per-tracing-session basis (except for
+	    timestamp and event id, which are mandatory).
+	  - Precise and fast clock sources with near cycle-level
+	    timestamps,
+	  - Efficient trace data transport:
+	    - Compact Binary format with CTF,
+	    - Per-core buffers ensures scalability,
+	    - Fast-paths in caller context, amortized synchronization,
+	    - Zero-copy using splice and mmap system calls, over disk,
+	      network or consumed in-place,
+	  - Multiple concurrent tracing sessions are supported,
+	  - Designed to meet hard real-time constraints,
+	  - Supports live streaming of the trace data,
+	  - Produces CTF (Common Trace Format) natively (see
+	    http://www.efficios.com/ctf).
diff --git a/drivers/staging/lttng/Makefile b/drivers/staging/lttng/Makefile
new file mode 100644
index 0000000..9ad4eb0
--- /dev/null
+++ b/drivers/staging/lttng/Makefile
@@ -0,0 +1,33 @@
+#
+# Makefile for the LTTng modules.
+#
+
+obj-m += ltt-ring-buffer-client-discard.o
+obj-m += ltt-ring-buffer-client-overwrite.o
+obj-m += ltt-ring-buffer-metadata-client.o
+obj-m += ltt-ring-buffer-client-mmap-discard.o
+obj-m += ltt-ring-buffer-client-mmap-overwrite.o
+obj-m += ltt-ring-buffer-metadata-mmap-client.o
+
+obj-m += ltt-relay.o
+ltt-relay-objs :=  ltt-events.o ltt-debugfs-abi.o \
+			ltt-probes.o ltt-context.o \
+			lttng-context-pid.o lttng-context-procname.o \
+			lttng-context-prio.o lttng-context-nice.o \
+			lttng-context-vpid.o lttng-context-tid.o \
+			lttng-context-vtid.o lttng-context-ppid.o \
+			lttng-context-vppid.o lttng-calibrate.o
+
+ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),)
+ltt-relay-objs += lttng-syscalls.o
+endif
+
+ifneq ($(CONFIG_PERF_EVENTS),)
+ltt-relay-objs += $(shell \
+	if [ $(VERSION) -ge 3 \
+		-o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 33 \) ] ; then \
+		echo "lttng-context-perf-counters.o" ; fi;)
+endif
+
+obj-m += probes/
+obj-m += lib/
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 18/19] staging: add LTTng to build
  2011-11-26 15:03                                 ` [lttng-dev] [PATCH 17/19] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers
@ 2011-11-26 15:03                                   ` Mathieu Desnoyers
  2011-11-26 15:03                                     ` [lttng-dev] [PATCH 19/19] Add LTTng entry to MAINTAINERS file Mathieu Desnoyers
  0 siblings, 1 reply; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 drivers/staging/Kconfig  |    2 ++
 drivers/staging/Makefile |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 06c9081..09895ba 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -72,6 +72,8 @@ source "drivers/staging/phison/Kconfig"
 
 source "drivers/staging/line6/Kconfig"
 
+source "drivers/staging/lttng/Kconfig"
+
 source "drivers/gpu/drm/vmwgfx/Kconfig"
 
 source "drivers/gpu/drm/nouveau/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index f3c5e33..08f7ccc 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_TRANZPORT)		+= frontier/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
 obj-$(CONFIG_IDE_PHISON)	+= phison/
 obj-$(CONFIG_LINE6_USB)		+= line6/
+obj-$(CONFIG_LTTNG)		+= lttng/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)	+= serqt_usb2/
 obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)	+= quatech_usb2/
 obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 19/19] Add LTTng entry to MAINTAINERS file
  2011-11-26 15:03                                   ` [lttng-dev] [PATCH 18/19] staging: add LTTng to build Mathieu Desnoyers
@ 2011-11-26 15:03                                     ` Mathieu Desnoyers
  0 siblings, 0 replies; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-26 15:03 UTC (permalink / raw)


Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 MAINTAINERS |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6185d05..7627a1b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4065,6 +4065,13 @@ W:	http://ltp.sourceforge.net/
 T:	git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev
 S:	Maintained
 
+LTTng (Linux Trace Toolkit Next Generation)
+M:	Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+L:	lttng-dev at lists.lttng.org (moderated for non-subscribers)
+W:	http://lttng.org
+S:	Maintained
+F:	drivers/staging/lttng/
+
 M32R ARCHITECTURE
 M:	Hirokazu Takata <takata at linux-m32r.org>
 L:	linux-m32r at ml.linux-m32r.org
-- 
1.7.2.5




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files
  2011-11-26 15:03                           ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Mathieu Desnoyers
  2011-11-26 15:03                             ` [lttng-dev] [PATCH 15/19] lttng: add system call instrumentation probe Mathieu Desnoyers
@ 2011-11-27  2:24                             ` Greg KH
  2011-11-27 10:04                               ` Mathieu Desnoyers
  1 sibling, 1 reply; 24+ messages in thread
From: Greg KH @ 2011-11-27  2:24 UTC (permalink / raw)


On Sat, Nov 26, 2011 at 10:03:39AM -0500, Mathieu Desnoyers wrote:
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> ---
>  drivers/staging/lttng/ChangeLog    |   75 ++++++
>  drivers/staging/lttng/LICENSE      |   27 ++
>  drivers/staging/lttng/README       |   46 ++++
>  drivers/staging/lttng/gpl-2.0.txt  |  339 ++++++++++++++++++++++++
>  drivers/staging/lttng/lgpl-2.1.txt |  504 ++++++++++++++++++++++++++++++++++++
>  5 files changed, 991 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/staging/lttng/ChangeLog
>  create mode 100644 drivers/staging/lttng/LICENSE
>  create mode 100644 drivers/staging/lttng/README
>  create mode 100644 drivers/staging/lttng/gpl-2.0.txt
>  create mode 100644 drivers/staging/lttng/lgpl-2.1.txt

I've edited this patch, and only include the LICENSE and README files
from it, as that's all that is really needed in the kernel source tree
(no need for a license that is a duplicate, and a changelog will just be
instantly deleted anyway.)

thanks,

greg k-h



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] LTTng driver submission for inclusion in staging (resend)
  2011-11-26 15:03 [lttng-dev] LTTng driver submission for inclusion in staging (resend) Mathieu Desnoyers
  2011-11-26 15:03 ` [lttng-dev] [PATCH 01/19] lttng lib: ring buffer Mathieu Desnoyers
@ 2011-11-27  2:28 ` Greg KH
  2011-11-27 10:07   ` Mathieu Desnoyers
  1 sibling, 1 reply; 24+ messages in thread
From: Greg KH @ 2011-11-27  2:28 UTC (permalink / raw)


On Sat, Nov 26, 2011 at 10:03:25AM -0500, Mathieu Desnoyers wrote:
> 
> Hi,
> 
> I hereby propose the LTTng kernel tracer for inclusion into the staging
> area of the Linux kernel. For those eager to try it out, and to get
> information about the features of this tracer, you should grab the
> control/consumer/viewer tools at: http://lttng.org/lttng2.0
> 
> Feedback is very welcome!

I applied this, but it failed to build:

  CC [M]  drivers/staging/lttng/ltt-ring-buffer-client-discard.o
In file included from drivers/staging/lttng/ltt-tracer.h:24:0,
                 from drivers/staging/lttng/ltt-ring-buffer-client-discard.c:12:
drivers/staging/lttng/wrapper/trace-clock.h: In function ?get_trace_clock?:
drivers/staging/lttng/wrapper/trace-clock.h:66:2: warning: #warning "LTTng: Using mainline kernel monotonic clock. NMIs will not be traced, and expect significant performance degradation compared to the LTTng trace clocks. Integration of the LTTng 0.x trace clocks into LTTng 2.0 is planned in a near future." [-Wcpp]
In file included from drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h:1:0,
                 from drivers/staging/lttng/ltt-ring-buffer-client.h:18,
                 from drivers/staging/lttng/ltt-ring-buffer-client-discard.c:17:
drivers/staging/lttng/wrapper/ringbuffer/../../lib/ringbuffer/frontend_types.h: At top level:
drivers/staging/lttng/wrapper/ringbuffer/../../lib/ringbuffer/frontend_types.h:23:86: fatal error: ../../lib/prio_heap/lttng_prio_heap.h: No such file or directory
compilation terminated.


The build warning is a bit harsh, and should be a Kconfig option or a run-time
kernel log message, please fix that.  No new code should ever add build
warnings, especially ones like this.

The build error isn't ok, so I can't apply this series, sorry :(

Care to fix this up and resend?

thanks,

greg k-h



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files
  2011-11-27  2:24                             ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Greg KH
@ 2011-11-27 10:04                               ` Mathieu Desnoyers
  0 siblings, 0 replies; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-27 10:04 UTC (permalink / raw)


* Greg KH (greg at kroah.com) wrote:
> On Sat, Nov 26, 2011 at 10:03:39AM -0500, Mathieu Desnoyers wrote:
> > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> > ---
> >  drivers/staging/lttng/ChangeLog    |   75 ++++++
> >  drivers/staging/lttng/LICENSE      |   27 ++
> >  drivers/staging/lttng/README       |   46 ++++
> >  drivers/staging/lttng/gpl-2.0.txt  |  339 ++++++++++++++++++++++++
> >  drivers/staging/lttng/lgpl-2.1.txt |  504 ++++++++++++++++++++++++++++++++++++
> >  5 files changed, 991 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/staging/lttng/ChangeLog
> >  create mode 100644 drivers/staging/lttng/LICENSE
> >  create mode 100644 drivers/staging/lttng/README
> >  create mode 100644 drivers/staging/lttng/gpl-2.0.txt
> >  create mode 100644 drivers/staging/lttng/lgpl-2.1.txt
> 
> I've edited this patch, and only include the LICENSE and README files
> from it, as that's all that is really needed in the kernel source tree
> (no need for a license that is a duplicate, and a changelog will just be
> instantly deleted anyway.)

Perfect, thanks !

Mathieu

> 
> thanks,
> 
> greg k-h

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [lttng-dev] LTTng driver submission for inclusion in staging (resend)
  2011-11-27  2:28 ` [lttng-dev] LTTng driver submission for inclusion in staging (resend) Greg KH
@ 2011-11-27 10:07   ` Mathieu Desnoyers
  0 siblings, 0 replies; 24+ messages in thread
From: Mathieu Desnoyers @ 2011-11-27 10:07 UTC (permalink / raw)


* Greg KH (greg at kroah.com) wrote:
> On Sat, Nov 26, 2011 at 10:03:25AM -0500, Mathieu Desnoyers wrote:
> > 
> > Hi,
> > 
> > I hereby propose the LTTng kernel tracer for inclusion into the staging
> > area of the Linux kernel. For those eager to try it out, and to get
> > information about the features of this tracer, you should grab the
> > control/consumer/viewer tools at: http://lttng.org/lttng2.0
> > 
> > Feedback is very welcome!
> 
> I applied this, but it failed to build:
> 
>   CC [M]  drivers/staging/lttng/ltt-ring-buffer-client-discard.o
> In file included from drivers/staging/lttng/ltt-tracer.h:24:0,
>                  from drivers/staging/lttng/ltt-ring-buffer-client-discard.c:12:
> drivers/staging/lttng/wrapper/trace-clock.h: In function ?get_trace_clock?:
> drivers/staging/lttng/wrapper/trace-clock.h:66:2: warning: #warning "LTTng: Using mainline kernel monotonic clock. NMIs will not be traced, and expect significant performance degradation compared to the LTTng trace clocks. Integration of the LTTng 0.x trace clocks into LTTng 2.0 is planned in a near future." [-Wcpp]
> In file included from drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h:1:0,
>                  from drivers/staging/lttng/ltt-ring-buffer-client.h:18,
>                  from drivers/staging/lttng/ltt-ring-buffer-client-discard.c:17:
> drivers/staging/lttng/wrapper/ringbuffer/../../lib/ringbuffer/frontend_types.h: At top level:
> drivers/staging/lttng/wrapper/ringbuffer/../../lib/ringbuffer/frontend_types.h:23:86: fatal error: ../../lib/prio_heap/lttng_prio_heap.h: No such file or directory
> compilation terminated.
> 
> 
> The build warning is a bit harsh, and should be a Kconfig option or a run-time
> kernel log message, please fix that.  No new code should ever add build
> warnings, especially ones like this.
> 
> The build error isn't ok, so I can't apply this series, sorry :(
> 
> Care to fix this up and resend?

No problem. I'll look into what happened in the git-to-patch transition,
remove the lgpl/gpl files, and move the #warning messages into the TODO
file, then resend.

Thanks,

Mathieu

> 
> thanks,
> 
> greg k-h

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2011-11-27 10:07 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-26 15:03 [lttng-dev] LTTng driver submission for inclusion in staging (resend) Mathieu Desnoyers
2011-11-26 15:03 ` [lttng-dev] [PATCH 01/19] lttng lib: ring buffer Mathieu Desnoyers
2011-11-26 15:03   ` [lttng-dev] [PATCH 02/19] lttng lib: portable bitfield read/write header Mathieu Desnoyers
2011-11-26 15:03     ` [lttng-dev] [PATCH 03/19] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers
2011-11-26 15:03       ` [lttng-dev] [PATCH 04/19] lttng: offset alignment header Mathieu Desnoyers
2011-11-26 15:03         ` [lttng-dev] [PATCH 05/19] lttng libs: add Makefile Mathieu Desnoyers
2011-11-26 15:03           ` [lttng-dev] [PATCH 06/19] lttng wrappers Mathieu Desnoyers
2011-11-26 15:03             ` [lttng-dev] [PATCH 07/19] lttng instrumentation: tracepoint events Mathieu Desnoyers
2011-11-26 15:03               ` [lttng-dev] [PATCH 08/19] lttng: syscall instrumentation Mathieu Desnoyers
2011-11-26 15:03                 ` [lttng-dev] [PATCH 09/19] lttng: lib ring buffer clients Mathieu Desnoyers
2011-11-26 15:03                   ` [lttng-dev] [PATCH 10/19] lttng: tracer control and core structures Mathieu Desnoyers
2011-11-26 15:03                     ` [lttng-dev] [PATCH 11/19] lttng: dynamically selectable context information Mathieu Desnoyers
2011-11-26 15:03                       ` [lttng-dev] [PATCH 12/19] lttng: timing calibration feature Mathieu Desnoyers
2011-11-26 15:03                         ` [lttng-dev] [PATCH 13/19] lttng: debugfs and procfs ABI Mathieu Desnoyers
2011-11-26 15:03                           ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Mathieu Desnoyers
2011-11-26 15:03                             ` [lttng-dev] [PATCH 15/19] lttng: add system call instrumentation probe Mathieu Desnoyers
2011-11-26 15:03                               ` [lttng-dev] [PATCH 16/19] lttng: probe callbacks Mathieu Desnoyers
2011-11-26 15:03                                 ` [lttng-dev] [PATCH 17/19] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers
2011-11-26 15:03                                   ` [lttng-dev] [PATCH 18/19] staging: add LTTng to build Mathieu Desnoyers
2011-11-26 15:03                                     ` [lttng-dev] [PATCH 19/19] Add LTTng entry to MAINTAINERS file Mathieu Desnoyers
2011-11-27  2:24                             ` [lttng-dev] [PATCH 14/19] lttng: Add documentation and license files Greg KH
2011-11-27 10:04                               ` Mathieu Desnoyers
2011-11-27  2:28 ` [lttng-dev] LTTng driver submission for inclusion in staging (resend) Greg KH
2011-11-27 10:07   ` Mathieu Desnoyers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox