Revert "remove old version of LTTNG"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Apr 2012 00:36:37 +0000 (17:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Apr 2012 00:36:37 +0000 (17:36 -0700)
This reverts commit 8efd67cefaa1cc27c1c45a84217404f719edd27b.

Oops, the new version of LTTNG fit on top of this one...

29 files changed:
patches.lttng/0000-lttng-lib-lttng-priority-heap.patch [new file with mode: 0644]
patches.lttng/0001-lttng-lib-ring-buffer.patch [new file with mode: 0644]
patches.lttng/0002-lttng-lib-portable-bitfield-read-write-header.patch [new file with mode: 0644]
patches.lttng/0003-lttng-BUILD_RUNTIME_BUG_ON.patch [new file with mode: 0644]
patches.lttng/0004-lttng-offset-alignment-header.patch [new file with mode: 0644]
patches.lttng/0005-lttng-libs-add-Makefile.patch [new file with mode: 0644]
patches.lttng/0006-lttng-wrappers.patch [new file with mode: 0644]
patches.lttng/0007-lttng-instrumentation-tracepoint-events.patch [new file with mode: 0644]
patches.lttng/0008-lttng-syscall-instrumentation.patch [new file with mode: 0644]
patches.lttng/0009-lttng-lib-ring-buffer-clients.patch [new file with mode: 0644]
patches.lttng/0010-lttng-tracer-control-and-core-structures.patch [new file with mode: 0644]
patches.lttng/0011-lttng-dynamically-selectable-context-information.patch [new file with mode: 0644]
patches.lttng/0012-lttng-timing-calibration-feature.patch [new file with mode: 0644]
patches.lttng/0013-lttng-debugfs-and-procfs-ABI.patch [new file with mode: 0644]
patches.lttng/0014-lttng-Add-documentation-and-TODO-files.patch [new file with mode: 0644]
patches.lttng/0015-lttng-add-system-call-instrumentation-probe.patch [new file with mode: 0644]
patches.lttng/0016-lttng-probe-callbacks.patch [new file with mode: 0644]
patches.lttng/0017-lttng-toplevel-Makefile-and-Kconfig.patch [new file with mode: 0644]
patches.lttng/0018-staging-add-LTTng-to-build.patch [new file with mode: 0644]
patches.lttng/0019-staging-Add-LTTng-entry-to-MAINTAINERS-file.patch [new file with mode: 0644]
patches.lttng/0069-lttng-lib-ring-buffer-remove-stale-null-pointer.patch [new file with mode: 0644]
patches.lttng/0070-lttng-lib-ring-buffer-remove-duplicate-null-pointer.patch [new file with mode: 0644]
patches.lttng/0071-lttng-lib-ring-buffer-move-null-pointer-check-to-ope.patch [new file with mode: 0644]
patches.lttng/0072-lttng-wrapper-add-missing-include-to-kallsyms-wrappe.patch [new file with mode: 0644]
patches.lttng/0073-staging-lttng-cleanup-one-bit-signed-bitfields.patch [new file with mode: 0644]
patches.lttng/0172-staging-lttng-Fix-recent-modifications-to-string_fro.patch [new file with mode: 0644]
patches.lttng/0173-staging-lttng-TODO-update-lttng-reported-to-work-fin.patch [new file with mode: 0644]
patches.lttng/0174-staging-lttng-Update-max-symbol-length-to-256.patch [new file with mode: 0644]
series

diff --git a/patches.lttng/0000-lttng-lib-lttng-priority-heap.patch b/patches.lttng/0000-lttng-lib-lttng-priority-heap.patch
new file mode 100644 (file)
index 0000000..2c7aa68
--- /dev/null
@@ -0,0 +1,344 @@
+From 1b4d28b622fd88745fc020dd3e363e586e4f9943 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:08 -0500
+Subject: lttng lib: lttng priority heap
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+diff --git a/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c
+new file mode 100644
+index 0000000..2fce143
+--- /dev/null
++++ b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c
+@@ -0,0 +1,207 @@
++/*
++ * lttng_prio_heap.c
++ *
++ * Priority heap containing pointers. Based on CLRS, chapter 6.
++ *
++ * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@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 <linux/slab.h>
++#include "lttng_prio_heap.h"
++
++#ifdef DEBUG_HEAP
++void lttng_check_heap(const struct lttng_ptr_heap *heap)
++{
++      size_t i;
++
++      if (!heap->len)
++              return;
++
++      for (i = 1; i < heap->len; i++)
++              WARN_ON_ONCE(!heap->gt(heap->ptrs[i], heap->ptrs[0]));
++}
++#endif
++
++static
++size_t parent(size_t i)
++{
++      return (i -1) >> 1;
++}
++
++static
++size_t left(size_t i)
++{
++      return (i << 1) + 1;
++}
++
++static
++size_t right(size_t i)
++{
++      return (i << 1) + 2;
++}
++
++/*
++ * Copy of heap->ptrs pointer is invalid after heap_grow.
++ */
++static
++int heap_grow(struct lttng_ptr_heap *heap, size_t new_len)
++{
++      void **new_ptrs;
++
++      if (heap->alloc_len >= new_len)
++              return 0;
++
++      heap->alloc_len = max_t(size_t, new_len, heap->alloc_len << 1);
++      new_ptrs = kmalloc(heap->alloc_len * sizeof(void *), heap->gfpmask);
++      if (!new_ptrs)
++              return -ENOMEM;
++      if (heap->ptrs)
++              memcpy(new_ptrs, heap->ptrs, heap->len * sizeof(void *));
++      kfree(heap->ptrs);
++      heap->ptrs = new_ptrs;
++      return 0;
++}
++
++static
++int heap_set_len(struct lttng_ptr_heap *heap, size_t new_len)
++{
++      int ret;
++
++      ret = heap_grow(heap, new_len);
++      if (ret)
++              return ret;
++      heap->len = new_len;
++      return 0;
++}
++
++int lttng_heap_init(struct lttng_ptr_heap *heap, size_t alloc_len,
++            gfp_t gfpmask, int gt(void *a, void *b))
++{
++      heap->ptrs = NULL;
++      heap->len = 0;
++      heap->alloc_len = 0;
++      heap->gt = gt;
++      heap->gfpmask = gfpmask;
++      /*
++       * Minimum size allocated is 1 entry to ensure memory allocation
++       * never fails within heap_replace_max.
++       */
++      return heap_grow(heap, max_t(size_t, 1, alloc_len));
++}
++
++void lttng_heap_free(struct lttng_ptr_heap *heap)
++{
++      kfree(heap->ptrs);
++}
++
++static void heapify(struct lttng_ptr_heap *heap, size_t i)
++{
++      void **ptrs = heap->ptrs;
++      size_t l, r, largest;
++
++      for (;;) {
++              void *tmp;
++
++              l = left(i);
++              r = right(i);
++              if (l < heap->len && heap->gt(ptrs[l], ptrs[i]))
++                      largest = l;
++              else
++                      largest = i;
++              if (r < heap->len && heap->gt(ptrs[r], ptrs[largest]))
++                      largest = r;
++              if (largest == i)
++                      break;
++              tmp = ptrs[i];
++              ptrs[i] = ptrs[largest];
++              ptrs[largest] = tmp;
++              i = largest;
++      }
++      lttng_check_heap(heap);
++}
++
++void *lttng_heap_replace_max(struct lttng_ptr_heap *heap, void *p)
++{
++      void *res;
++
++      if (!heap->len) {
++              (void) heap_set_len(heap, 1);
++              heap->ptrs[0] = p;
++              lttng_check_heap(heap);
++              return NULL;
++      }
++
++      /* Replace the current max and heapify */
++      res = heap->ptrs[0];
++      heap->ptrs[0] = p;
++      heapify(heap, 0);
++      return res;
++}
++
++int lttng_heap_insert(struct lttng_ptr_heap *heap, void *p)
++{
++      void **ptrs;
++      size_t pos;
++      int ret;
++
++      ret = heap_set_len(heap, heap->len + 1);
++      if (ret)
++              return ret;
++      ptrs = heap->ptrs;
++      pos = heap->len - 1;
++      while (pos > 0 && heap->gt(p, ptrs[parent(pos)])) {
++              /* Move parent down until we find the right spot */
++              ptrs[pos] = ptrs[parent(pos)];
++              pos = parent(pos);
++      }
++      ptrs[pos] = p;
++      lttng_check_heap(heap);
++      return 0;
++}
++
++void *lttng_heap_remove(struct lttng_ptr_heap *heap)
++{
++      switch (heap->len) {
++      case 0:
++              return NULL;
++      case 1:
++              (void) heap_set_len(heap, 0);
++              return heap->ptrs[0];
++      }
++      /* Shrink, replace the current max by previous last entry and heapify */
++      heap_set_len(heap, heap->len - 1);
++      /* len changed. previous last entry is at heap->len */
++      return lttng_heap_replace_max(heap, heap->ptrs[heap->len]);
++}
++
++void *lttng_heap_cherrypick(struct lttng_ptr_heap *heap, void *p)
++{
++      size_t pos, len = heap->len;
++
++      for (pos = 0; pos < len; pos++)
++              if (heap->ptrs[pos] == p)
++                      goto found;
++      return NULL;
++found:
++      if (heap->len == 1) {
++              (void) heap_set_len(heap, 0);
++              lttng_check_heap(heap);
++              return heap->ptrs[0];
++      }
++      /* Replace p with previous last entry and heapify. */
++      heap_set_len(heap, heap->len - 1);
++      /* len changed. previous last entry is at heap->len */
++      heap->ptrs[pos] = heap->ptrs[heap->len];
++      heapify(heap, pos);
++      return p;
++}
+diff --git a/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h
+new file mode 100644
+index 0000000..ea8dbb8
+--- /dev/null
++++ b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h
+@@ -0,0 +1,117 @@
++#ifndef _LTTNG_PRIO_HEAP_H
++#define _LTTNG_PRIO_HEAP_H
++
++/*
++ * lttng_prio_heap.h
++ *
++ * Priority heap containing pointers. Based on CLRS, chapter 6.
++ *
++ * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@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 <linux/gfp.h>
++
++struct lttng_ptr_heap {
++      size_t len, alloc_len;
++      void **ptrs;
++      int (*gt)(void *a, void *b);
++      gfp_t gfpmask;
++};
++
++#ifdef DEBUG_HEAP
++void lttng_check_heap(const struct lttng_ptr_heap *heap);
++#else
++static inline
++void lttng_check_heap(const struct lttng_ptr_heap *heap)
++{
++}
++#endif
++
++/**
++ * lttng_heap_maximum - return the largest element in the heap
++ * @heap: the heap to be operated on
++ *
++ * Returns the largest element in the heap, without performing any modification
++ * to the heap structure. Returns NULL if the heap is empty.
++ */
++static inline void *lttng_heap_maximum(const struct lttng_ptr_heap *heap)
++{
++      lttng_check_heap(heap);
++      return heap->len ? heap->ptrs[0] : NULL;
++}
++
++/**
++ * lttng_heap_init - initialize the heap
++ * @heap: the heap to initialize
++ * @alloc_len: number of elements initially allocated
++ * @gfp: allocation flags
++ * @gt: function to compare the elements
++ *
++ * Returns -ENOMEM if out of memory.
++ */
++extern int lttng_heap_init(struct lttng_ptr_heap *heap,
++                   size_t alloc_len, gfp_t gfpmask,
++                   int gt(void *a, void *b));
++
++/**
++ * lttng_heap_free - free the heap
++ * @heap: the heap to free
++ */
++extern void lttng_heap_free(struct lttng_ptr_heap *heap);
++
++/**
++ * lttng_heap_insert - insert an element into the heap
++ * @heap: the heap to be operated on
++ * @p: the element to add
++ *
++ * Insert an element into the heap.
++ *
++ * Returns -ENOMEM if out of memory.
++ */
++extern int lttng_heap_insert(struct lttng_ptr_heap *heap, void *p);
++
++/**
++ * lttng_heap_remove - remove the largest element from the heap
++ * @heap: the heap to be operated on
++ *
++ * Returns the largest element in the heap. It removes this element from the
++ * heap. Returns NULL if the heap is empty.
++ */
++extern void *lttng_heap_remove(struct lttng_ptr_heap *heap);
++
++/**
++ * lttng_heap_cherrypick - remove a given element from the heap
++ * @heap: the heap to be operated on
++ * @p: the element
++ *
++ * Remove the given element from the heap. Return the element if present, else
++ * return NULL. This algorithm has a complexity of O(n), which is higher than
++ * O(log(n)) provided by the rest of this API.
++ */
++extern void *lttng_heap_cherrypick(struct lttng_ptr_heap *heap, void *p);
++
++/**
++ * lttng_heap_replace_max - replace the the largest element from the heap
++ * @heap: the heap to be operated on
++ * @p: the pointer to be inserted as topmost element replacement
++ *
++ * Returns the largest element in the heap. It removes this element from the
++ * heap. The heap is rebalanced only once after the insertion. Returns NULL if
++ * the heap is empty.
++ *
++ * This is the equivalent of calling heap_remove() and then heap_insert(), but
++ * it only rebalances the heap once. It never allocates memory.
++ */
++extern void *lttng_heap_replace_max(struct lttng_ptr_heap *heap, void *p);
++
++#endif /* _LTTNG_PRIO_HEAP_H */
diff --git a/patches.lttng/0001-lttng-lib-ring-buffer.patch b/patches.lttng/0001-lttng-lib-ring-buffer.patch
new file mode 100644 (file)
index 0000000..9d27c5f
--- /dev/null
@@ -0,0 +1,6804 @@
+From c844b2f5cfea185bcc5b5344ee642b3e3ee7ff03 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:09 -0500
+Subject: lttng lib: ring buffer
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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@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@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@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@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@efficios.com>
++ *
++ * Ring Buffer Library Synchronization Header (API).
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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@efficios.com>
++ *
++ * Ring Buffer Library Synchronization Header (buffer write API).
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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@efficios.com>
++ *
++ * Ring Buffer Library Synchronization Header (internal helpers).
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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@efficios.com>
++ *
++ * Ring Buffer Library Synchronization Header (types).
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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@efficios.com>
++ *
++ * Ring buffer and channel iterators.
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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@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@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@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@efficios.com>
++ *
++ * Inspired from LTT and RelayFS:
++ *  Karim Yaghmour <karim@opersys.com>
++ *  Tom Zanussi <zanussi@us.ibm.com>
++ *  Bob Wisniewski <bob@watson.ibm.com>
++ * And from K42 :
++ *  Bob Wisniewski <bob@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@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@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@us.ibm.com>, IBM Corp
++ * Copyright (C) 1999-2005 - Karim Yaghmour <karim@opersys.com>
++ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers@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@us.ibm.com>, IBM Corp
++ * Copyright (C) 1999-2005 - Karim Yaghmour <karim@opersys.com>
++ * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers@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@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@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@efficios.com>
++ *
++ * Wait-free ring buffer VFS file operations.
++ *
++ * Author:
++ *    Mathieu Desnoyers <mathieu.desnoyers@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.9
+
diff --git a/patches.lttng/0002-lttng-lib-portable-bitfield-read-write-header.patch b/patches.lttng/0002-lttng-lib-portable-bitfield-read-write-header.patch
new file mode 100644 (file)
index 0000000..1bca3f7
--- /dev/null
@@ -0,0 +1,421 @@
+From 7430010ec58a189e2ef81d504417299779f47663 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:10 -0500
+Subject: lttng lib: portable bitfield read/write header
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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.9
+
diff --git a/patches.lttng/0003-lttng-BUILD_RUNTIME_BUG_ON.patch b/patches.lttng/0003-lttng-BUILD_RUNTIME_BUG_ON.patch
new file mode 100644 (file)
index 0000000..a94b2ea
--- /dev/null
@@ -0,0 +1,50 @@
+From a643061cb861ebb18e0292b7510dd9879b598ae0 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:11 -0500
+Subject: lttng: BUILD_RUNTIME_BUG_ON
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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.9
+
diff --git a/patches.lttng/0004-lttng-offset-alignment-header.patch b/patches.lttng/0004-lttng-offset-alignment-header.patch
new file mode 100644 (file)
index 0000000..4ddd023
--- /dev/null
@@ -0,0 +1,82 @@
+From 2d31597d37ec8842b9575005190fde2898764628 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:12 -0500
+Subject: lttng: offset alignment header
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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.9
+
diff --git a/patches.lttng/0005-lttng-libs-add-Makefile.patch b/patches.lttng/0005-lttng-libs-add-Makefile.patch
new file mode 100644 (file)
index 0000000..2c2b608
--- /dev/null
@@ -0,0 +1,32 @@
+From 848afbd72ed02db1ed20ae7917c241983df7b314 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:13 -0500
+Subject: lttng libs: add Makefile
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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.9
+
diff --git a/patches.lttng/0006-lttng-wrappers.patch b/patches.lttng/0006-lttng-wrappers.patch
new file mode 100644 (file)
index 0000000..f318563
--- /dev/null
@@ -0,0 +1,625 @@
+From 69e1242eaab021eb6a4110a671af1e443fbf704d Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:14 -0500
+Subject: lttng wrappers
+
+Implement wrappers for compatibility with older kernel versions and
+kernels with had the libringbuffer (old) patchset applied.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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               |   14 ++++
+ 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        |   75 ++++++++++++++++++++
+ drivers/staging/lttng/wrapper/uuid.h               |   29 ++++++++
+ drivers/staging/lttng/wrapper/vmalloc.h            |   49 +++++++++++++
+ 24 files changed, 417 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@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@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@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@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..9c2d18f
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/poll.h
+@@ -0,0 +1,14 @@
++#ifndef _LTTNG_WRAPPER_POLL_H
++#define _LTTNG_WRAPPER_POLL_H
++
++/*
++ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ *
++ * Dual LGPL v2.1/GPL v2 license.
++ */
++
++#include <linux/poll.h>
++
++#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@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@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@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..8b77428
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/trace-clock.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@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");
++
++      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@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@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.9
+
diff --git a/patches.lttng/0007-lttng-instrumentation-tracepoint-events.patch b/patches.lttng/0007-lttng-instrumentation-tracepoint-events.patch
new file mode 100644 (file)
index 0000000..2aa7da8
--- /dev/null
@@ -0,0 +1,3227 @@
+From 763be8c0a919015a3c1e205005176d4aacec22e3 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:15 -0500
+Subject: lttng instrumentation: tracepoint events
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../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.9
+
diff --git a/patches.lttng/0008-lttng-syscall-instrumentation.patch b/patches.lttng/0008-lttng-syscall-instrumentation.patch
new file mode 100644 (file)
index 0000000..1ddac7a
--- /dev/null
@@ -0,0 +1,7758 @@
+From 54a69e5511f5031d3d14e1418ef7ea2456a73684 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:16 -0500
+Subject: lttng: syscall instrumentation
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../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           |    7 +
+ .../syscalls/headers/syscalls_integers_override.h  |   14 +
+ .../syscalls/headers/syscalls_pointers.h           |    7 +
+ .../syscalls/headers/syscalls_pointers_override.h  |    4 +
+ .../syscalls/headers/syscalls_unknown.h            |   55 +
+ .../headers/x86-32-syscalls-3.1.0-rc6_integers.h   | 1163 ++++++++++
+ .../x86-32-syscalls-3.1.0-rc6_integers_override.h  |   38 +
+ .../headers/x86-32-syscalls-3.1.0-rc6_pointers.h   | 2232 ++++++++++++++++++++
+ .../x86-32-syscalls-3.1.0-rc6_pointers_override.h  |   17 +
+ .../headers/x86-64-syscalls-3.0.4_integers.h       | 1013 +++++++++
+ .../x86-64-syscalls-3.0.4_integers_override.h      |    3 +
+ .../headers/x86-64-syscalls-3.0.4_pointers.h       | 2076 ++++++++++++++++++
+ .../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    |  275 +++
+ 21 files changed, 7573 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..dabc4bf
+--- /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..41db916
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h
+@@ -0,0 +1,7 @@
++#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..276d9a6
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h
+@@ -0,0 +1,14 @@
++#define OVERRIDE_32_sys_mmap
++#define OVERRIDE_64_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..3223890
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h
+@@ -0,0 +1,7 @@
++#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..e464a4e
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h
+@@ -0,0 +1,4 @@
++/*
++ * This is a place-holder for override defines for system calls with
++ * pointers (all architectures).
++ */
+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..f4ee16c
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h
+@@ -0,0 +1,1163 @@
++/* 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"
++#include "syscalls_integers_override.h"
++
++SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,
++      TP_STRUCT__entry(),
++      TP_fast_assign(),
++      TP_printk()
++)
++#ifndef OVERRIDE_32_sys_restart_syscall
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall)
++#endif
++#ifndef OVERRIDE_32_sys_getpid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid)
++#endif
++#ifndef OVERRIDE_32_sys_getuid16
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid16)
++#endif
++#ifndef OVERRIDE_32_sys_pause
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause)
++#endif
++#ifndef OVERRIDE_32_sys_sync
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync)
++#endif
++#ifndef OVERRIDE_32_sys_getgid16
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid16)
++#endif
++#ifndef OVERRIDE_32_sys_geteuid16
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid16)
++#endif
++#ifndef OVERRIDE_32_sys_getegid16
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid16)
++#endif
++#ifndef OVERRIDE_32_sys_getppid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid)
++#endif
++#ifndef OVERRIDE_32_sys_getpgrp
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp)
++#endif
++#ifndef OVERRIDE_32_sys_setsid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid)
++#endif
++#ifndef OVERRIDE_32_sys_sgetmask
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sgetmask)
++#endif
++#ifndef OVERRIDE_32_sys_vhangup
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup)
++#endif
++#ifndef OVERRIDE_32_sys_munlockall
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall)
++#endif
++#ifndef OVERRIDE_32_sys_sched_yield
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield)
++#endif
++#ifndef OVERRIDE_32_sys_getuid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid)
++#endif
++#ifndef OVERRIDE_32_sys_getgid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid)
++#endif
++#ifndef OVERRIDE_32_sys_geteuid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid)
++#endif
++#ifndef OVERRIDE_32_sys_getegid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid)
++#endif
++#ifndef OVERRIDE_32_sys_gettid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid)
++#endif
++#ifndef OVERRIDE_32_sys_inotify_init
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init)
++#endif
++#ifndef OVERRIDE_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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"
++#include "syscalls_integers_override.h"
++
++#ifndef OVERRIDE_TABLE_32_sys_restart_syscall
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 0, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getpid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 20, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getuid16
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid16, 24, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pause
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 29, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sync
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 36, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getgid16
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid16, 47, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_geteuid16
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid16, 49, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getegid16
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid16, 50, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getppid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 64, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getpgrp
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 65, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setsid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 66, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sgetmask
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sgetmask, 68, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_vhangup
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 111, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_munlockall
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 153, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_yield
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 158, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getuid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 199, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getgid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 200, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_geteuid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 201, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getegid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 202, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_gettid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 224, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_inotify_init
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 291, 0)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_exit
++TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 1, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_close
++TRACE_SYSCALL_TABLE(sys_close, sys_close, 6, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lseek
++TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 19, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setuid16
++TRACE_SYSCALL_TABLE(sys_setuid16, sys_setuid16, 23, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ptrace
++TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 26, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_alarm
++TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 27, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_nice
++TRACE_SYSCALL_TABLE(sys_nice, sys_nice, 34, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_kill
++TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 37, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_dup
++TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 41, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_brk
++TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 45, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setgid16
++TRACE_SYSCALL_TABLE(sys_setgid16, sys_setgid16, 46, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_signal
++TRACE_SYSCALL_TABLE(sys_signal, sys_signal, 48, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ioctl
++TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 54, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fcntl
++TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 55, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setpgid
++TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 57, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_umask
++TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 60, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_dup2
++TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 63, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ssetmask
++TRACE_SYSCALL_TABLE(sys_ssetmask, sys_ssetmask, 69, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setreuid16
++TRACE_SYSCALL_TABLE(sys_setreuid16, sys_setreuid16, 70, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setregid16
++TRACE_SYSCALL_TABLE(sys_setregid16, sys_setregid16, 71, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_munmap
++TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 91, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ftruncate
++TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 93, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchmod
++TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 94, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchown16
++TRACE_SYSCALL_TABLE(sys_fchown16, sys_fchown16, 95, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getpriority
++TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 96, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setpriority
++TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 97, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fsync
++TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 118, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mprotect
++TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 125, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getpgid
++TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 132, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchdir
++TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 133, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_bdflush
++TRACE_SYSCALL_TABLE(sys_bdflush, sys_bdflush, 134, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sysfs
++TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 135, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_personality
++TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 136, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setfsuid16
++TRACE_SYSCALL_TABLE(sys_setfsuid16, sys_setfsuid16, 138, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setfsgid16
++TRACE_SYSCALL_TABLE(sys_setfsgid16, sys_setfsgid16, 139, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_flock
++TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 143, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_msync
++TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 144, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getsid
++TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 147, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fdatasync
++TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 148, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mlock
++TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 150, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_munlock
++TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 151, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mlockall
++TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 152, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_getscheduler
++TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 157, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_get_priority_max
++TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 159, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_get_priority_min
++TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 160, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mremap
++TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 163, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setresuid16
++TRACE_SYSCALL_TABLE(sys_setresuid16, sys_setresuid16, 164, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setresgid16
++TRACE_SYSCALL_TABLE(sys_setresgid16, sys_setresgid16, 170, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_prctl
++TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 172, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mmap_pgoff
++TRACE_SYSCALL_TABLE(sys_mmap_pgoff, sys_mmap_pgoff, 192, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setreuid
++TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 203, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setregid
++TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 204, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchown
++TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 207, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setresuid
++TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 208, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setresgid
++TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 210, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setuid
++TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 213, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setgid
++TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 214, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setfsuid
++TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 215, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setfsgid
++TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 216, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_madvise
++TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 219, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fcntl64
++TRACE_SYSCALL_TABLE(sys_fcntl64, sys_fcntl64, 221, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_tkill
++TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 238, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_io_destroy
++TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 246, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_exit_group
++TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 252, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_epoll_create
++TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 254, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_remap_file_pages
++TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 257, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timer_getoverrun
++TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 262, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timer_delete
++TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 263, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_tgkill
++TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 270, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_keyctl
++TRACE_SYSCALL_TABLE(sys_keyctl, sys_keyctl, 288, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ioprio_set
++TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 289, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ioprio_get
++TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 290, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_inotify_rm_watch
++TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 293, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_unshare
++TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 310, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_tee
++TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 315, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timerfd_create
++TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 322, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_eventfd
++TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 323, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_eventfd2
++TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 328, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_epoll_create1
++TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 329, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_dup3
++TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 330, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_inotify_init1
++TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 332, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fanotify_init
++TRACE_SYSCALL_TABLE(sys_fanotify_init, sys_fanotify_init, 338, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_syncfs
++TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 344, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_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..ed2cf1f
+--- /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_32_sys_getuid16
++#define OVERRIDE_32_sys_getgid16
++#define OVERRIDE_32_sys_geteuid16
++#define OVERRIDE_32_sys_getegid16
++#define OVERRIDE_32_sys_setuid16
++#define OVERRIDE_32_sys_setgid16
++#define OVERRIDE_32_sys_setfsuid16
++#define OVERRIDE_32_sys_setfsgid16
++#define OVERRIDE_32_sys_setreuid16
++#define OVERRIDE_32_sys_setregid16
++#define OVERRIDE_32_sys_fchown16
++#define OVERRIDE_32_sys_setresuid16
++#define OVERRIDE_32_sys_setresgid16
++
++#define OVERRIDE_TABLE_32_sys_getuid16
++#define OVERRIDE_TABLE_32_sys_getgid16
++#define OVERRIDE_TABLE_32_sys_geteuid16
++#define OVERRIDE_TABLE_32_sys_getegid16
++#define OVERRIDE_TABLE_32_sys_setuid16
++#define OVERRIDE_TABLE_32_sys_setgid16
++#define OVERRIDE_TABLE_32_sys_setreuid16
++#define OVERRIDE_TABLE_32_sys_setregid16
++#define OVERRIDE_TABLE_32_sys_fchown16
++#define OVERRIDE_TABLE_32_sys_setfsuid16
++#define OVERRIDE_TABLE_32_sys_setfsgid16
++#define OVERRIDE_TABLE_32_sys_setresuid16
++#define OVERRIDE_TABLE_32_sys_setresgid16
++
++#endif
++
++#ifdef CREATE_SYSCALL_TABLE
++
++#define OVERRIDE_TABLE_32_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..ec5b301
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h
+@@ -0,0 +1,2232 @@
++/* 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"
++#include "syscalls_pointers_override.h"
++
++#ifndef OVERRIDE_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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_32_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"
++#include "syscalls_pointers_override.h"
++
++#ifndef OVERRIDE_TABLE_32_sys_read
++TRACE_SYSCALL_TABLE(sys_read, sys_read, 3, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_write
++TRACE_SYSCALL_TABLE(sys_write, sys_write, 4, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_open
++TRACE_SYSCALL_TABLE(sys_open, sys_open, 5, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_waitpid
++TRACE_SYSCALL_TABLE(sys_waitpid, sys_waitpid, 7, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_creat
++TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 8, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_link
++TRACE_SYSCALL_TABLE(sys_link, sys_link, 9, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_unlink
++TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 10, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_chdir
++TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 12, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_time
++TRACE_SYSCALL_TABLE(sys_time, sys_time, 13, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mknod
++TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 14, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_chmod
++TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 15, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lchown16
++TRACE_SYSCALL_TABLE(sys_lchown16, sys_lchown16, 16, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_stat
++TRACE_SYSCALL_TABLE(sys_stat, sys_stat, 18, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mount
++TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 21, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_oldumount
++TRACE_SYSCALL_TABLE(sys_oldumount, sys_oldumount, 22, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_stime
++TRACE_SYSCALL_TABLE(sys_stime, sys_stime, 25, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fstat
++TRACE_SYSCALL_TABLE(sys_fstat, sys_fstat, 28, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_utime
++TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 30, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_access
++TRACE_SYSCALL_TABLE(sys_access, sys_access, 33, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rename
++TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 38, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mkdir
++TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 39, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rmdir
++TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 40, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pipe
++TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 42, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_times
++TRACE_SYSCALL_TABLE(sys_times, sys_times, 43, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_acct
++TRACE_SYSCALL_TABLE(sys_acct, sys_acct, 51, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_umount
++TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 52, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_olduname
++TRACE_SYSCALL_TABLE(sys_olduname, sys_olduname, 59, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_chroot
++TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 61, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ustat
++TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 62, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sigpending
++TRACE_SYSCALL_TABLE(sys_sigpending, sys_sigpending, 73, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sethostname
++TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 74, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setrlimit
++TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 75, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_old_getrlimit
++TRACE_SYSCALL_TABLE(sys_old_getrlimit, sys_old_getrlimit, 76, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getrusage
++TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 77, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_gettimeofday
++TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 78, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_settimeofday
++TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 79, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getgroups16
++TRACE_SYSCALL_TABLE(sys_getgroups16, sys_getgroups16, 80, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setgroups16
++TRACE_SYSCALL_TABLE(sys_setgroups16, sys_setgroups16, 81, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_old_select
++TRACE_SYSCALL_TABLE(sys_old_select, sys_old_select, 82, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_symlink
++TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 83, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lstat
++TRACE_SYSCALL_TABLE(sys_lstat, sys_lstat, 84, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_readlink
++TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 85, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_uselib
++TRACE_SYSCALL_TABLE(sys_uselib, sys_uselib, 86, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_swapon
++TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 87, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_reboot
++TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 88, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_old_readdir
++TRACE_SYSCALL_TABLE(sys_old_readdir, sys_old_readdir, 89, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_old_mmap
++TRACE_SYSCALL_TABLE(sys_old_mmap, sys_old_mmap, 90, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_truncate
++TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 92, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_statfs
++TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 99, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fstatfs
++TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 100, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_socketcall
++TRACE_SYSCALL_TABLE(sys_socketcall, sys_socketcall, 102, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_syslog
++TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setitimer
++TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 104, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getitimer
++TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 105, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_newstat
++TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 106, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_newlstat
++TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 107, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_newfstat
++TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 108, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_uname
++TRACE_SYSCALL_TABLE(sys_uname, sys_uname, 109, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_wait4
++TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 114, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_swapoff
++TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 115, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sysinfo
++TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 116, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ipc
++TRACE_SYSCALL_TABLE(sys_ipc, sys_ipc, 117, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setdomainname
++TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 121, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_newuname
++TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 122, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_adjtimex
++TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 124, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sigprocmask
++TRACE_SYSCALL_TABLE(sys_sigprocmask, sys_sigprocmask, 126, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_init_module
++TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 128, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_delete_module
++TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 129, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_quotactl
++TRACE_SYSCALL_TABLE(sys_quotactl, sys_quotactl, 131, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_llseek
++TRACE_SYSCALL_TABLE(sys_llseek, sys_llseek, 140, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getdents
++TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 141, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_select
++TRACE_SYSCALL_TABLE(sys_select, sys_select, 142, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_readv
++TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 145, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_writev
++TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 146, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sysctl
++TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 149, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_setparam
++TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 154, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_getparam
++TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 155, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_setscheduler
++TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 156, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_rr_get_interval
++TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 161, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_nanosleep
++TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 162, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getresuid16
++TRACE_SYSCALL_TABLE(sys_getresuid16, sys_getresuid16, 165, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_poll
++TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 168, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getresgid16
++TRACE_SYSCALL_TABLE(sys_getresgid16, sys_getresgid16, 171, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigaction
++TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 174, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigprocmask
++TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 175, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigpending
++TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 176, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigtimedwait
++TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 177, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigqueueinfo
++TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 178, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_sigsuspend
++TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 179, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_chown16
++TRACE_SYSCALL_TABLE(sys_chown16, sys_chown16, 182, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getcwd
++TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 183, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sendfile
++TRACE_SYSCALL_TABLE(sys_sendfile, sys_sendfile, 187, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getrlimit
++TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 191, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_stat64
++TRACE_SYSCALL_TABLE(sys_stat64, sys_stat64, 195, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lstat64
++TRACE_SYSCALL_TABLE(sys_lstat64, sys_lstat64, 196, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fstat64
++TRACE_SYSCALL_TABLE(sys_fstat64, sys_fstat64, 197, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lchown
++TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 198, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getgroups
++TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 205, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setgroups
++TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 206, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getresuid
++TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 209, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getresgid
++TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 211, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_chown
++TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 212, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pivot_root
++TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 217, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mincore
++TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 218, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getdents64
++TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 220, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_setxattr
++TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 226, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lsetxattr
++TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 227, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fsetxattr
++TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 228, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getxattr
++TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 229, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lgetxattr
++TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 230, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fgetxattr
++TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 231, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_listxattr
++TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 232, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_llistxattr
++TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 233, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_flistxattr
++TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 234, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_removexattr
++TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 235, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_lremovexattr
++TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 236, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fremovexattr
++TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 237, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sendfile64
++TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 239, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_futex
++TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 240, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_setaffinity
++TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 241, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_sched_getaffinity
++TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 242, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_io_setup
++TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 245, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_io_getevents
++TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 247, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_io_submit
++TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 248, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_io_cancel
++TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 249, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_epoll_ctl
++TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 255, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_epoll_wait
++TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 256, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_set_tid_address
++TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 258, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timer_create
++TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 259, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timer_settime
++TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 260, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timer_gettime
++TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 261, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_clock_settime
++TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 264, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_clock_gettime
++TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 265, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_clock_getres
++TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 266, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_clock_nanosleep
++TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 267, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_statfs64
++TRACE_SYSCALL_TABLE(sys_statfs64, sys_statfs64, 268, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fstatfs64
++TRACE_SYSCALL_TABLE(sys_fstatfs64, sys_fstatfs64, 269, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_utimes
++TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 271, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_open
++TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 277, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_unlink
++TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 278, 1)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_timedsend
++TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 279, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_timedreceive
++TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 280, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_notify
++TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 281, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mq_getsetattr
++TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 282, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_kexec_load
++TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 283, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_waitid
++TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 284, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_add_key
++TRACE_SYSCALL_TABLE(sys_add_key, sys_add_key, 286, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_request_key
++TRACE_SYSCALL_TABLE(sys_request_key, sys_request_key, 287, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_inotify_add_watch
++TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 292, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_openat
++TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 295, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mkdirat
++TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 296, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_mknodat
++TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 297, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchownat
++TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 298, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_futimesat
++TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 299, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fstatat64
++TRACE_SYSCALL_TABLE(sys_fstatat64, sys_fstatat64, 300, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_unlinkat
++TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 301, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_renameat
++TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 302, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_linkat
++TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 303, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_symlinkat
++TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 304, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_readlinkat
++TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 305, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_fchmodat
++TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 306, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_faccessat
++TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 307, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pselect6
++TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 308, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_ppoll
++TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 309, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_set_robust_list
++TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 311, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_get_robust_list
++TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 312, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_splice
++TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 313, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_vmsplice
++TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 316, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_getcpu
++TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 318, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_epoll_pwait
++TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 319, 6)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_utimensat
++TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 320, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_signalfd
++TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 321, 3)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timerfd_settime
++TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 325, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_timerfd_gettime
++TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 326, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_signalfd4
++TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 327, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pipe2
++TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 331, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_preadv
++TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 333, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_pwritev
++TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 334, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_rt_tgsigqueueinfo
++TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 335, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_perf_event_open
++TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 336, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_recvmmsg
++TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 337, 5)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_prlimit64
++TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 340, 4)
++#endif
++#ifndef OVERRIDE_TABLE_32_sys_clock_adjtime
++TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 343, 2)
++#endif
++#ifndef OVERRIDE_TABLE_32_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..d35657c
+--- /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_32_sys_getgroups16
++#define OVERRIDE_32_sys_setgroups16
++#define OVERRIDE_32_sys_lchown16
++#define OVERRIDE_32_sys_getresuid16
++#define OVERRIDE_32_sys_getresgid16
++#define OVERRIDE_32_sys_chown16
++
++#define OVERRIDE_TABLE_32_sys_getgroups16
++#define OVERRIDE_TABLE_32_sys_setgroups16
++#define OVERRIDE_TABLE_32_sys_lchown16
++#define OVERRIDE_TABLE_32_sys_getresuid16
++#define OVERRIDE_TABLE_32_sys_getresgid16
++#define OVERRIDE_TABLE_32_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..6d0dbb9
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h
+@@ -0,0 +1,1013 @@
++/* 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"
++#include "syscalls_integers_override.h"
++
++SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,
++      TP_STRUCT__entry(),
++      TP_fast_assign(),
++      TP_printk()
++)
++#ifndef OVERRIDE_64_sys_sched_yield
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield)
++#endif
++#ifndef OVERRIDE_64_sys_pause
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause)
++#endif
++#ifndef OVERRIDE_64_sys_getpid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid)
++#endif
++#ifndef OVERRIDE_64_sys_getuid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid)
++#endif
++#ifndef OVERRIDE_64_sys_getgid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid)
++#endif
++#ifndef OVERRIDE_64_sys_geteuid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid)
++#endif
++#ifndef OVERRIDE_64_sys_getegid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid)
++#endif
++#ifndef OVERRIDE_64_sys_getppid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid)
++#endif
++#ifndef OVERRIDE_64_sys_getpgrp
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp)
++#endif
++#ifndef OVERRIDE_64_sys_setsid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid)
++#endif
++#ifndef OVERRIDE_64_sys_munlockall
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall)
++#endif
++#ifndef OVERRIDE_64_sys_vhangup
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup)
++#endif
++#ifndef OVERRIDE_64_sys_sync
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync)
++#endif
++#ifndef OVERRIDE_64_sys_gettid
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid)
++#endif
++#ifndef OVERRIDE_64_sys_restart_syscall
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall)
++#endif
++#ifndef OVERRIDE_64_sys_inotify_init
++SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init)
++#endif
++#ifndef OVERRIDE_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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"
++#include "syscalls_integers_override.h"
++
++#ifndef OVERRIDE_TABLE_64_sys_sched_yield
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 24, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pause
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 34, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getpid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 39, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getuid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 102, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getgid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 104, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_geteuid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 107, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getegid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 108, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getppid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 110, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getpgrp
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 111, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setsid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 112, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_munlockall
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 152, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_vhangup
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 153, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sync
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 162, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_gettid
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 186, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_restart_syscall
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 219, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_inotify_init
++TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 253, 0)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_close
++TRACE_SYSCALL_TABLE(sys_close, sys_close, 3, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_lseek
++TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 8, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mmap
++TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 9, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mprotect
++TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 10, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_munmap
++TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 11, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_brk
++TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 12, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ioctl
++TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 16, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mremap
++TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 25, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_msync
++TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 26, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_madvise
++TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 28, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_shmget
++TRACE_SYSCALL_TABLE(sys_shmget, sys_shmget, 29, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_dup
++TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 32, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_dup2
++TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 33, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_alarm
++TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 37, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_socket
++TRACE_SYSCALL_TABLE(sys_socket, sys_socket, 41, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_shutdown
++TRACE_SYSCALL_TABLE(sys_shutdown, sys_shutdown, 48, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_listen
++TRACE_SYSCALL_TABLE(sys_listen, sys_listen, 50, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_exit
++TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 60, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_kill
++TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 62, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_semget
++TRACE_SYSCALL_TABLE(sys_semget, sys_semget, 64, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_msgget
++TRACE_SYSCALL_TABLE(sys_msgget, sys_msgget, 68, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fcntl
++TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 72, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_flock
++TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 73, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fsync
++TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 74, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fdatasync
++TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 75, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ftruncate
++TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 77, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fchdir
++TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 81, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fchmod
++TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 91, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fchown
++TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 93, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_umask
++TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 95, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ptrace
++TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 101, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setuid
++TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 105, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setgid
++TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 106, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setpgid
++TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 109, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setreuid
++TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 113, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setregid
++TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 114, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setresuid
++TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 117, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setresgid
++TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 119, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getpgid
++TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 121, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setfsuid
++TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 122, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setfsgid
++TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 123, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getsid
++TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 124, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_personality
++TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 135, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sysfs
++TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 139, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getpriority
++TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 140, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setpriority
++TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 141, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_getscheduler
++TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 145, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_max
++TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 146, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_min
++TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 147, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mlock
++TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 149, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_munlock
++TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 150, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mlockall
++TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 151, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_prctl
++TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 157, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_tkill
++TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 200, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_io_destroy
++TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 207, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_epoll_create
++TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 213, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_remap_file_pages
++TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 216, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timer_getoverrun
++TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 225, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timer_delete
++TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 226, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_exit_group
++TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 231, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_tgkill
++TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 234, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ioprio_set
++TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 251, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ioprio_get
++TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 252, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_inotify_rm_watch
++TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 255, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_unshare
++TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 272, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_tee
++TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 276, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timerfd_create
++TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 283, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_eventfd
++TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 284, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_eventfd2
++TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 290, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_epoll_create1
++TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 291, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_dup3
++TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 292, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_inotify_init1
++TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 294, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_syncfs
++TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 306, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_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..3d400f7
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h
+@@ -0,0 +1,3 @@
++/*
++ * this is a place-holder for x86_64 interger syscall definition override.
++ */
+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..e926a60
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h
+@@ -0,0 +1,2076 @@
++/* 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"
++#include "syscalls_pointers_override.h"
++
++#ifndef OVERRIDE_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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_64_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"
++#include "syscalls_pointers_override.h"
++
++#ifndef OVERRIDE_TABLE_64_sys_read
++TRACE_SYSCALL_TABLE(sys_read, sys_read, 0, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_write
++TRACE_SYSCALL_TABLE(sys_write, sys_write, 1, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_open
++TRACE_SYSCALL_TABLE(sys_open, sys_open, 2, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_newstat
++TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 4, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_newfstat
++TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 5, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_newlstat
++TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 6, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_poll
++TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 7, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigaction
++TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 13, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigprocmask
++TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 14, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_readv
++TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 19, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_writev
++TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 20, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_access
++TRACE_SYSCALL_TABLE(sys_access, sys_access, 21, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pipe
++TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 22, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_select
++TRACE_SYSCALL_TABLE(sys_select, sys_select, 23, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mincore
++TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 27, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_shmat
++TRACE_SYSCALL_TABLE(sys_shmat, sys_shmat, 30, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_shmctl
++TRACE_SYSCALL_TABLE(sys_shmctl, sys_shmctl, 31, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_nanosleep
++TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 35, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getitimer
++TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 36, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setitimer
++TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 38, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sendfile64
++TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 40, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_connect
++TRACE_SYSCALL_TABLE(sys_connect, sys_connect, 42, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_accept
++TRACE_SYSCALL_TABLE(sys_accept, sys_accept, 43, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sendto
++TRACE_SYSCALL_TABLE(sys_sendto, sys_sendto, 44, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_recvfrom
++TRACE_SYSCALL_TABLE(sys_recvfrom, sys_recvfrom, 45, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sendmsg
++TRACE_SYSCALL_TABLE(sys_sendmsg, sys_sendmsg, 46, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_recvmsg
++TRACE_SYSCALL_TABLE(sys_recvmsg, sys_recvmsg, 47, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_bind
++TRACE_SYSCALL_TABLE(sys_bind, sys_bind, 49, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getsockname
++TRACE_SYSCALL_TABLE(sys_getsockname, sys_getsockname, 51, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getpeername
++TRACE_SYSCALL_TABLE(sys_getpeername, sys_getpeername, 52, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_socketpair
++TRACE_SYSCALL_TABLE(sys_socketpair, sys_socketpair, 53, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setsockopt
++TRACE_SYSCALL_TABLE(sys_setsockopt, sys_setsockopt, 54, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getsockopt
++TRACE_SYSCALL_TABLE(sys_getsockopt, sys_getsockopt, 55, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_wait4
++TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 61, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_newuname
++TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 63, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_semop
++TRACE_SYSCALL_TABLE(sys_semop, sys_semop, 65, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_shmdt
++TRACE_SYSCALL_TABLE(sys_shmdt, sys_shmdt, 67, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_msgsnd
++TRACE_SYSCALL_TABLE(sys_msgsnd, sys_msgsnd, 69, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_msgrcv
++TRACE_SYSCALL_TABLE(sys_msgrcv, sys_msgrcv, 70, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_msgctl
++TRACE_SYSCALL_TABLE(sys_msgctl, sys_msgctl, 71, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_truncate
++TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 76, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getdents
++TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 78, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getcwd
++TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 79, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_chdir
++TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 80, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rename
++TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 82, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mkdir
++TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 83, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rmdir
++TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 84, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_creat
++TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 85, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_link
++TRACE_SYSCALL_TABLE(sys_link, sys_link, 86, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_unlink
++TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 87, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_symlink
++TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 88, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_readlink
++TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 89, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_chmod
++TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 90, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_chown
++TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 92, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_lchown
++TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 94, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_gettimeofday
++TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 96, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getrlimit
++TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 97, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getrusage
++TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 98, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sysinfo
++TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 99, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_times
++TRACE_SYSCALL_TABLE(sys_times, sys_times, 100, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_syslog
++TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getgroups
++TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 115, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setgroups
++TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 116, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getresuid
++TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 118, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getresgid
++TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 120, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigpending
++TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 127, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigtimedwait
++TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 128, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigqueueinfo
++TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 129, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_sigsuspend
++TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 130, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_utime
++TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 132, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mknod
++TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 133, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ustat
++TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 136, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_statfs
++TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 137, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fstatfs
++TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 138, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_setparam
++TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 142, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_getparam
++TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 143, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_setscheduler
++TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 144, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_rr_get_interval
++TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 148, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pivot_root
++TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 155, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sysctl
++TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 156, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_adjtimex
++TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 159, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setrlimit
++TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 160, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_chroot
++TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 161, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_settimeofday
++TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 164, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mount
++TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 165, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_umount
++TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 166, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_swapon
++TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 167, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_swapoff
++TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 168, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_reboot
++TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 169, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sethostname
++TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 170, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setdomainname
++TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 171, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_init_module
++TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 175, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_delete_module
++TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 176, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_nfsservctl
++TRACE_SYSCALL_TABLE(sys_nfsservctl, sys_nfsservctl, 180, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_setxattr
++TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 188, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_lsetxattr
++TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 189, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fsetxattr
++TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 190, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getxattr
++TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 191, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_lgetxattr
++TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 192, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fgetxattr
++TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 193, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_listxattr
++TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 194, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_llistxattr
++TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 195, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_flistxattr
++TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 196, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_removexattr
++TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 197, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_lremovexattr
++TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 198, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fremovexattr
++TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 199, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_time
++TRACE_SYSCALL_TABLE(sys_time, sys_time, 201, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_futex
++TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 202, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_setaffinity
++TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 203, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_sched_getaffinity
++TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 204, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_io_setup
++TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 206, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_io_getevents
++TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 208, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_io_submit
++TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 209, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_io_cancel
++TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 210, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_getdents64
++TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 217, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_set_tid_address
++TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 218, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_semtimedop
++TRACE_SYSCALL_TABLE(sys_semtimedop, sys_semtimedop, 220, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timer_create
++TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 222, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timer_settime
++TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 223, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timer_gettime
++TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 224, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_clock_settime
++TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 227, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_clock_gettime
++TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 228, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_clock_getres
++TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 229, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_clock_nanosleep
++TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 230, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_epoll_wait
++TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 232, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_epoll_ctl
++TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 233, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_utimes
++TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 235, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_open
++TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 240, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_unlink
++TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 241, 1)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_timedsend
++TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 242, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_timedreceive
++TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 243, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_notify
++TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 244, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mq_getsetattr
++TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 245, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_kexec_load
++TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 246, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_waitid
++TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 247, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_inotify_add_watch
++TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 254, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_openat
++TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 257, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mkdirat
++TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 258, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_mknodat
++TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 259, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fchownat
++TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 260, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_futimesat
++TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 261, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_newfstatat
++TRACE_SYSCALL_TABLE(sys_newfstatat, sys_newfstatat, 262, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_unlinkat
++TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 263, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_renameat
++TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 264, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_linkat
++TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 265, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_symlinkat
++TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 266, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_readlinkat
++TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 267, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_fchmodat
++TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 268, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_faccessat
++TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 269, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pselect6
++TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 270, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_ppoll
++TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 271, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_set_robust_list
++TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 273, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_get_robust_list
++TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 274, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_splice
++TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 275, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_vmsplice
++TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 278, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_utimensat
++TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 280, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_epoll_pwait
++TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 281, 6)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_signalfd
++TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 282, 3)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timerfd_settime
++TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 286, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_timerfd_gettime
++TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 287, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_accept4
++TRACE_SYSCALL_TABLE(sys_accept4, sys_accept4, 288, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_signalfd4
++TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 289, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pipe2
++TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 293, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_preadv
++TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 295, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_pwritev
++TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 296, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_rt_tgsigqueueinfo
++TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 297, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_perf_event_open
++TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 298, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_recvmmsg
++TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 299, 5)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_prlimit64
++TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 302, 4)
++#endif
++#ifndef OVERRIDE_TABLE_64_sys_clock_adjtime
++TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 305, 2)
++#endif
++#ifndef OVERRIDE_TABLE_64_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@efficios.com>
++ * Copyright 2011 - Julien Desfossez <julien.desfossez@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..5eddb27
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh
+@@ -0,0 +1,275 @@
++#!/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 64
++# lttng-syscalls-generate-headers.sh pointers 3.0.4 x86-64-syscalls-3.0.4 64
++
++CLASS=$1
++INPUTDIR=$2
++INPUTFILE=$3
++BITNESS=$4
++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\"
++#include \"syscalls_${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_'"${BITNESS}"'_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_'"${BITNESS}"'_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_'"${BITNESS}"'_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_'"${BITNESS}"'_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_'"${BITNESS}"'_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_'"${BITNESS}"'_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_'"${BITNESS}"'_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\"
++#include \"syscalls_${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_'"${BITNESS}"'_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_'"${BITNESS}"'_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.9
+
diff --git a/patches.lttng/0009-lttng-lib-ring-buffer-clients.patch b/patches.lttng/0009-lttng-lib-ring-buffer-clients.patch
new file mode 100644 (file)
index 0000000..3982646
--- /dev/null
@@ -0,0 +1,1106 @@
+From 6857797120e99facc465a972026038199e4c2356 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:17 -0500
+Subject: lttng: lib ring buffer clients
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../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@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@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@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@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@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@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@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@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.9
+
diff --git a/patches.lttng/0010-lttng-tracer-control-and-core-structures.patch b/patches.lttng/0010-lttng-tracer-control-and-core-structures.patch
new file mode 100644 (file)
index 0000000..7c3541e
--- /dev/null
@@ -0,0 +1,1812 @@
+From ccc7340a9415839763e872bceb626638c58174a1 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:18 -0500
+Subject: lttng: tracer control and core structures
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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@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@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@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@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@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@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.9
+
diff --git a/patches.lttng/0011-lttng-dynamically-selectable-context-information.patch b/patches.lttng/0011-lttng-dynamically-selectable-context-information.patch
new file mode 100644 (file)
index 0000000..e10ed06
--- /dev/null
@@ -0,0 +1,1131 @@
+From 6c19da3578bc0ae0d3a65560b7ac7963a35ea79c Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:19 -0500
+Subject: lttng: dynamically selectable context information
+
+Events can be augmented with context information. This is dynamically
+configurable from the command line.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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@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@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@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@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@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@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@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@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@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@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.9
+
diff --git a/patches.lttng/0012-lttng-timing-calibration-feature.patch b/patches.lttng/0012-lttng-timing-calibration-feature.patch
new file mode 100644 (file)
index 0000000..7dffaf9
--- /dev/null
@@ -0,0 +1,54 @@
+From da66e4e541b21b326a26a36de42f400975da60ac Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:20 -0500
+Subject: lttng: timing calibration feature
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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.9
+
diff --git a/patches.lttng/0013-lttng-debugfs-and-procfs-ABI.patch b/patches.lttng/0013-lttng-debugfs-and-procfs-ABI.patch
new file mode 100644 (file)
index 0000000..9142942
--- /dev/null
@@ -0,0 +1,965 @@
+From c623c0a3493e87ba60a07eef89dc78274d2e1f4a Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:21 -0500
+Subject: lttng: debugfs and procfs ABI
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@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@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.9
+
diff --git a/patches.lttng/0014-lttng-Add-documentation-and-TODO-files.patch b/patches.lttng/0014-lttng-Add-documentation-and-TODO-files.patch
new file mode 100644 (file)
index 0000000..1d3c7fe
--- /dev/null
@@ -0,0 +1,249 @@
+From 18b2248a0dcc70284d68ecd095cd2e8451714966 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:22 -0500
+Subject: lttng: Add documentation and TODO files
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/LICENSE |   27 ++++++++
+ drivers/staging/lttng/README  |   48 ++++++++++++++
+ drivers/staging/lttng/TODO    |  137 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 212 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/staging/lttng/LICENSE
+ create mode 100644 drivers/staging/lttng/README
+ create mode 100644 drivers/staging/lttng/TODO
+
+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..a154d6e
+--- /dev/null
++++ b/drivers/staging/lttng/README
+@@ -0,0 +1,48 @@
++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 now ready to be used, but still only available from the
++git repository.
++
++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/TODO b/drivers/staging/lttng/TODO
+new file mode 100644
+index 0000000..3fdc5e6
+--- /dev/null
++++ b/drivers/staging/lttng/TODO
+@@ -0,0 +1,137 @@
++Please contact Mathieu Desnoyers <mathieu.desnoyers@efficios.com> for
++questions about this TODO list. The "Cleanup/Testing" section would be
++good to go through before integration into mainline. The "Features"
++section is a wish list of features to complete before releasing the
++"LTTng 2.0" final version, but are not required to have LTTng working.
++These features are mostly performance enhancements and instrumentation
++enhancements.
++
++TODO:
++
++A) Cleanup/Testing
++
++      1) Remove debugfs "lttng" file (keep only procfs "lttng" file).
++         The rationale for this is that this file is needed for
++         user-level tracing support (LTTng-UST 2.0) intended to be
++         used on production system, and therefore should be present as
++         part of a "usually mounted" filesystem rather than a debug
++         filesystem.
++
++      2) Cleanup wrappers. The drivers/staging/lttng/wrapper directory
++         contains various wrapper headers that use kallsyms lookups to
++         work around some missing EXPORT_SYMBOL_GPL() in the mainline
++         kernel. Ideally, those few symbols should become exported to
++         modules by the kernel.
++
++      3) Test lib ring buffer snapshot feature.
++         When working on the lttngtop project, Julien Desfossez
++         reported that he needed to push the consumer position
++         forward explicitely with lib_ring_buffer_put_next_subbuf.
++         This means that although the usual case of pairs of
++         lib_ring_buffer_get_next_subbuf/lib_ring_buffer_put_next_subbuf
++         work fine, there is probably a problem that needs to be
++         investigated in
++         lib_ring_buffer_get_subbuf/lib_ring_buffer_put_subbuf, which
++         depend on the producer to push the reader position.
++         Contact: Julien Desfossez <julien.desfossez@polymtl.ca>
++
++      4) Test latest -rt kernel support.
++         There has been report of corrupted traces when tracing a
++         3.0.10-rt27 in the area of access_ok() system call event.
++         Still has to be investigated. Cannot be reproduced with
++         mainline kernel.
++         Contact: Yannick Brosseau <yannick.brosseau@polymtl.ca>
++
++B) Features
++
++      1) Integration of the LTTng 0.x trace clocks into
++         LTTng 2.0.
++           Currently using mainline kernel monotonic clock. NMIs can
++           therefore not be traced, and this causes a significant
++           performance degradation compared to the LTTng 0.x trace
++           clocks. Imply the creation of drivers/staging/lttng/arch to
++           contain the arch-specific clock support files.
++           * Dependency: addition of clock descriptions to CTF.
++         See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary
++              for the LTTng 0.x git tree.
++
++      2) Port OMAP3 LTTng trace clocks to x86 to support systems
++         without constant TSC.
++          * Dependency: (B.1)
++         See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary
++              for the LTTng 0.x git tree.
++
++      3) Implement mmap operation on an anonymous file created by a
++         LTTNG_KERNEL_CLOCK ioctl to export data to export
++         synchronized kernel and user-level LTTng trace clocks:
++         with:
++            - shared per-cpu data,
++            - read seqlock.
++         The content exported by this shared memory area will be
++         arch-specific.
++         * Dependency: (B.1) && (B.2)
++         See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary
++              for the LTTng 0.x git tree, which has vDSO support for
++              LTTng trace clock on the x86 architecture.
++
++      3) Integrate the "statedump" module from LTTng 0.x into LTTng
++         2.0.
++           * Dependency: addition of "dynamic enumerations" type to CTF.
++         See: http://git.lttng.org/?p=lttng-modules.git;a=shortlog;h=refs/heads/v0.19-stable
++              ltt-statedump.c
++
++      4) Generate system call TRACE_EVENT headers for all
++         architectures (currently done: x86 32/64).
++
++      5) Define "unknown" system calls into instrumentation/syscalls
++         override files / or do SYSCALL_DEFINE improvements to
++         mainline kernel to allow automatic generation of these
++         missing system call descriptions.
++
++      6) Create missing tracepoint event headers files into
++         instrumentation/events from headers located in
++         include/trace/events/. Choice: either do as currently done,
++         and copy those headers locally into the lttng driver and
++         perform the modifications locally, or push TRACE_EVENT API
++         modification into mainline headers, which would require
++         collaboration from Ftrace/Perf maintainers.
++
++      7) Poll: implement a poll and/or epoll exclusive wakeup scheme,
++         which contradicts POSIX, but protect multiple consumer
++         threads from thundering herd effect.
++
++      8) Re-integrate sample modules from libringbuffer into
++         lttng driver. Those modules can be used as example of how to
++         use libringbuffer in other contexts than LTTng, and are
++         useful to perform benchmarks of the ringbuffer library.
++         See: http://www.efficios.com/ringbuffer
++
++      9) NOHZ support for lib ring buffer. NOHZ infrastructure in the
++         Linux kernel does not support notifiers chains, which does
++         not let LTTng play nicely with low power consumption setups
++         for flight recorder (overwrite mode) live traces. One way to
++         allow integration between NOHZ and LTTng would be to add
++         support for such notifiers into NOHZ kernel infrastructure.
++
++      10) Turn drivers/staging/lttng/ltt-probes.c probe_list into a
++          hash table. Turns O(n^2) trace systems registration (cost
++          for n systems) into O(n). (O(1) per system)
++
++      11) drivers/staging/lttng/probes/lttng-ftrace.c:
++          LTTng currently uses kretprobes for per-function tracing,
++          not the function tracer. So lttng-ftrace.c should be used
++          for "all" function tracing.
++
++      12) drivers/staging/lttng/probes/lttng-types.c:
++          This is a currently unused placeholder to export entire C
++          type declarations into the trace metadata, e.g. for support
++          of describing the layout of structures/enumeration mapping
++          along with syscall entry events.  The design of this support
++          will likely change though, and become integrated with the
++          TRACE_EVENT support within lttng, by adding new macros, and
++          support for generation of metadata from these macros, to
++          allow description of those compound types/enumerations.
++
++Please send patches
++To: Greg Kroah-Hartman <greg@kroah.com>
++To: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+-- 
+1.7.9
+
diff --git a/patches.lttng/0015-lttng-add-system-call-instrumentation-probe.patch b/patches.lttng/0015-lttng-add-system-call-instrumentation-probe.patch
new file mode 100644 (file)
index 0000000..f38581e
--- /dev/null
@@ -0,0 +1,459 @@
+From 97104e24fbefa7081e4c9aa9bff3c4fa1a0212cf Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:23 -0500
+Subject: lttng: add system call instrumentation probe
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/lttng-syscalls.c |  438 ++++++++++++++++++++++++++++++++
+ 1 files changed, 438 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..16624a7f7
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-syscalls.c
+@@ -0,0 +1,438 @@
++/*
++ * lttng-syscalls.c
++ *
++ * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@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
++
++#undef TRACE_SYSTEM
++
++/* 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)
++#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.9
+
diff --git a/patches.lttng/0016-lttng-probe-callbacks.patch b/patches.lttng/0016-lttng-probe-callbacks.patch
new file mode 100644 (file)
index 0000000..60ce75c
--- /dev/null
@@ -0,0 +1,2035 @@
+From 1e8ab70d74ed14bc287e2cb98145e860e2d95f6e Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:24 -0500
+Subject: lttng: probe callbacks
+
+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@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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@goodmis.org>
++ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@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@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@goodmis.org>
++ * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@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@efficios.com>
++ *
++ * Dual LGPL v2.1/GPL v2 license.
++ */
++
++#undef PARAMS
++#define PARAMS(args...)               args
++
++#endif /* _LTTNG_PROBES_LTTNG_H */
+-- 
+1.7.9
+
diff --git a/patches.lttng/0017-lttng-toplevel-Makefile-and-Kconfig.patch b/patches.lttng/0017-lttng-toplevel-Makefile-and-Kconfig.patch
new file mode 100644 (file)
index 0000000..aad46b0
--- /dev/null
@@ -0,0 +1,97 @@
+From 3c46c44027a86fc8a008a6096b0e5b8f5a4afcb5 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:25 -0500
+Subject: lttng: toplevel Makefile and Kconfig
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ 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.9
+
diff --git a/patches.lttng/0018-staging-add-LTTng-to-build.patch b/patches.lttng/0018-staging-add-LTTng-to-build.patch
new file mode 100644 (file)
index 0000000..11da1a2
--- /dev/null
@@ -0,0 +1,33 @@
+From 9b6d12198448aa51979b81aa68651cb49c0c5a02 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:26 -0500
+Subject: staging: add LTTng to build
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/Kconfig  |    2 ++
+ drivers/staging/Makefile |    1 +
+ 2 files changed, 3 insertions(+)
+
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -78,6 +78,8 @@ source "drivers/staging/line6/Kconfig"
+ source "drivers/gpu/drm/vmwgfx/Kconfig"
++source "drivers/staging/lttng/Kconfig"
++
+ source "drivers/gpu/drm/nouveau/Kconfig"
+ source "drivers/staging/octeon/Kconfig"
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -32,6 +32,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/
diff --git a/patches.lttng/0019-staging-Add-LTTng-entry-to-MAINTAINERS-file.patch b/patches.lttng/0019-staging-Add-LTTng-entry-to-MAINTAINERS-file.patch
new file mode 100644 (file)
index 0000000..23ee572
--- /dev/null
@@ -0,0 +1,27 @@
+From 70bd4399bbdd4dd35697664af00fcd48cb2008a2 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 28 Nov 2011 07:42:27 -0500
+Subject: staging: Add LTTng entry to MAINTAINERS file
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ MAINTAINERS |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4022,6 +4022,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@efficios.com>
++L:    lttng-dev@lists.lttng.org (moderated for non-subscribers)
++W:    http://lttng.org
++S:    Maintained
++F:    drivers/staging/lttng/
++
+ M32R ARCHITECTURE
+ M:    Hirokazu Takata <takata@linux-m32r.org>
+ L:    linux-m32r@ml.linux-m32r.org
diff --git a/patches.lttng/0069-lttng-lib-ring-buffer-remove-stale-null-pointer.patch b/patches.lttng/0069-lttng-lib-ring-buffer-remove-stale-null-pointer.patch
new file mode 100644 (file)
index 0000000..bb268ac
--- /dev/null
@@ -0,0 +1,63 @@
+From 2f8e0b31ad257bca9ff5dda9fdfdcc98d38d97f8 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Wed, 30 Nov 2011 13:34:14 -0500
+Subject: lttng lib: ring buffer: remove stale null-pointer
+
+* Dan Carpenter <dan.carpenter@oracle.com> wrote:
+[...]
+> The patch c844b2f5cfea: "lttng lib: ring buffer" from Nov 28, 2011,
+> leads to the following Smatch complaint:
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c +1150
+> +lib_ring_buffer_print_buffer_errors()
+>          warn: variable dereferenced before check 'chan' (see line 1143)
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+>   1142  {
+>   1143          const struct lib_ring_buffer_config *config =
+> +chan->backend.config;
+>
+> +^^^^^^^^^^^^^^^^^^^^
+> Dereference.
+>
+>   1144          unsigned long write_offset, cons_offset;
+>   1145
+>   1146          /*
+>   1147           * Can be called in the error path of allocation when
+>   1148           * trans_channel_data is not yet set.
+>   1149           */
+>   1150          if (!chan)
+>                 ^^^^^^^^^
+> Check.  At first glance the comment seems out of date, I think check can
+> be removed safely.
+>
+>   1151                  return;
+>   1152          /*
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../lttng/lib/ringbuffer/ring_buffer_frontend.c    |    6 ------
+ 1 files changed, 0 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+index 802f5cd..957d7f3 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+@@ -1144,12 +1144,6 @@ void lib_ring_buffer_print_buffer_errors(struct lib_ring_buffer *buf,
+       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.
+-- 
+1.7.9
+
diff --git a/patches.lttng/0070-lttng-lib-ring-buffer-remove-duplicate-null-pointer.patch b/patches.lttng/0070-lttng-lib-ring-buffer-remove-duplicate-null-pointer.patch
new file mode 100644 (file)
index 0000000..dccc660
--- /dev/null
@@ -0,0 +1,60 @@
+From e5f7787388da7562b955a36b46e909e500a5974b Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Wed, 30 Nov 2011 13:34:15 -0500
+Subject: lttng lib: ring buffer remove duplicate null pointer
+
+* Dan Carpenter <dan.carpenter@oracle.com> wrote:
+> The patch c844b2f5cfea: "lttng lib: ring buffer" from Nov 28, 2011,
+> leads to the following Smatch complaint:
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c +33
+> +lib_ring_buffer_fault()
+>          warn: variable dereferenced before check 'buf' (see line 26)
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+>     25          struct lib_ring_buffer *buf = vma->vm_private_data;
+>     26          struct channel *chan = buf->backend.chan;
+>                                        ^^^^^^^^^^^^^^^^^
+> Dereference.
+>
+>     27          const struct lib_ring_buffer_config *config = chan->backend.config;
+>     28          pgoff_t pgoff = vmf->pgoff;
+>     29          struct page **page;
+>     30          void **virt;
+>     31          unsigned long offset, sb_bindex;
+>     32
+>     33          if (!buf)
+>                     ^^^^
+> Check.
+>
+>     34                  return VM_FAULT_OOM;
+>     35
+
+This check is performed at mapping setup time in
+lib_ring_buffer_mmap_buf() already, so we can safely remove this
+duplicata.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../lttng/lib/ringbuffer/ring_buffer_mmap.c        |    3 ---
+ 1 files changed, 0 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+index 68221ee..cf37434 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+@@ -30,9 +30,6 @@ static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vm
+       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.
+-- 
+1.7.9
+
diff --git a/patches.lttng/0071-lttng-lib-ring-buffer-move-null-pointer-check-to-ope.patch b/patches.lttng/0071-lttng-lib-ring-buffer-move-null-pointer-check-to-ope.patch
new file mode 100644 (file)
index 0000000..6d6d98b
--- /dev/null
@@ -0,0 +1,75 @@
+From eeb34e2113576aea782094d1e30f22b445355fe8 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Wed, 30 Nov 2011 13:34:16 -0500
+Subject: lttng lib: ring buffer move null pointer check to open
+
+* Dan Carpenter <dan.carpenter@oracle.com> wrote:
+> The patch c844b2f5cfea: "lttng lib: ring buffer" from Nov 28, 2011,
+> leads to the following Smatch complaint:
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c +86
+> +lib_ring_buffer_mmap_buf()
+>          warn: variable dereferenced before check 'buf' (see line 79)
+>
+> drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+>     78          unsigned long length = vma->vm_end - vma->vm_start;
+>     79          struct channel *chan = buf->backend.chan;
+>                                        ^^^^^^^^^^^^^^^^^
+> Dereference.
+>
+>     80          const struct lib_ring_buffer_config *config = chan->backend.config;
+>     81          unsigned long mmap_buf_len;
+>     82
+>     83          if (config->output != RING_BUFFER_MMAP)
+>     84                  return -EINVAL;
+>     85
+>     86          if (!buf)
+>                     ^^^^
+> Check.
+>
+>     87                  return -EBADF;
+>     88
+
+Let's move the NULL buf check to the file "open", where it belongs. The
+"open" file operation is the actual interface between lib ring buffer
+and the modules using it.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../lttng/lib/ringbuffer/ring_buffer_mmap.c        |    3 ---
+ .../staging/lttng/lib/ringbuffer/ring_buffer_vfs.c |    3 +++
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+index cf37434..c9d6e89 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+@@ -80,9 +80,6 @@ static int lib_ring_buffer_mmap_buf(struct lib_ring_buffer *buf,
+       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;
+diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
+index 1708ffd..8b78305 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
+@@ -42,6 +42,9 @@ int lib_ring_buffer_open(struct inode *inode, struct file *file)
+       struct lib_ring_buffer *buf = inode->i_private;
+       int ret;
++      if (!buf)
++              return -EINVAL;
++
+       ret = lib_ring_buffer_open_read(buf);
+       if (ret)
+               return ret;
+-- 
+1.7.9
+
diff --git a/patches.lttng/0072-lttng-wrapper-add-missing-include-to-kallsyms-wrappe.patch b/patches.lttng/0072-lttng-wrapper-add-missing-include-to-kallsyms-wrappe.patch
new file mode 100644 (file)
index 0000000..8f2d8fb
--- /dev/null
@@ -0,0 +1,29 @@
+From 91c0a213f10aa6637f680848e474fb107dd41ecf Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Wed, 30 Nov 2011 13:34:18 -0500
+Subject: lttng wrapper: add missing include to kallsyms wrapper
+
+Needed to keep bissectability.
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/wrapper/kallsyms.h |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/staging/lttng/wrapper/kallsyms.h b/drivers/staging/lttng/wrapper/kallsyms.h
+index bb45f38..a7b8ab1 100644
+--- a/drivers/staging/lttng/wrapper/kallsyms.h
++++ b/drivers/staging/lttng/wrapper/kallsyms.h
+@@ -1,6 +1,8 @@
+ #ifndef _LTT_WRAPPER_KALLSYMS_H
+ #define _LTT_WRAPPER_KALLSYMS_H
++#include <linux/kallsyms.h>
++
+ /*
+  * Copyright (C) 2011 Avik Sil (avik.sil@linaro.org)
+  *
+-- 
+1.7.9
+
diff --git a/patches.lttng/0073-staging-lttng-cleanup-one-bit-signed-bitfields.patch b/patches.lttng/0073-staging-lttng-cleanup-one-bit-signed-bitfields.patch
new file mode 100644 (file)
index 0000000..c85c466
--- /dev/null
@@ -0,0 +1,209 @@
+From 0dcbcbb49e3e8636e2f9d8cbcbeea827c5c951d9 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 1 Dec 2011 09:31:18 -0500
+Subject: staging: lttng: cleanup one-bit signed bitfields
+
+* Dan Carpenter <dan.carpenter@oracle.com> wrote:
+> Sparse complains that these signed bitfields look "dubious".  The
+> problem is that instead of being either 0 or 1 like people would expect,
+> signed one bit variables like this are either 0 or -1.  It doesn't cause
+> a problem in this case but it's ugly so lets fix them.
+
+* walter harms (wharms@bfs.de) wrote:
+> hi,
+> This patch looks ok to me but this design is ugly by itself.
+> It should be replaced by an uchar uint whatever or use a
+> real bool (obviously not preferred by this programmes).
+
+bool :1, uchar :1 or uint :1 could make sense. uchar:1/bool:1 won't save
+any space here, because the surrounding fields are either uint or
+pointers, so alignment will just add padding.
+
+I try to use int/uint whenever possible because x86 CPUs tend to get
+less register false-dependencies when using instructions modifying the
+whole register (generated by using int/uint types) rather than only part
+of it (uchar/char/bool). I only use char/uchar/bool when there is a
+clear wanted space gain.
+
+The reason why I never use the bool type within a structure when I want
+a compact representation is that bool takes a whole byte just to
+represent one bit:
+
+struct usebitfield {
+    int a;
+    unsigned int f:1, g:1, h:1, i:1, j:1;
+    int b;
+};
+
+struct usebool {
+    int a;
+    bool f, g, h, i, j;
+    int b;
+};
+
+struct useboolbf {
+    int a;
+    bool f:1, g:1, h:1, i:1, j:1;
+    int b;
+};
+
+int main()
+{
+    printf("bitfield %d bytes, bool %d bytes, boolbitfield %d bytes\n",
+            sizeof(struct usebitfield), sizeof(struct usebool),
+            sizeof(struct useboolbf));
+}
+
+result:
+
+bitfield 12 bytes, bool 16 bytes, boolbitfield 12 bytes
+
+This is because each bool takes one byte, while the bitfields are put in
+units of "unsigned int" (or bool for the 3rd struct). So in this
+example, we need 5 bytes + 3 bytes alignment for the bool, but only 4
+bytes to hold the "unsigned int" unit for the bitfields.
+
+The choice between bool and bitfields must also take into account the
+frequency of access to the variable, because bitfields require mask
+operations to access the selected bit(s). You will notice that none of
+these bitfields are accessed on the tracing fast-path: only in
+slow-paths. Therefore, space gain is more important than speed here.
+
+One might argue that I have so few of these fields here that it does not
+make an actual difference to go for bitfield or bool. I am just trying
+to choose types best suited for their intended purpose, ensuring they
+are future-proof and will allow simply adding more fields using the same
+type, as needed.
+
+So I guess I'll go for uint :1.
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ .../staging/lttng/lib/ringbuffer/backend_types.h   |    4 ++--
+ .../staging/lttng/lib/ringbuffer/frontend_types.h  |   14 +++++++-------
+ .../lttng/lib/ringbuffer/ring_buffer_frontend.c    |    2 +-
+ drivers/staging/lttng/ltt-events.h                 |   10 +++++-----
+ 4 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/staging/lttng/lib/ringbuffer/backend_types.h b/drivers/staging/lttng/lib/ringbuffer/backend_types.h
+index 1d301de..25c41bc 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/backend_types.h
++++ b/drivers/staging/lttng/lib/ringbuffer/backend_types.h
+@@ -53,7 +53,7 @@ struct lib_ring_buffer_backend {
+       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 ? */
++      uint allocated:1;               /* is buffer allocated ? */
+ };
+ struct channel_backend {
+@@ -65,7 +65,7 @@ struct channel_backend {
+                                        * for writer.
+                                        */
+       unsigned int buf_size_order;    /* Order of buffer size */
+-      int extra_reader_sb:1;          /* Bool: has extra reader subbuffer */
++      uint extra_reader_sb:1;         /* has extra reader subbuffer ? */
+       struct lib_ring_buffer *buf;    /* Channel per-cpu buffers */
+       unsigned long num_subbuf;       /* Number of sub-buffers for writer */
+diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_types.h b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
+index 5c7437f..eced7be 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
++++ b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
+@@ -60,8 +60,8 @@ struct channel {
+       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. */
++      uint cpu_hp_enable:1;                   /* Enable CPU hotplug notif. */
++      uint 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 */
+@@ -94,8 +94,8 @@ struct lib_ring_buffer_iter {
+               ITER_NEXT_RECORD,
+               ITER_PUT_SUBBUF,
+       } state;
+-      int allocated:1;
+-      int read_open:1;                /* Opened for reading ? */
++      uint allocated:1;
++      uint read_open:1;               /* Opened for reading ? */
+ };
+ /* ring buffer state */
+@@ -138,9 +138,9 @@ struct lib_ring_buffer {
+       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 */
++      uint get_subbuf:1;              /* Sub-buffer being held by reader */
++      uint switch_timer_enabled:1;    /* Protected by ring_buffer_nohz_lock */
++      uint read_timer_enabled:1;      /* Protected by ring_buffer_nohz_lock */
+ };
+ static inline
+diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+index 957d7f3..348c05e 100644
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+@@ -54,7 +54,7 @@
+ 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,
++      uint switch_new_start:1, switch_new_end:1, switch_old_start:1,
+                    switch_old_end:1;
+ };
+diff --git a/drivers/staging/lttng/ltt-events.h b/drivers/staging/lttng/ltt-events.h
+index 36b281a..c370ca6 100644
+--- a/drivers/staging/lttng/ltt-events.h
++++ b/drivers/staging/lttng/ltt-events.h
+@@ -67,8 +67,8 @@ struct lttng_enum_entry {
+ struct lttng_integer_type {
+       unsigned int size;              /* in bits */
+       unsigned short alignment;       /* in bits */
+-      unsigned int signedness:1;
+-      unsigned int reverse_byte_order:1;
++      uint signedness:1;
++      uint reverse_byte_order:1;
+       unsigned int base;              /* 2, 8, 10, 16, for pretty print */
+       enum lttng_string_encodings encoding;
+ };
+@@ -191,7 +191,7 @@ struct ltt_event {
+               } ftrace;
+       } u;
+       struct list_head list;          /* Event list */
+-      int metadata_dumped:1;
++      uint metadata_dumped:1;
+ };
+ struct ltt_channel_ops {
+@@ -251,7 +251,7 @@ struct ltt_channel {
+       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;
++      uint metadata_dumped:1;
+ };
+ struct ltt_session {
+@@ -264,7 +264,7 @@ struct ltt_session {
+       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;
++      uint metadata_dumped:1;
+ };
+ struct ltt_session *ltt_session_create(void);
+-- 
+1.7.9
+
diff --git a/patches.lttng/0172-staging-lttng-Fix-recent-modifications-to-string_fro.patch b/patches.lttng/0172-staging-lttng-Fix-recent-modifications-to-string_fro.patch
new file mode 100644 (file)
index 0000000..9b0ccef
--- /dev/null
@@ -0,0 +1,42 @@
+From 643167423858052c26b2dfaf332c1ec0b472ea7a Mon Sep 17 00:00:00 2001
+From: Yannick Brosseau <yannick.brosseau@gmail.com>
+Date: Fri, 2 Dec 2011 21:13:32 -0500
+Subject: staging: lttng: Fix recent modifications to string_from_user
+ operation
+
+Include: a fix for a recently introduced change: obviously max_t should
+be used instead of min_t here. Also, a likely should apply to the result
+of the comparison, not the variable per se.
+
+Signed-off-by: Yannick Brosseau <yannick.brosseau@gmail.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/probes/lttng-events.h |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/lttng/probes/lttng-events.h b/drivers/staging/lttng/probes/lttng-events.h
+index ff6273f..d486994 100644
+--- a/drivers/staging/lttng/probes/lttng-events.h
++++ b/drivers/staging/lttng/probes/lttng-events.h
+@@ -347,7 +347,7 @@ static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = {
+ #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);
++              max_t(size_t, strlen_user(_src), 1);
+ #undef TP_PROTO
+ #define TP_PROTO(args...) args
+@@ -557,7 +557,7 @@ __assign_##dest##_2:                                                       \
+                       (void) __typemap.dest;                          \
+               lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));\
+               __ustrlen = __get_dynamic_array_len(dest);              \
+-              if (likely(__ustrlen) > 1) {                            \
++              if (likely(__ustrlen > 1)) {                            \
+                       __chan->ops->event_write_from_user(&__ctx, src, \
+                               __ustrlen - 1);                         \
+               }                                                       \
+-- 
+1.7.9
+
diff --git a/patches.lttng/0173-staging-lttng-TODO-update-lttng-reported-to-work-fin.patch b/patches.lttng/0173-staging-lttng-TODO-update-lttng-reported-to-work-fin.patch
new file mode 100644 (file)
index 0000000..e3a98e3
--- /dev/null
@@ -0,0 +1,37 @@
+From 4ee778a44cc353ee201e933e45f493453cde3dfb Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Sat, 3 Dec 2011 13:05:37 -0500
+Subject: staging: lttng: TODO update: lttng reported to work fine on -rt now
+
+The patch "lttng: Fix recent modifications to string_from_user
+operation" has been confirmed to fix the corrupted trace problem
+experienced on -rt kernel by the original bug reporter. Remove the
+entry from the LTTng TODO list.
+
+Reported-by: Yannick Brosseau <yannick.brosseau@gmail.com>
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/TODO |    6 ------
+ 1 files changed, 0 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/staging/lttng/TODO b/drivers/staging/lttng/TODO
+index 3fdc5e6..5e3a581 100644
+--- a/drivers/staging/lttng/TODO
++++ b/drivers/staging/lttng/TODO
+@@ -35,12 +35,6 @@ A) Cleanup/Testing
+          depend on the producer to push the reader position.
+          Contact: Julien Desfossez <julien.desfossez@polymtl.ca>
+-      4) Test latest -rt kernel support.
+-         There has been report of corrupted traces when tracing a
+-         3.0.10-rt27 in the area of access_ok() system call event.
+-         Still has to be investigated. Cannot be reproduced with
+-         mainline kernel.
+-         Contact: Yannick Brosseau <yannick.brosseau@polymtl.ca>
+ B) Features
+-- 
+1.7.9
+
diff --git a/patches.lttng/0174-staging-lttng-Update-max-symbol-length-to-256.patch b/patches.lttng/0174-staging-lttng-Update-max-symbol-length-to-256.patch
new file mode 100644 (file)
index 0000000..289b02b
--- /dev/null
@@ -0,0 +1,30 @@
+From 4588d6d4087bfcd3663e9dc26d0fffacb38c4df6 Mon Sep 17 00:00:00 2001
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Mon, 5 Dec 2011 20:07:35 -0500
+Subject: staging: lttng: Update max symbol length to 256
+
+The user-space tracer, along with the control tools, now support longer
+event name strings (up to 256 chars, including \0).
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/lttng/ltt-debugfs-abi.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/staging/lttng/ltt-debugfs-abi.h b/drivers/staging/lttng/ltt-debugfs-abi.h
+index 42bc9fd..a018297 100644
+--- a/drivers/staging/lttng/ltt-debugfs-abi.h
++++ b/drivers/staging/lttng/ltt-debugfs-abi.h
+@@ -13,7 +13,7 @@
+ #include <linux/fs.h>
+-#define LTTNG_SYM_NAME_LEN    128
++#define LTTNG_SYM_NAME_LEN    256
+ enum lttng_kernel_instrumentation {
+       LTTNG_KERNEL_TRACEPOINT = 0,
+-- 
+1.7.9
+
diff --git a/series b/series
index c03d014..e4832e0 100644 (file)
--- a/series
+++ b/series
@@ -62,3 +62,35 @@ patches.android/staging-android-add-the-code-back-to-the-build.patch
 
 #############################################################################
 # LTTNG
+# Patches came from short-lived experiment when they were added to the staging
+# tree for a week or so.
+#
+patches.lttng/0000-lttng-lib-lttng-priority-heap.patch
+patches.lttng/0001-lttng-lib-ring-buffer.patch
+patches.lttng/0002-lttng-lib-portable-bitfield-read-write-header.patch
+patches.lttng/0003-lttng-BUILD_RUNTIME_BUG_ON.patch
+patches.lttng/0004-lttng-offset-alignment-header.patch
+patches.lttng/0005-lttng-libs-add-Makefile.patch
+patches.lttng/0006-lttng-wrappers.patch
+patches.lttng/0007-lttng-instrumentation-tracepoint-events.patch
+patches.lttng/0008-lttng-syscall-instrumentation.patch
+patches.lttng/0009-lttng-lib-ring-buffer-clients.patch
+patches.lttng/0010-lttng-tracer-control-and-core-structures.patch
+patches.lttng/0011-lttng-dynamically-selectable-context-information.patch
+patches.lttng/0012-lttng-timing-calibration-feature.patch
+patches.lttng/0013-lttng-debugfs-and-procfs-ABI.patch
+patches.lttng/0014-lttng-Add-documentation-and-TODO-files.patch
+patches.lttng/0015-lttng-add-system-call-instrumentation-probe.patch
+patches.lttng/0016-lttng-probe-callbacks.patch
+patches.lttng/0017-lttng-toplevel-Makefile-and-Kconfig.patch
+patches.lttng/0018-staging-add-LTTng-to-build.patch
+patches.lttng/0019-staging-Add-LTTng-entry-to-MAINTAINERS-file.patch
+patches.lttng/0069-lttng-lib-ring-buffer-remove-stale-null-pointer.patch
+patches.lttng/0070-lttng-lib-ring-buffer-remove-duplicate-null-pointer.patch
+patches.lttng/0071-lttng-lib-ring-buffer-move-null-pointer-check-to-ope.patch
+patches.lttng/0072-lttng-wrapper-add-missing-include-to-kallsyms-wrappe.patch
+patches.lttng/0073-staging-lttng-cleanup-one-bit-signed-bitfields.patch
+patches.lttng/0172-staging-lttng-Fix-recent-modifications-to-string_fro.patch
+patches.lttng/0173-staging-lttng-TODO-update-lttng-reported-to-work-fin.patch
+patches.lttng/0174-staging-lttng-Update-max-symbol-length-to-256.patch
+