aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-25 17:38:35 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-25 17:38:35 -0700
commit29ec9a84a9dd42d5d04c8deb12bdd6598c64241b (patch)
tree8948f8ce5c3ac9eef05503a18e990a4c9b2d87ab
parentbfd0d2ec9956717c87da97bf5e39b09dcc00435d (diff)
downloadltsi-kernel-29ec9a84a9dd42d5d04c8deb12bdd6598c64241b.tar.gz
Update to latest version of LTTNG (v2.0.1)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--patches.lttng/lttng-update-to-v2.0.1.patch14289
-rw-r--r--series2
2 files changed, 14290 insertions, 1 deletions
diff --git a/patches.lttng/lttng-update-to-v2.0.1.patch b/patches.lttng/lttng-update-to-v2.0.1.patch
new file mode 100644
index 0000000000000..e12c0f0510eb5
--- /dev/null
+++ b/patches.lttng/lttng-update-to-v2.0.1.patch
@@ -0,0 +1,14289 @@
+From compudj@mail.openrapids.net Thu Apr 5 07:40:26 2012
+From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date: Thu, 5 Apr 2012 10:40:20 -0400
+Subject: [PATCH LTSI staging] LTTng update to v2.0.1
+To: Greg KH <gregkh@linuxfoundation.org>
+Cc: Tim Bird <tim.bird@am.sony.com>, ltsi-dev@lists.linuxfoundation.org
+Message-ID: <20120405144020.GA31482@Krystal>
+Content-Disposition: inline
+
+
+Update LTTng driver (in LTSI tree) to v2.0.1 from
+git://git.lttng.org/lttng-modules.git, the external module package on which
+development has continued.
+
+Changelog:
+
+2012-03-29 LTTng modules 2.0.1
+ * Fix: is_compat_task !CONFIG_COMPAT compile error on kernels >= 3.3
+
+2012-03-20 LTTng modules 2.0.0
+ * First STABLE version
+ * Add version name
+
+2012-03-20 LTTng modules 2.0.0-rc4
+ * Update README and add version name place-holder
+
+2012-03-16 LTTng modules 2.0.0-rc3
+ * Fix clock offset 32-bit multiplication overflow
+ * Fix : wrong assign of fd in state dump
+ * License cleanup, ifdef namespace cleanup
+ * Fix: ensure power of 2 check handles 64-bit size_t entirely
+
+2012-03-02 LTTng modules 2.0.0-rc2
+ * Fix: dmesg printout should not print metadata warnings
+ * Fix: use transport name as channel name
+ * Fix: Return -EINVAL instead of print warning if non power of 2 size/num_subbuf
+
+2012-02-20 LTTng modules 2.0.0-rc1
+ * Standardize version across toolchain
+ * statedump: Use old macro name for kernel 2.6.38
+
+2012-02-16 LTTng modules 2.0-pre15
+ * Add timer instrumentation
+ * fix: need to undef mainline define
+ * fix: Include signal.h instead of irq.h for prototype match check
+ * Add signal instrumentation
+
+2012-02-16 LTTng modules 2.0-pre14
+ * syscall tracing: sys_getcpu
+ * Add sys_clone x86 instrumentation
+ * statedump: fix include circular dep
+ * Implement state dump
+
+2012-02-09 LTTng modules 2.0-pre13
+ * Update README
+ * environment: write sysname, release, version, domain to metadata
+ * Allow open /proc/lttng for read & write
+
+2012-02-02 LTTng modules 2.0-pre12
+ * Add x86 32/64 execve syscall instrumentation override
+ * Remove unused defines
+ * Add padding to ABI
+ * Use LTTNG_KERNEL_SYM_NAME_LEN
+ * Update version to 1.9.9
+ * Add missing double-quotes to clock uuid
+ * clock: read bootid as clock monotonic ID
+ * Fix comment
+ * Cleanup comment
+ * clock: output clock description in metadata
+ * Properly fix the timekeeping overflow detection
+ * Fix init bug
+ * rename lib-ring-buffer to lttng-lib-ring-buffer
+ * Remove #warning
+ * Mass rename: ltt_*/ltt-* to LTTNG_*/LTTNG-*
+ * Update TODO
+ * Update TODO
+ * Remove debugfs file (keep only proc file)
+ * Rename lttng-debugfs-abi files to lttng-abi
+
+2011-12-13 LTTng modules 2.0-pre11
+ * Fix OOPS caused by reference of config pointer
+ * Gather detailed info from x86 64 32-bit compat syscall instrumentation
+ * lttng lib: ring buffer move null pointer check to open
+ * lttng lib: ring buffer remove duplicate null pointer
+ * lttng lib: ring buffer: remove stale null-pointer
+ * lttng wrapper: add missing include to kallsyms wrapper
+ * lttng: cleanup one-bit signed bitfields
+ * Add TODO file
+ * Update symbol name length max size to 256
+ * Fix last modifications to string_from_user operations
+ * Document that depmod needs to be executed by hand
+ * Fix strlen_user fault space reservation
+ * Fix tp_copy_string_from_user handling of faults
+ * Disable block layer tracing support for kernels < 2.6.38
+ * lttng context: perf counter, fix 32-bit vs 64-bit field size bug
+ * Update trace clock warning to match the current development plan
+ * ringbuffer: make ring buffer printk less verbose
+ * Makefile: do not run depmod manually
+
+Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+CC: Greg KH <gregkh@linuxfoundation.org>
+CC: Tim Bird <tim.bird@am.sony.com>
+CC: ltsi-dev@lists.linuxfoundation.org
+---
+ drivers/staging/lttng/Makefile | 28
+ drivers/staging/lttng/README | 43
+ drivers/staging/lttng/TODO | 18
+ drivers/staging/lttng/instrumentation/events/lttng-module/lttng-statedump.h | 162 +
+ drivers/staging/lttng/instrumentation/events/lttng-module/signal.h | 165 +
+ drivers/staging/lttng/instrumentation/events/lttng-module/timer.h | 333 ++
+ drivers/staging/lttng/instrumentation/events/mainline/signal.h | 166 +
+ drivers/staging/lttng/instrumentation/events/mainline/timer.h | 329 ++
+ drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h | 53
+ drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h | 46
+ drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h | 3
+ drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h | 7
+ drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c | 18
+ drivers/staging/lttng/lib/Makefile | 4
+ drivers/staging/lttng/lib/align.h | 16
+ drivers/staging/lttng/lib/bitfield.h | 2
+ drivers/staging/lttng/lib/bug.h | 16
+ drivers/staging/lttng/lib/ringbuffer/api.h | 26
+ drivers/staging/lttng/lib/ringbuffer/backend.h | 26
+ drivers/staging/lttng/lib/ringbuffer/backend_internal.h | 26
+ drivers/staging/lttng/lib/ringbuffer/backend_types.h | 33
+ drivers/staging/lttng/lib/ringbuffer/config.h | 26
+ drivers/staging/lttng/lib/ringbuffer/frontend.h | 28
+ drivers/staging/lttng/lib/ringbuffer/frontend_api.h | 28
+ drivers/staging/lttng/lib/ringbuffer/frontend_internal.h | 26
+ drivers/staging/lttng/lib/ringbuffer/frontend_types.h | 34
+ drivers/staging/lttng/lib/ringbuffer/iterator.h | 28
+ drivers/staging/lttng/lib/ringbuffer/nohz.h | 24
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c | 60
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c | 112
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c | 46
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c | 29
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c | 23
+ drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c | 24
+ drivers/staging/lttng/lib/ringbuffer/vatomic.h | 24
+ drivers/staging/lttng/lib/ringbuffer/vfs.h | 28
+ drivers/staging/lttng/ltt-context.c | 93
+ drivers/staging/lttng/ltt-debugfs-abi.c | 777 ------
+ drivers/staging/lttng/ltt-debugfs-abi.h | 153 -
+ 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-ring-buffer-client-discard.c | 21
+ drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c | 21
+ drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c | 21
+ drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c | 21
+ drivers/staging/lttng/ltt-ring-buffer-client.h | 569 -----
+ drivers/staging/lttng/ltt-ring-buffer-metadata-client.c | 21
+ drivers/staging/lttng/ltt-ring-buffer-metadata-client.h | 330 --
+ drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c | 21
+ drivers/staging/lttng/ltt-tracer-core.h | 28
+ drivers/staging/lttng/ltt-tracer.h | 67
+ drivers/staging/lttng/lttng-abi.c | 781 ++++++
+ drivers/staging/lttng/lttng-abi.h | 176 +
+ drivers/staging/lttng/lttng-calibrate.c | 22
+ drivers/staging/lttng/lttng-context-nice.c | 31
+ drivers/staging/lttng/lttng-context-perf-counters.c | 31
+ drivers/staging/lttng/lttng-context-pid.c | 31
+ drivers/staging/lttng/lttng-context-ppid.c | 31
+ drivers/staging/lttng/lttng-context-prio.c | 31
+ drivers/staging/lttng/lttng-context-procname.c | 27
+ drivers/staging/lttng/lttng-context-tid.c | 31
+ drivers/staging/lttng/lttng-context-vpid.c | 31
+ drivers/staging/lttng/lttng-context-vppid.c | 31
+ drivers/staging/lttng/lttng-context-vtid.c | 31
+ drivers/staging/lttng/lttng-context.c | 105
+ drivers/staging/lttng/lttng-endian.h | 43
+ drivers/staging/lttng/lttng-events.c | 1126 ++++++++++
+ drivers/staging/lttng/lttng-events.h | 466 ++++
+ drivers/staging/lttng/lttng-probes.c | 176 +
+ drivers/staging/lttng/lttng-ring-buffer-client-discard.c | 33
+ drivers/staging/lttng/lttng-ring-buffer-client-mmap-discard.c | 33
+ drivers/staging/lttng/lttng-ring-buffer-client-mmap-overwrite.c | 33
+ drivers/staging/lttng/lttng-ring-buffer-client-overwrite.c | 33
+ drivers/staging/lttng/lttng-ring-buffer-client.h | 598 +++++
+ drivers/staging/lttng/lttng-ring-buffer-metadata-client.c | 33
+ drivers/staging/lttng/lttng-ring-buffer-metadata-client.h | 342 +++
+ drivers/staging/lttng/lttng-ring-buffer-metadata-mmap-client.c | 33
+ drivers/staging/lttng/lttng-statedump-impl.c | 385 +++
+ drivers/staging/lttng/lttng-syscalls.c | 69
+ drivers/staging/lttng/lttng-tracer-core.h | 41
+ drivers/staging/lttng/lttng-tracer.h | 80
+ drivers/staging/lttng/probes/Makefile | 4
+ drivers/staging/lttng/probes/define_trace.h | 16
+ drivers/staging/lttng/probes/lttng-events-reset.h | 16
+ drivers/staging/lttng/probes/lttng-events.h | 79
+ drivers/staging/lttng/probes/lttng-ftrace.c | 43
+ drivers/staging/lttng/probes/lttng-kprobes.c | 47
+ drivers/staging/lttng/probes/lttng-kretprobes.c | 47
+ drivers/staging/lttng/probes/lttng-probe-block.c | 18
+ drivers/staging/lttng/probes/lttng-probe-irq.c | 18
+ drivers/staging/lttng/probes/lttng-probe-kvm.c | 18
+ drivers/staging/lttng/probes/lttng-probe-lttng.c | 18
+ drivers/staging/lttng/probes/lttng-probe-sched.c | 18
+ drivers/staging/lttng/probes/lttng-probe-signal.c | 42
+ drivers/staging/lttng/probes/lttng-probe-statedump.c | 45
+ drivers/staging/lttng/probes/lttng-probe-timer.c | 43
+ drivers/staging/lttng/probes/lttng-type-list.h | 16
+ drivers/staging/lttng/probes/lttng-types.c | 20
+ drivers/staging/lttng/probes/lttng-types.h | 24
+ drivers/staging/lttng/probes/lttng.h | 16
+ drivers/staging/lttng/wrapper/ftrace.h | 24
+ drivers/staging/lttng/wrapper/inline_memcpy.h | 16
+ drivers/staging/lttng/wrapper/irqdesc.c | 58
+ drivers/staging/lttng/wrapper/irqdesc.h | 33
+ drivers/staging/lttng/wrapper/kallsyms.h | 45
+ drivers/staging/lttng/wrapper/perf.h | 24
+ drivers/staging/lttng/wrapper/poll.h | 24
+ drivers/staging/lttng/wrapper/random.c | 77
+ drivers/staging/lttng/wrapper/random.h | 32
+ drivers/staging/lttng/wrapper/spinlock.h | 24
+ drivers/staging/lttng/wrapper/splice.c | 20
+ drivers/staging/lttng/wrapper/splice.h | 26
+ drivers/staging/lttng/wrapper/trace-clock.h | 41
+ drivers/staging/lttng/wrapper/uuid.h | 24
+ drivers/staging/lttng/wrapper/vmalloc.h | 24
+ 117 files changed, 7456 insertions(+), 4357 deletions(-)
+
+--- a/drivers/staging/lttng/Makefile
++++ b/drivers/staging/lttng/Makefile
+@@ -2,28 +2,32 @@
+ # 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 += lttng-ring-buffer-client-discard.o
++obj-m += lttng-ring-buffer-client-overwrite.o
++obj-m += lttng-ring-buffer-metadata-client.o
++obj-m += lttng-ring-buffer-client-mmap-discard.o
++obj-m += lttng-ring-buffer-client-mmap-overwrite.o
++obj-m += lttng-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 \
++obj-m += lttng-relay.o
++lttng-relay-objs := lttng-events.o lttng-abi.o \
++ lttng-probes.o lttng-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
++ lttng-context-vppid.o lttng-calibrate.o \
++ wrapper/random.o
++
++obj-m += lttng-statedump.o
++lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o
+
+ ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),)
+-ltt-relay-objs += lttng-syscalls.o
++lttng-relay-objs += lttng-syscalls.o
+ endif
+
+ ifneq ($(CONFIG_PERF_EVENTS),)
+-ltt-relay-objs += $(shell \
++lttng-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;)
+--- a/drivers/staging/lttng/README
++++ b/drivers/staging/lttng/README
+@@ -1,10 +1,10 @@
+ LTTng 2.0 modules
+
+ Mathieu Desnoyers
+-November 1st, 2011
++February 8, 2012
+
+-LTTng 2.0 kernel modules is currently part of the Linux kernel staging
+-tree. It features (new features since LTTng 0.x):
++LTTng 2.0 kernel modules build against a vanilla or distribution kernel, without
++need for additional patches. Other features:
+
+ - Produces CTF (Common Trace Format) natively,
+ (http://www.efficios.com/ctf)
+@@ -17,28 +17,29 @@ tree. It features (new features since LT
+ 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.
++To build and install, you will need to enable LTTng in your kernel
++configuration.
+
+-Use lttng-tools to control the tracer. LTTng tools should automatically
+-load the kernel modules when needed. Use Babeltrace to print traces as a
++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.
++So far, it has been tested on vanilla Linux kernels 2.6.38, 2.6.39, 3.0,
++3.1, 3.2, 3.3 (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.
++
++LTTng-modules depends on having kallsyms enabled in the kernel it is
++built against. Ideally, if you want to have system call tracing, the
++"Trace Syscalls" feature should be enabled too.
+
+ * Note about Perf PMU counters support
+
+--- a/drivers/staging/lttng/TODO
++++ b/drivers/staging/lttng/TODO
+@@ -10,20 +10,7 @@ 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.
++ 1) 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.
+@@ -70,7 +57,6 @@ B) Features
+
+ 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
+
+@@ -107,7 +93,7 @@ B) Features
+ 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
++ 10) Turn lttng-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)
+
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/events/lttng-module/lttng-statedump.h
+@@ -0,0 +1,162 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM lttng_statedump
++
++#if !defined(_TRACE_LTTNG_STATEDUMP_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_LTTNG_STATEDUMP_H
++
++#include <linux/tracepoint.h>
++
++TRACE_EVENT(lttng_statedump_start,
++ TP_PROTO(struct lttng_session *session),
++ TP_ARGS(session),
++ TP_STRUCT__entry(
++ ),
++ TP_fast_assign(
++ ),
++ TP_printk("")
++)
++
++TRACE_EVENT(lttng_statedump_end,
++ TP_PROTO(struct lttng_session *session),
++ TP_ARGS(session),
++ TP_STRUCT__entry(
++ ),
++ TP_fast_assign(
++ ),
++ TP_printk("")
++)
++
++TRACE_EVENT(lttng_statedump_process_state,
++ TP_PROTO(struct lttng_session *session,
++ struct task_struct *p,
++ int type, int mode, int submode, int status),
++ TP_ARGS(session, p, type, mode, submode, status),
++ TP_STRUCT__entry(
++ __field(pid_t, tid)
++ __field(pid_t, vtid)
++ __field(pid_t, pid)
++ __field(pid_t, vpid)
++ __field(pid_t, ppid)
++ __field(pid_t, vppid)
++ __array_text(char, name, TASK_COMM_LEN)
++ __field(int, type)
++ __field(int, mode)
++ __field(int, submode)
++ __field(int, status)
++ ),
++ TP_fast_assign(
++ tp_assign(tid, p->pid)
++ tp_assign(vtid, !p->nsproxy ? 0 : task_pid_vnr(p))
++ tp_assign(pid, p->tgid)
++ tp_assign(vpid, !p->nsproxy ? 0 : task_tgid_vnr(p))
++ tp_assign(ppid,
++ ({
++ pid_t ret;
++
++ rcu_read_lock();
++ ret = task_tgid_nr(p->real_parent);
++ rcu_read_unlock();
++ ret;
++ }))
++ tp_assign(vppid,
++ ({
++ struct task_struct *parent;
++ pid_t ret;
++
++ rcu_read_lock();
++ parent = rcu_dereference(current->real_parent);
++ if (!parent->nsproxy)
++ ret = 0;
++ else
++ ret = task_tgid_nr(parent);
++ rcu_read_unlock();
++ ret;
++ }))
++ tp_memcpy(name, p->comm, TASK_COMM_LEN)
++ tp_assign(type, type)
++ tp_assign(mode, mode)
++ tp_assign(submode, submode)
++ tp_assign(status, status)
++ ),
++ TP_printk("")
++)
++
++TRACE_EVENT(lttng_statedump_file_descriptor,
++ TP_PROTO(struct lttng_session *session,
++ struct task_struct *p, int fd, const char *filename),
++ TP_ARGS(session, p, fd, filename),
++ TP_STRUCT__entry(
++ __field(pid_t, pid)
++ __field(int, fd)
++ __string(filename, filename)
++ ),
++ TP_fast_assign(
++ tp_assign(pid, p->tgid)
++ tp_assign(fd, fd)
++ tp_strcpy(filename, filename)
++ ),
++ TP_printk("")
++)
++
++TRACE_EVENT(lttng_statedump_vm_map,
++ TP_PROTO(struct lttng_session *session,
++ struct task_struct *p, struct vm_area_struct *map,
++ unsigned long inode),
++ TP_ARGS(session, p, map, inode),
++ TP_STRUCT__entry(
++ __field(pid_t, pid)
++ __field_hex(unsigned long, start)
++ __field_hex(unsigned long, end)
++ __field_hex(unsigned long, flags)
++ __field(unsigned long, inode)
++ __field(unsigned long, pgoff)
++ ),
++ TP_fast_assign(
++ tp_assign(pid, p->tgid)
++ tp_assign(start, map->vm_start)
++ tp_assign(end, map->vm_end)
++ tp_assign(flags, map->vm_flags)
++ tp_assign(inode, inode)
++ tp_assign(pgoff, map->vm_pgoff << PAGE_SHIFT)
++ ),
++ TP_printk("")
++)
++
++TRACE_EVENT(lttng_statedump_network_interface,
++ TP_PROTO(struct lttng_session *session,
++ struct net_device *dev, struct in_ifaddr *ifa),
++ TP_ARGS(session, dev, ifa),
++ TP_STRUCT__entry(
++ __string(name, dev->name)
++ __field_network_hex(uint32_t, address_ipv4)
++ ),
++ TP_fast_assign(
++ tp_strcpy(name, dev->name)
++ tp_assign(address_ipv4, ifa ? ifa->ifa_address : 0U)
++ ),
++ TP_printk("")
++)
++
++/* Called with desc->lock held */
++TRACE_EVENT(lttng_statedump_interrupt,
++ TP_PROTO(struct lttng_session *session,
++ unsigned int irq, const char *chip_name,
++ struct irqaction *action),
++ TP_ARGS(session, irq, chip_name, action),
++ TP_STRUCT__entry(
++ __field(unsigned int, irq)
++ __string(name, chip_name)
++ __string(action, action->name)
++ ),
++ TP_fast_assign(
++ tp_assign(irq, irq)
++ tp_strcpy(name, chip_name)
++ tp_strcpy(action, action->name)
++ ),
++ TP_printk("")
++)
++
++#endif /* _TRACE_LTTNG_STATEDUMP_H */
++
++/* This part must be outside protection */
++#include "../../../probes/define_trace.h"
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/events/lttng-module/signal.h
+@@ -0,0 +1,165 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM signal
++
++#if !defined(_TRACE_SIGNAL_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_SIGNAL_H
++
++#include <linux/tracepoint.h>
++
++#ifndef _TRACE_SIGNAL_DEF
++#define _TRACE_SIGNAL_DEF
++#include <linux/signal.h>
++#include <linux/sched.h>
++#undef TP_STORE_SIGINFO
++#define TP_STORE_SIGINFO(info) \
++ tp_assign(errno, \
++ (info == SEND_SIG_NOINFO || info == SEND_SIG_FORCED || info == SEND_SIG_PRIV) ? \
++ 0 : \
++ info->si_errno) \
++ tp_assign(code, \
++ (info == SEND_SIG_NOINFO || info == SEND_SIG_FORCED) ? \
++ SI_USER : \
++ ((info == SEND_SIG_PRIV) ? SI_KERNEL : info->si_code))
++#endif /* _TRACE_SIGNAL_DEF */
++
++/**
++ * signal_generate - called when a signal is generated
++ * @sig: signal number
++ * @info: pointer to struct siginfo
++ * @task: pointer to struct task_struct
++ *
++ * Current process sends a 'sig' signal to 'task' process with
++ * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV,
++ * 'info' is not a pointer and you can't access its field. Instead,
++ * SEND_SIG_NOINFO means that si_code is SI_USER, and SEND_SIG_PRIV
++ * means that si_code is SI_KERNEL.
++ */
++TRACE_EVENT(signal_generate,
++
++ TP_PROTO(int sig, struct siginfo *info, struct task_struct *task),
++
++ TP_ARGS(sig, info, task),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, errno )
++ __field( int, code )
++ __array( char, comm, TASK_COMM_LEN )
++ __field( pid_t, pid )
++ ),
++
++ TP_fast_assign(
++ tp_assign(sig, sig)
++ TP_STORE_SIGINFO(info)
++ tp_memcpy(comm, task->comm, TASK_COMM_LEN)
++ tp_assign(pid, task->pid)
++ ),
++
++ TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d",
++ __entry->sig, __entry->errno, __entry->code,
++ __entry->comm, __entry->pid)
++)
++
++/**
++ * signal_deliver - called when a signal is delivered
++ * @sig: signal number
++ * @info: pointer to struct siginfo
++ * @ka: pointer to struct k_sigaction
++ *
++ * A 'sig' signal is delivered to current process with 'info' siginfo,
++ * and it will be handled by 'ka'. ka->sa.sa_handler can be SIG_IGN or
++ * SIG_DFL.
++ * Note that some signals reported by signal_generate tracepoint can be
++ * lost, ignored or modified (by debugger) before hitting this tracepoint.
++ * This means, this can show which signals are actually delivered, but
++ * matching generated signals and delivered signals may not be correct.
++ */
++TRACE_EVENT(signal_deliver,
++
++ TP_PROTO(int sig, struct siginfo *info, struct k_sigaction *ka),
++
++ TP_ARGS(sig, info, ka),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, errno )
++ __field( int, code )
++ __field( unsigned long, sa_handler )
++ __field( unsigned long, sa_flags )
++ ),
++
++ TP_fast_assign(
++ tp_assign(sig, sig)
++ TP_STORE_SIGINFO(info)
++ tp_assign(sa_handler, (unsigned long)ka->sa.sa_handler)
++ tp_assign(sa_flags, ka->sa.sa_flags)
++ ),
++
++ TP_printk("sig=%d errno=%d code=%d sa_handler=%lx sa_flags=%lx",
++ __entry->sig, __entry->errno, __entry->code,
++ __entry->sa_handler, __entry->sa_flags)
++)
++
++DECLARE_EVENT_CLASS(signal_queue_overflow,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, group )
++ __field( int, errno )
++ __field( int, code )
++ ),
++
++ TP_fast_assign(
++ tp_assign(sig, sig)
++ tp_assign(group, group)
++ TP_STORE_SIGINFO(info)
++ ),
++
++ TP_printk("sig=%d group=%d errno=%d code=%d",
++ __entry->sig, __entry->group, __entry->errno, __entry->code)
++)
++
++/**
++ * signal_overflow_fail - called when signal queue is overflow
++ * @sig: signal number
++ * @group: signal to process group or not (bool)
++ * @info: pointer to struct siginfo
++ *
++ * Kernel fails to generate 'sig' signal with 'info' siginfo, because
++ * siginfo queue is overflow, and the signal is dropped.
++ * 'group' is not 0 if the signal will be sent to a process group.
++ * 'sig' is always one of RT signals.
++ */
++DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info)
++)
++
++/**
++ * signal_lose_info - called when siginfo is lost
++ * @sig: signal number
++ * @group: signal to process group or not (bool)
++ * @info: pointer to struct siginfo
++ *
++ * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo
++ * queue is overflow.
++ * 'group' is not 0 if the signal will be sent to a process group.
++ * 'sig' is always one of non-RT signals.
++ */
++DEFINE_EVENT(signal_queue_overflow, signal_lose_info,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info)
++)
++
++#endif /* _TRACE_SIGNAL_H */
++
++/* This part must be outside protection */
++#include "../../../probes/define_trace.h"
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/events/lttng-module/timer.h
+@@ -0,0 +1,333 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM timer
++
++#if !defined(_TRACE_TIMER_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_TIMER_H
++
++#include <linux/tracepoint.h>
++
++#ifndef _TRACE_TIMER_DEF_
++#define _TRACE_TIMER_DEF_
++#include <linux/hrtimer.h>
++#include <linux/timer.h>
++#endif /* _TRACE_TIMER_DEF_ */
++
++DECLARE_EVENT_CLASS(timer_class,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ ),
++
++ TP_fast_assign(
++ tp_assign(timer, timer)
++ ),
++
++ TP_printk("timer=%p", __entry->timer)
++)
++
++/**
++ * timer_init - called when the timer is initialized
++ * @timer: pointer to struct timer_list
++ */
++DEFINE_EVENT(timer_class, timer_init,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++)
++
++/**
++ * timer_start - called when the timer is started
++ * @timer: pointer to struct timer_list
++ * @expires: the timers expiry time
++ */
++TRACE_EVENT(timer_start,
++
++ TP_PROTO(struct timer_list *timer, unsigned long expires),
++
++ TP_ARGS(timer, expires),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ __field( void *, function )
++ __field( unsigned long, expires )
++ __field( unsigned long, now )
++ ),
++
++ TP_fast_assign(
++ tp_assign(timer, timer)
++ tp_assign(function, timer->function)
++ tp_assign(expires, expires)
++ tp_assign(now, jiffies)
++ ),
++
++ TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld]",
++ __entry->timer, __entry->function, __entry->expires,
++ (long)__entry->expires - __entry->now)
++)
++
++/**
++ * timer_expire_entry - called immediately before the timer callback
++ * @timer: pointer to struct timer_list
++ *
++ * Allows to determine the timer latency.
++ */
++TRACE_EVENT(timer_expire_entry,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ __field( unsigned long, now )
++ __field( void *, function)
++ ),
++
++ TP_fast_assign(
++ tp_assign(timer, timer)
++ tp_assign(now, jiffies)
++ tp_assign(function, timer->function)
++ ),
++
++ TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
++)
++
++/**
++ * timer_expire_exit - called immediately after the timer callback returns
++ * @timer: pointer to struct timer_list
++ *
++ * When used in combination with the timer_expire_entry tracepoint we can
++ * determine the runtime of the timer callback function.
++ *
++ * NOTE: Do NOT derefernce timer in TP_fast_assign. The pointer might
++ * be invalid. We solely track the pointer.
++ */
++DEFINE_EVENT(timer_class, timer_expire_exit,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++)
++
++/**
++ * timer_cancel - called when the timer is canceled
++ * @timer: pointer to struct timer_list
++ */
++DEFINE_EVENT(timer_class, timer_cancel,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++)
++
++/**
++ * hrtimer_init - called when the hrtimer is initialized
++ * @timer: pointer to struct hrtimer
++ * @clockid: the hrtimers clock
++ * @mode: the hrtimers mode
++ */
++TRACE_EVENT(hrtimer_init,
++
++ TP_PROTO(struct hrtimer *hrtimer, clockid_t clockid,
++ enum hrtimer_mode mode),
++
++ TP_ARGS(hrtimer, clockid, mode),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( clockid_t, clockid )
++ __field( enum hrtimer_mode, mode )
++ ),
++
++ TP_fast_assign(
++ tp_assign(hrtimer, hrtimer)
++ tp_assign(clockid, clockid)
++ tp_assign(mode, mode)
++ ),
++
++ TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer,
++ __entry->clockid == CLOCK_REALTIME ?
++ "CLOCK_REALTIME" : "CLOCK_MONOTONIC",
++ __entry->mode == HRTIMER_MODE_ABS ?
++ "HRTIMER_MODE_ABS" : "HRTIMER_MODE_REL")
++)
++
++/**
++ * hrtimer_start - called when the hrtimer is started
++ * @timer: pointer to struct hrtimer
++ */
++TRACE_EVENT(hrtimer_start,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( void *, function )
++ __field( s64, expires )
++ __field( s64, softexpires )
++ ),
++
++ TP_fast_assign(
++ tp_assign(hrtimer, hrtimer)
++ tp_assign(function, hrtimer->function)
++ tp_assign(expires, hrtimer_get_expires(hrtimer).tv64)
++ tp_assign(softexpires, hrtimer_get_softexpires(hrtimer).tv64)
++ ),
++
++ TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu",
++ __entry->hrtimer, __entry->function,
++ (unsigned long long)ktime_to_ns((ktime_t) {
++ .tv64 = __entry->expires }),
++ (unsigned long long)ktime_to_ns((ktime_t) {
++ .tv64 = __entry->softexpires }))
++)
++
++/**
++ * htimmer_expire_entry - called immediately before the hrtimer callback
++ * @timer: pointer to struct hrtimer
++ * @now: pointer to variable which contains current time of the
++ * timers base.
++ *
++ * Allows to determine the timer latency.
++ */
++TRACE_EVENT(hrtimer_expire_entry,
++
++ TP_PROTO(struct hrtimer *hrtimer, ktime_t *now),
++
++ TP_ARGS(hrtimer, now),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( s64, now )
++ __field( void *, function)
++ ),
++
++ TP_fast_assign(
++ tp_assign(hrtimer, hrtimer)
++ tp_assign(now, now->tv64)
++ tp_assign(function, hrtimer->function)
++ ),
++
++ TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
++ (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
++)
++
++DECLARE_EVENT_CLASS(hrtimer_class,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ ),
++
++ TP_fast_assign(
++ tp_assign(hrtimer, hrtimer)
++ ),
++
++ TP_printk("hrtimer=%p", __entry->hrtimer)
++)
++
++/**
++ * hrtimer_expire_exit - called immediately after the hrtimer callback returns
++ * @timer: pointer to struct hrtimer
++ *
++ * When used in combination with the hrtimer_expire_entry tracepoint we can
++ * determine the runtime of the callback function.
++ */
++DEFINE_EVENT(hrtimer_class, hrtimer_expire_exit,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer)
++)
++
++/**
++ * hrtimer_cancel - called when the hrtimer is canceled
++ * @hrtimer: pointer to struct hrtimer
++ */
++DEFINE_EVENT(hrtimer_class, hrtimer_cancel,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer)
++)
++
++/**
++ * itimer_state - called when itimer is started or canceled
++ * @which: name of the interval timer
++ * @value: the itimers value, itimer is canceled if value->it_value is
++ * zero, otherwise it is started
++ * @expires: the itimers expiry time
++ */
++TRACE_EVENT(itimer_state,
++
++ TP_PROTO(int which, const struct itimerval *const value,
++ cputime_t expires),
++
++ TP_ARGS(which, value, expires),
++
++ TP_STRUCT__entry(
++ __field( int, which )
++ __field( cputime_t, expires )
++ __field( long, value_sec )
++ __field( long, value_usec )
++ __field( long, interval_sec )
++ __field( long, interval_usec )
++ ),
++
++ TP_fast_assign(
++ tp_assign(which, which)
++ tp_assign(expires, expires)
++ tp_assign(value_sec, value->it_value.tv_sec)
++ tp_assign(value_usec, value->it_value.tv_usec)
++ tp_assign(interval_sec, value->it_interval.tv_sec)
++ tp_assign(interval_usec, value->it_interval.tv_usec)
++ ),
++
++ TP_printk("which=%d expires=%llu it_value=%ld.%ld it_interval=%ld.%ld",
++ __entry->which, (unsigned long long)__entry->expires,
++ __entry->value_sec, __entry->value_usec,
++ __entry->interval_sec, __entry->interval_usec)
++)
++
++/**
++ * itimer_expire - called when itimer expires
++ * @which: type of the interval timer
++ * @pid: pid of the process which owns the timer
++ * @now: current time, used to calculate the latency of itimer
++ */
++TRACE_EVENT(itimer_expire,
++
++ TP_PROTO(int which, struct pid *pid, cputime_t now),
++
++ TP_ARGS(which, pid, now),
++
++ TP_STRUCT__entry(
++ __field( int , which )
++ __field( pid_t, pid )
++ __field( cputime_t, now )
++ ),
++
++ TP_fast_assign(
++ tp_assign(which, which)
++ tp_assign(now, now)
++ tp_assign(pid, pid_nr(pid))
++ ),
++
++ TP_printk("which=%d pid=%d now=%llu", __entry->which,
++ (int) __entry->pid, (unsigned long long)__entry->now)
++)
++
++#endif /* _TRACE_TIMER_H */
++
++/* This part must be outside protection */
++#include "../../../probes/define_trace.h"
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/events/mainline/signal.h
+@@ -0,0 +1,166 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM signal
++
++#if !defined(_TRACE_SIGNAL_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_SIGNAL_H
++
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/tracepoint.h>
++
++#define TP_STORE_SIGINFO(__entry, info) \
++ do { \
++ if (info == SEND_SIG_NOINFO || \
++ info == SEND_SIG_FORCED) { \
++ __entry->errno = 0; \
++ __entry->code = SI_USER; \
++ } else if (info == SEND_SIG_PRIV) { \
++ __entry->errno = 0; \
++ __entry->code = SI_KERNEL; \
++ } else { \
++ __entry->errno = info->si_errno; \
++ __entry->code = info->si_code; \
++ } \
++ } while (0)
++
++/**
++ * signal_generate - called when a signal is generated
++ * @sig: signal number
++ * @info: pointer to struct siginfo
++ * @task: pointer to struct task_struct
++ *
++ * Current process sends a 'sig' signal to 'task' process with
++ * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV,
++ * 'info' is not a pointer and you can't access its field. Instead,
++ * SEND_SIG_NOINFO means that si_code is SI_USER, and SEND_SIG_PRIV
++ * means that si_code is SI_KERNEL.
++ */
++TRACE_EVENT(signal_generate,
++
++ TP_PROTO(int sig, struct siginfo *info, struct task_struct *task),
++
++ TP_ARGS(sig, info, task),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, errno )
++ __field( int, code )
++ __array( char, comm, TASK_COMM_LEN )
++ __field( pid_t, pid )
++ ),
++
++ TP_fast_assign(
++ __entry->sig = sig;
++ TP_STORE_SIGINFO(__entry, info);
++ memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
++ __entry->pid = task->pid;
++ ),
++
++ TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d",
++ __entry->sig, __entry->errno, __entry->code,
++ __entry->comm, __entry->pid)
++);
++
++/**
++ * signal_deliver - called when a signal is delivered
++ * @sig: signal number
++ * @info: pointer to struct siginfo
++ * @ka: pointer to struct k_sigaction
++ *
++ * A 'sig' signal is delivered to current process with 'info' siginfo,
++ * and it will be handled by 'ka'. ka->sa.sa_handler can be SIG_IGN or
++ * SIG_DFL.
++ * Note that some signals reported by signal_generate tracepoint can be
++ * lost, ignored or modified (by debugger) before hitting this tracepoint.
++ * This means, this can show which signals are actually delivered, but
++ * matching generated signals and delivered signals may not be correct.
++ */
++TRACE_EVENT(signal_deliver,
++
++ TP_PROTO(int sig, struct siginfo *info, struct k_sigaction *ka),
++
++ TP_ARGS(sig, info, ka),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, errno )
++ __field( int, code )
++ __field( unsigned long, sa_handler )
++ __field( unsigned long, sa_flags )
++ ),
++
++ TP_fast_assign(
++ __entry->sig = sig;
++ TP_STORE_SIGINFO(__entry, info);
++ __entry->sa_handler = (unsigned long)ka->sa.sa_handler;
++ __entry->sa_flags = ka->sa.sa_flags;
++ ),
++
++ TP_printk("sig=%d errno=%d code=%d sa_handler=%lx sa_flags=%lx",
++ __entry->sig, __entry->errno, __entry->code,
++ __entry->sa_handler, __entry->sa_flags)
++);
++
++DECLARE_EVENT_CLASS(signal_queue_overflow,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info),
++
++ TP_STRUCT__entry(
++ __field( int, sig )
++ __field( int, group )
++ __field( int, errno )
++ __field( int, code )
++ ),
++
++ TP_fast_assign(
++ __entry->sig = sig;
++ __entry->group = group;
++ TP_STORE_SIGINFO(__entry, info);
++ ),
++
++ TP_printk("sig=%d group=%d errno=%d code=%d",
++ __entry->sig, __entry->group, __entry->errno, __entry->code)
++);
++
++/**
++ * signal_overflow_fail - called when signal queue is overflow
++ * @sig: signal number
++ * @group: signal to process group or not (bool)
++ * @info: pointer to struct siginfo
++ *
++ * Kernel fails to generate 'sig' signal with 'info' siginfo, because
++ * siginfo queue is overflow, and the signal is dropped.
++ * 'group' is not 0 if the signal will be sent to a process group.
++ * 'sig' is always one of RT signals.
++ */
++DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info)
++);
++
++/**
++ * signal_lose_info - called when siginfo is lost
++ * @sig: signal number
++ * @group: signal to process group or not (bool)
++ * @info: pointer to struct siginfo
++ *
++ * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo
++ * queue is overflow.
++ * 'group' is not 0 if the signal will be sent to a process group.
++ * 'sig' is always one of non-RT signals.
++ */
++DEFINE_EVENT(signal_queue_overflow, signal_lose_info,
++
++ TP_PROTO(int sig, int group, struct siginfo *info),
++
++ TP_ARGS(sig, group, info)
++);
++
++#endif /* _TRACE_SIGNAL_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
+--- /dev/null
++++ b/drivers/staging/lttng/instrumentation/events/mainline/timer.h
+@@ -0,0 +1,329 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM timer
++
++#if !defined(_TRACE_TIMER_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_TIMER_H
++
++#include <linux/tracepoint.h>
++#include <linux/hrtimer.h>
++#include <linux/timer.h>
++
++DECLARE_EVENT_CLASS(timer_class,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ ),
++
++ TP_fast_assign(
++ __entry->timer = timer;
++ ),
++
++ TP_printk("timer=%p", __entry->timer)
++);
++
++/**
++ * timer_init - called when the timer is initialized
++ * @timer: pointer to struct timer_list
++ */
++DEFINE_EVENT(timer_class, timer_init,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++);
++
++/**
++ * timer_start - called when the timer is started
++ * @timer: pointer to struct timer_list
++ * @expires: the timers expiry time
++ */
++TRACE_EVENT(timer_start,
++
++ TP_PROTO(struct timer_list *timer, unsigned long expires),
++
++ TP_ARGS(timer, expires),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ __field( void *, function )
++ __field( unsigned long, expires )
++ __field( unsigned long, now )
++ ),
++
++ TP_fast_assign(
++ __entry->timer = timer;
++ __entry->function = timer->function;
++ __entry->expires = expires;
++ __entry->now = jiffies;
++ ),
++
++ TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld]",
++ __entry->timer, __entry->function, __entry->expires,
++ (long)__entry->expires - __entry->now)
++);
++
++/**
++ * timer_expire_entry - called immediately before the timer callback
++ * @timer: pointer to struct timer_list
++ *
++ * Allows to determine the timer latency.
++ */
++TRACE_EVENT(timer_expire_entry,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer),
++
++ TP_STRUCT__entry(
++ __field( void *, timer )
++ __field( unsigned long, now )
++ __field( void *, function)
++ ),
++
++ TP_fast_assign(
++ __entry->timer = timer;
++ __entry->now = jiffies;
++ __entry->function = timer->function;
++ ),
++
++ TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
++);
++
++/**
++ * timer_expire_exit - called immediately after the timer callback returns
++ * @timer: pointer to struct timer_list
++ *
++ * When used in combination with the timer_expire_entry tracepoint we can
++ * determine the runtime of the timer callback function.
++ *
++ * NOTE: Do NOT derefernce timer in TP_fast_assign. The pointer might
++ * be invalid. We solely track the pointer.
++ */
++DEFINE_EVENT(timer_class, timer_expire_exit,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++);
++
++/**
++ * timer_cancel - called when the timer is canceled
++ * @timer: pointer to struct timer_list
++ */
++DEFINE_EVENT(timer_class, timer_cancel,
++
++ TP_PROTO(struct timer_list *timer),
++
++ TP_ARGS(timer)
++);
++
++/**
++ * hrtimer_init - called when the hrtimer is initialized
++ * @timer: pointer to struct hrtimer
++ * @clockid: the hrtimers clock
++ * @mode: the hrtimers mode
++ */
++TRACE_EVENT(hrtimer_init,
++
++ TP_PROTO(struct hrtimer *hrtimer, clockid_t clockid,
++ enum hrtimer_mode mode),
++
++ TP_ARGS(hrtimer, clockid, mode),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( clockid_t, clockid )
++ __field( enum hrtimer_mode, mode )
++ ),
++
++ TP_fast_assign(
++ __entry->hrtimer = hrtimer;
++ __entry->clockid = clockid;
++ __entry->mode = mode;
++ ),
++
++ TP_printk("hrtimer=%p clockid=%s mode=%s", __entry->hrtimer,
++ __entry->clockid == CLOCK_REALTIME ?
++ "CLOCK_REALTIME" : "CLOCK_MONOTONIC",
++ __entry->mode == HRTIMER_MODE_ABS ?
++ "HRTIMER_MODE_ABS" : "HRTIMER_MODE_REL")
++);
++
++/**
++ * hrtimer_start - called when the hrtimer is started
++ * @timer: pointer to struct hrtimer
++ */
++TRACE_EVENT(hrtimer_start,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( void *, function )
++ __field( s64, expires )
++ __field( s64, softexpires )
++ ),
++
++ TP_fast_assign(
++ __entry->hrtimer = hrtimer;
++ __entry->function = hrtimer->function;
++ __entry->expires = hrtimer_get_expires(hrtimer).tv64;
++ __entry->softexpires = hrtimer_get_softexpires(hrtimer).tv64;
++ ),
++
++ TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu",
++ __entry->hrtimer, __entry->function,
++ (unsigned long long)ktime_to_ns((ktime_t) {
++ .tv64 = __entry->expires }),
++ (unsigned long long)ktime_to_ns((ktime_t) {
++ .tv64 = __entry->softexpires }))
++);
++
++/**
++ * htimmer_expire_entry - called immediately before the hrtimer callback
++ * @timer: pointer to struct hrtimer
++ * @now: pointer to variable which contains current time of the
++ * timers base.
++ *
++ * Allows to determine the timer latency.
++ */
++TRACE_EVENT(hrtimer_expire_entry,
++
++ TP_PROTO(struct hrtimer *hrtimer, ktime_t *now),
++
++ TP_ARGS(hrtimer, now),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ __field( s64, now )
++ __field( void *, function)
++ ),
++
++ TP_fast_assign(
++ __entry->hrtimer = hrtimer;
++ __entry->now = now->tv64;
++ __entry->function = hrtimer->function;
++ ),
++
++ TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
++ (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
++ );
++
++DECLARE_EVENT_CLASS(hrtimer_class,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer),
++
++ TP_STRUCT__entry(
++ __field( void *, hrtimer )
++ ),
++
++ TP_fast_assign(
++ __entry->hrtimer = hrtimer;
++ ),
++
++ TP_printk("hrtimer=%p", __entry->hrtimer)
++);
++
++/**
++ * hrtimer_expire_exit - called immediately after the hrtimer callback returns
++ * @timer: pointer to struct hrtimer
++ *
++ * When used in combination with the hrtimer_expire_entry tracepoint we can
++ * determine the runtime of the callback function.
++ */
++DEFINE_EVENT(hrtimer_class, hrtimer_expire_exit,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer)
++);
++
++/**
++ * hrtimer_cancel - called when the hrtimer is canceled
++ * @hrtimer: pointer to struct hrtimer
++ */
++DEFINE_EVENT(hrtimer_class, hrtimer_cancel,
++
++ TP_PROTO(struct hrtimer *hrtimer),
++
++ TP_ARGS(hrtimer)
++);
++
++/**
++ * itimer_state - called when itimer is started or canceled
++ * @which: name of the interval timer
++ * @value: the itimers value, itimer is canceled if value->it_value is
++ * zero, otherwise it is started
++ * @expires: the itimers expiry time
++ */
++TRACE_EVENT(itimer_state,
++
++ TP_PROTO(int which, const struct itimerval *const value,
++ cputime_t expires),
++
++ TP_ARGS(which, value, expires),
++
++ TP_STRUCT__entry(
++ __field( int, which )
++ __field( cputime_t, expires )
++ __field( long, value_sec )
++ __field( long, value_usec )
++ __field( long, interval_sec )
++ __field( long, interval_usec )
++ ),
++
++ TP_fast_assign(
++ __entry->which = which;
++ __entry->expires = expires;
++ __entry->value_sec = value->it_value.tv_sec;
++ __entry->value_usec = value->it_value.tv_usec;
++ __entry->interval_sec = value->it_interval.tv_sec;
++ __entry->interval_usec = value->it_interval.tv_usec;
++ ),
++
++ TP_printk("which=%d expires=%llu it_value=%ld.%ld it_interval=%ld.%ld",
++ __entry->which, (unsigned long long)__entry->expires,
++ __entry->value_sec, __entry->value_usec,
++ __entry->interval_sec, __entry->interval_usec)
++);
++
++/**
++ * itimer_expire - called when itimer expires
++ * @which: type of the interval timer
++ * @pid: pid of the process which owns the timer
++ * @now: current time, used to calculate the latency of itimer
++ */
++TRACE_EVENT(itimer_expire,
++
++ TP_PROTO(int which, struct pid *pid, cputime_t now),
++
++ TP_ARGS(which, pid, now),
++
++ TP_STRUCT__entry(
++ __field( int , which )
++ __field( pid_t, pid )
++ __field( cputime_t, now )
++ ),
++
++ TP_fast_assign(
++ __entry->which = which;
++ __entry->now = now;
++ __entry->pid = pid_nr(pid);
++ ),
++
++ TP_printk("which=%d pid=%d now=%llu", __entry->which,
++ (int) __entry->pid, (unsigned long long)__entry->now)
++);
++
++#endif /* _TRACE_TIMER_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
+--- a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h
++++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h
+@@ -1,3 +1,56 @@
++#define OVERRIDE_32_sys_execve
++#define OVERRIDE_64_sys_execve
++
++#ifndef CREATE_SYSCALL_TABLE
++
++SC_TRACE_EVENT(sys_execve,
++ TP_PROTO(const char *filename, char *const *argv, char *const *envp),
++ TP_ARGS(filename, argv, envp),
++ TP_STRUCT__entry(__string_from_user(filename, filename)
++ __field_hex(char *const *, argv)
++ __field_hex(char *const *, envp)),
++ TP_fast_assign(tp_copy_string_from_user(filename, filename)
++ tp_assign(argv, argv)
++ tp_assign(envp, envp)),
++ TP_printk()
++)
++
++SC_TRACE_EVENT(sys_clone,
++ TP_PROTO(unsigned long clone_flags, unsigned long newsp,
++ void __user *parent_tid,
++ void __user *child_tid),
++ TP_ARGS(clone_flags, newsp, parent_tid, child_tid),
++ TP_STRUCT__entry(
++ __field_hex(unsigned long, clone_flags)
++ __field_hex(unsigned long, newsp)
++ __field_hex(void *, parent_tid)
++ __field_hex(void *, child_tid)),
++ TP_fast_assign(
++ tp_assign(clone_flags, clone_flags)
++ tp_assign(newsp, newsp)
++ tp_assign(parent_tid, parent_tid)
++ tp_assign(child_tid, child_tid)),
++ TP_printk()
++)
++
++/* present in 32, missing in 64 due to old kernel headers */
++#define OVERRIDE_32_sys_getcpu
++#define OVERRIDE_64_sys_getcpu
++SC_TRACE_EVENT(sys_getcpu,
++ TP_PROTO(unsigned __user *cpup, unsigned __user *nodep, void *tcache),
++ TP_ARGS(cpup, nodep, tcache),
++ TP_STRUCT__entry(
++ __field_hex(unsigned *, cpup)
++ __field_hex(unsigned *, nodep)
++ __field_hex(void *, tcache)),
++ TP_fast_assign(
++ tp_assign(cpup, cpup)
++ tp_assign(nodep, nodep)
++ tp_assign(tcache, tcache)),
++ TP_printk()
++)
++
++#endif /* CREATE_SYSCALL_TABLE */
+ /*
+ * This is a place-holder for override defines for system calls with
+ * pointers (all architectures).
+--- 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
+@@ -1,17 +1,33 @@
+-#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
++#ifndef CREATE_SYSCALL_TABLE
++
++# 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
++# endif
++
++#else /* CREATE_SYSCALL_TABLE */
++
++# ifndef CONFIG_UID16
++# 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
++
++#define OVERRIDE_TABLE_32_sys_execve
++TRACE_SYSCALL_TABLE(sys_execve, sys_execve, 11, 3)
++#define OVERRIDE_TABLE_32_sys_clone
++TRACE_SYSCALL_TABLE(sys_clone, sys_clone, 120, 5)
++#define OVERRIDE_TABLE_32_sys_getcpu
++TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 318, 3)
++
++#endif /* CREATE_SYSCALL_TABLE */
++
+
+-#endif
+--- 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
+@@ -1,3 +1,6 @@
+ /*
+ * this is a place-holder for x86_64 interger syscall definition override.
+ */
++/*
++ * this is a place-holder for x86_64 interger syscall definition override.
++ */
+--- 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
+@@ -2,4 +2,11 @@
+
+ #else /* CREATE_SYSCALL_TABLE */
+
++#define OVERRIDE_TABLE_64_sys_clone
++TRACE_SYSCALL_TABLE(sys_clone, sys_clone, 56, 5)
++#define OVERRIDE_TABLE_64_sys_execve
++TRACE_SYSCALL_TABLE(sys_execve, sys_execve, 59, 3)
++#define OVERRIDE_TABLE_64_sys_getcpu
++TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 309, 3)
++
+ #endif /* CREATE_SYSCALL_TABLE */
+--- 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
+@@ -1,10 +1,24 @@
+ /*
++ * lttng-syscalls-extractor.c
++ *
++ * Dump syscall metadata to console.
++ *
+ * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
+ *
+- * Dump syscall metadata to console.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
+ *
+- * GPLv2 license.
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+ #include <linux/module.h>
+--- a/drivers/staging/lttng/lib/Makefile
++++ b/drivers/staging/lttng/lib/Makefile
+@@ -1,6 +1,6 @@
+-obj-m += lib-ring-buffer.o
++obj-m += lttng-lib-ring-buffer.o
+
+-lib-ring-buffer-objs := \
++lttng-lib-ring-buffer-objs := \
+ ringbuffer/ring_buffer_backend.o \
+ ringbuffer/ring_buffer_frontend.o \
+ ringbuffer/ring_buffer_iterator.o \
+--- a/drivers/staging/lttng/lib/align.h
++++ b/drivers/staging/lttng/lib/align.h
+@@ -4,9 +4,21 @@
+ /*
+ * lib/align.h
+ *
+- * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #ifdef __KERNEL__
+--- a/drivers/staging/lttng/lib/bitfield.h
++++ b/drivers/staging/lttng/lib/bitfield.h
+@@ -19,7 +19,7 @@
+ * all copies or substantial portions of the Software.
+ */
+
+-#include "../ltt-endian.h"
++#include "../lttng-endian.h"
+
+ #ifndef CHAR_BIT
+ #define CHAR_BIT 8
+--- a/drivers/staging/lttng/lib/bug.h
++++ b/drivers/staging/lttng/lib/bug.h
+@@ -4,9 +4,21 @@
+ /*
+ * lib/bug.h
+ *
+- * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /**
+--- a/drivers/staging/lttng/lib/ringbuffer/api.h
++++ b/drivers/staging/lttng/lib/ringbuffer/api.h
+@@ -1,14 +1,26 @@
+-#ifndef _LINUX_RING_BUFFER_API_H
+-#define _LINUX_RING_BUFFER_API_H
++#ifndef _LIB_RING_BUFFER_API_H
++#define _LIB_RING_BUFFER_API_H
+
+ /*
+- * linux/ringbuffer/api.h
+- *
+- * Copyright (C) 2010 - Mathieu Desnoyers "mathieu.desnoyers@efficios.com"
++ * lib/ringbuffer/api.h
+ *
+ * Ring Buffer API.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include "../../wrapper/ringbuffer/backend.h"
+@@ -22,4 +34,4 @@
+ */
+ #include "../../wrapper/ringbuffer/frontend_api.h"
+
+-#endif /* _LINUX_RING_BUFFER_API_H */
++#endif /* _LIB_RING_BUFFER_API_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/backend.h
++++ b/drivers/staging/lttng/lib/ringbuffer/backend.h
+@@ -1,14 +1,26 @@
+-#ifndef _LINUX_RING_BUFFER_BACKEND_H
+-#define _LINUX_RING_BUFFER_BACKEND_H
++#ifndef _LIB_RING_BUFFER_BACKEND_H
++#define _LIB_RING_BUFFER_BACKEND_H
+
+ /*
+- * linux/ringbuffer/backend.h
+- *
+- * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/backend.h
+ *
+ * Ring buffer backend (API).
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Credits to Steven Rostedt for proposing to use an extra-subbuffer owned by
+ * the reader in flight recorder mode.
+@@ -247,4 +259,4 @@ ssize_t lib_ring_buffer_file_splice_read
+ 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 */
++#endif /* _LIB_RING_BUFFER_BACKEND_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/backend_internal.h
++++ b/drivers/staging/lttng/lib/ringbuffer/backend_internal.h
+@@ -1,14 +1,26 @@
+-#ifndef _LINUX_RING_BUFFER_BACKEND_INTERNAL_H
+-#define _LINUX_RING_BUFFER_BACKEND_INTERNAL_H
++#ifndef _LIB_RING_BUFFER_BACKEND_INTERNAL_H
++#define _LIB_RING_BUFFER_BACKEND_INTERNAL_H
+
+ /*
+- * linux/ringbuffer/backend_internal.h
+- *
+- * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/backend_internal.h
+ *
+ * Ring buffer backend (internal helpers).
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2008-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include "../../wrapper/ringbuffer/config.h"
+@@ -446,4 +458,4 @@ void lib_ring_buffer_do_memset(char *des
+ dest[i] = c;
+ }
+
+-#endif /* _LINUX_RING_BUFFER_BACKEND_INTERNAL_H */
++#endif /* _LIB_RING_BUFFER_BACKEND_INTERNAL_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/backend_types.h
++++ b/drivers/staging/lttng/lib/ringbuffer/backend_types.h
+@@ -1,14 +1,26 @@
+-#ifndef _LINUX_RING_BUFFER_BACKEND_TYPES_H
+-#define _LINUX_RING_BUFFER_BACKEND_TYPES_H
++#ifndef _LIB_RING_BUFFER_BACKEND_TYPES_H
++#define _LIB_RING_BUFFER_BACKEND_TYPES_H
+
+ /*
+- * linux/ringbuffer/backend_types.h
+- *
+- * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/backend_types.h
+ *
+ * Ring buffer backend (types).
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2008-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/cpumask.h>
+@@ -72,9 +84,14 @@ struct channel_backend {
+ 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 */
++ /*
++ * We need to copy config because the module containing the
++ * source config can vanish before the last reference to this
++ * channel's streams is released.
++ */
++ 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 */
++#endif /* _LIB_RING_BUFFER_BACKEND_TYPES_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/config.h
++++ b/drivers/staging/lttng/lib/ringbuffer/config.h
+@@ -1,15 +1,27 @@
+-#ifndef _LINUX_RING_BUFFER_CONFIG_H
+-#define _LINUX_RING_BUFFER_CONFIG_H
++#ifndef _LIB_RING_BUFFER_CONFIG_H
++#define _LIB_RING_BUFFER_CONFIG_H
+
+ /*
+- * linux/ringbuffer/config.h
+- *
+- * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/config.h
+ *
+ * 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.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/types.h>
+@@ -295,4 +307,4 @@ int lib_ring_buffer_check_config(const s
+
+ #include "../../wrapper/ringbuffer/vatomic.h"
+
+-#endif /* _LINUX_RING_BUFFER_CONFIG_H */
++#endif /* _LIB_RING_BUFFER_CONFIG_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/frontend.h
++++ b/drivers/staging/lttng/lib/ringbuffer/frontend.h
+@@ -1,19 +1,31 @@
+-#ifndef _LINUX_RING_BUFFER_FRONTEND_H
+-#define _LINUX_RING_BUFFER_FRONTEND_H
++#ifndef _LIB_RING_BUFFER_FRONTEND_H
++#define _LIB_RING_BUFFER_FRONTEND_H
+
+ /*
+- * linux/ringbuffer/frontend.h
+- *
+- * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/frontend.h
+ *
+ * Ring Buffer Library Synchronization Header (API).
+ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * 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>
+@@ -225,4 +237,4 @@ unsigned long lib_ring_buffer_get_record
+ return v_read(config, &buf->backend.records_read);
+ }
+
+-#endif /* _LINUX_RING_BUFFER_FRONTEND_H */
++#endif /* _LIB_RING_BUFFER_FRONTEND_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/frontend_api.h
++++ b/drivers/staging/lttng/lib/ringbuffer/frontend_api.h
+@@ -1,20 +1,32 @@
+-#ifndef _LINUX_RING_BUFFER_FRONTEND_API_H
+-#define _LINUX_RING_BUFFER_FRONTEND_API_H
++#ifndef _LIB_RING_BUFFER_FRONTEND_API_H
++#define _LIB_RING_BUFFER_FRONTEND_API_H
+
+ /*
+- * linux/ringbuffer/frontend_api.h
+- *
+- * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/frontend_api.h
+ *
+ * Ring Buffer Library Synchronization Header (buffer write API).
+ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * 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"
+@@ -355,4 +367,4 @@ void lib_ring_buffer_record_enable(const
+ atomic_dec(&buf->record_disabled);
+ }
+
+-#endif /* _LINUX_RING_BUFFER_FRONTEND_API_H */
++#endif /* _LIB_RING_BUFFER_FRONTEND_API_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h
++++ b/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h
+@@ -1,19 +1,31 @@
+-#ifndef _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H
+-#define _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H
++#ifndef _LIB_RING_BUFFER_FRONTEND_INTERNAL_H
++#define _LIB_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).
+ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * 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"
+@@ -421,4 +433,4 @@ extern void lib_ring_buffer_free(struct
+ /* 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 */
++#endif /* _LIB_RING_BUFFER_FRONTEND_INTERNAL_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
++++ b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h
+@@ -1,19 +1,31 @@
+-#ifndef _LINUX_RING_BUFFER_FRONTEND_TYPES_H
+-#define _LINUX_RING_BUFFER_FRONTEND_TYPES_H
++#ifndef _LIB_RING_BUFFER_FRONTEND_TYPES_H
++#define _LIB_RING_BUFFER_FRONTEND_TYPES_H
+
+ /*
+- * linux/ringbuffer/frontend_types.h
+- *
+- * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/frontend_types.h
+ *
+ * Ring Buffer Library Synchronization Header (types).
+ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * 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>
+@@ -138,9 +150,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 */
+- 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 */
++ uint get_subbuf:1, /* Sub-buffer being held by reader */
++ switch_timer_enabled:1, /* Protected by ring_buffer_nohz_lock */
++ read_timer_enabled:1; /* Protected by ring_buffer_nohz_lock */
+ };
+
+ static inline
+@@ -173,4 +185,4 @@ void *channel_get_private(struct channel
+ _____ret; \
+ })
+
+-#endif /* _LINUX_RING_BUFFER_FRONTEND_TYPES_H */
++#endif /* _LIB_RING_BUFFER_FRONTEND_TYPES_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/iterator.h
++++ b/drivers/staging/lttng/lib/ringbuffer/iterator.h
+@@ -1,17 +1,29 @@
+-#ifndef _LINUX_RING_BUFFER_ITERATOR_H
+-#define _LINUX_RING_BUFFER_ITERATOR_H
++#ifndef _LIB_RING_BUFFER_ITERATOR_H
++#define _LIB_RING_BUFFER_ITERATOR_H
+
+ /*
+- * linux/ringbuffer/iterator.h
+- *
+- * (C) Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/iterator.h
+ *
+ * Ring buffer and channel iterators.
+ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * Author:
+ * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+- * Dual LGPL v2.1/GPL v2 license.
+ */
+
+ #include "../../wrapper/ringbuffer/backend.h"
+@@ -67,4 +79,4 @@ void channel_iterator_free(struct channe
+ void channel_iterator_reset(struct channel *chan);
+ void lib_ring_buffer_iterator_reset(struct lib_ring_buffer *buf);
+
+-#endif /* _LINUX_RING_BUFFER_ITERATOR_H */
++#endif /* _LIB_RING_BUFFER_ITERATOR_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/nohz.h
++++ b/drivers/staging/lttng/lib/ringbuffer/nohz.h
+@@ -1,12 +1,24 @@
+-#ifndef _LINUX_RING_BUFFER_NOHZ_H
+-#define _LINUX_RING_BUFFER_NOHZ_H
++#ifndef _LIB_RING_BUFFER_NOHZ_H
++#define _LIB_RING_BUFFER_NOHZ_H
+
+ /*
+- * ringbuffer/nohz.h
++ * lib/ringbuffer/nohz.h
+ *
+- * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #ifdef CONFIG_LIB_RING_BUFFER
+@@ -27,4 +39,4 @@ static inline void lib_ring_buffer_tick_
+ }
+ #endif
+
+-#endif /* _LINUX_RING_BUFFER_NOHZ_H */
++#endif /* _LIB_RING_BUFFER_NOHZ_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c
+@@ -1,9 +1,21 @@
+ /*
+ * ring_buffer_backend.c
+ *
+- * Copyright (C) 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/stddef.h>
+@@ -155,7 +167,7 @@ pages_error:
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+
+ bufb->chan = container_of(chanb, struct channel, backend);
+ bufb->cpu = cpu;
+@@ -187,7 +199,7 @@ void lib_ring_buffer_backend_free(struct
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ unsigned long num_subbuf_alloc;
+ unsigned int i;
+
+@@ -221,7 +233,7 @@ void lib_ring_buffer_backend_reset(struc
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+
+ /*
+ * Don't reset buf_size, subbuf_size, subbuf_size_order,
+@@ -248,7 +260,7 @@ int __cpuinit lib_ring_buffer_cpu_hp_cal
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ struct lib_ring_buffer *buf;
+ int ret;
+
+@@ -307,18 +319,18 @@ int channel_backend_init(struct channel_
+ 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.
++ * Make sure the number of subbuffers and subbuffer size are
++ * power of 2 and nonzero.
+ */
+- CHAN_WARN_ON(chanb, hweight32(subbuf_size) != 1);
+- CHAN_WARN_ON(chanb, hweight32(num_subbuf) != 1);
++ if (!subbuf_size || (subbuf_size & (subbuf_size - 1)))
++ return -EINVAL;
++ if (!num_subbuf || (num_subbuf & (num_subbuf - 1)))
++ return -EINVAL;
+
+ ret = subbuffer_id_check_index(config, num_subbuf);
+ if (ret)
+@@ -334,7 +346,7 @@ int channel_backend_init(struct channel_
+ (config->mode == RING_BUFFER_OVERWRITE) ? 1 : 0;
+ chanb->num_subbuf = num_subbuf;
+ strlcpy(chanb->name, name, NAME_MAX);
+- chanb->config = config;
++ memcpy(&chanb->config, config, sizeof(chanb->config));
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+ if (!zalloc_cpumask_var(&chanb->cpumask, GFP_KERNEL))
+@@ -421,7 +433,7 @@ free_cpumask:
+ */
+ void channel_backend_unregister_notifiers(struct channel_backend *chanb)
+ {
+- const struct lib_ring_buffer_config *config = chanb->config;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+ unregister_hotcpu_notifier(&chanb->cpu_hp_notifier);
+@@ -435,7 +447,7 @@ void channel_backend_unregister_notifier
+ */
+ void channel_backend_free(struct channel_backend *chanb)
+ {
+- const struct lib_ring_buffer_config *config = chanb->config;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ unsigned int i;
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+@@ -469,7 +481,7 @@ void _lib_ring_buffer_write(struct lib_r
+ 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;
++ 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;
+@@ -515,7 +527,7 @@ void _lib_ring_buffer_memset(struct lib_
+ int c, size_t len, ssize_t pagecpy)
+ {
+ struct channel_backend *chanb = &bufb->chan->backend;
+- const struct lib_ring_buffer_config *config = chanb->config;
++ 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;
+@@ -564,7 +576,7 @@ void _lib_ring_buffer_copy_from_user(str
+ ssize_t pagecpy)
+ {
+ struct channel_backend *chanb = &bufb->chan->backend;
+- const struct lib_ring_buffer_config *config = chanb->config;
++ 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;
+@@ -616,7 +628,7 @@ size_t lib_ring_buffer_read(struct lib_r
+ void *dest, size_t len)
+ {
+ struct channel_backend *chanb = &bufb->chan->backend;
+- const struct lib_ring_buffer_config *config = chanb->config;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ size_t index;
+ ssize_t pagecpy, orig_len;
+ struct lib_ring_buffer_backend_pages *rpages;
+@@ -668,7 +680,7 @@ int __lib_ring_buffer_copy_to_user(struc
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ size_t index;
+ ssize_t pagecpy;
+ struct lib_ring_buffer_backend_pages *rpages;
+@@ -719,7 +731,7 @@ int lib_ring_buffer_read_cstr(struct lib
+ void *dest, size_t len)
+ {
+ struct channel_backend *chanb = &bufb->chan->backend;
+- const struct lib_ring_buffer_config *config = chanb->config;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ size_t index;
+ ssize_t pagecpy, pagelen, strpagelen, orig_offset;
+ char *str;
+@@ -777,7 +789,7 @@ struct page **lib_ring_buffer_read_get_p
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ unsigned long sb_bindex, id;
+
+ offset &= chanb->buf_size - 1;
+@@ -808,7 +820,7 @@ void *lib_ring_buffer_read_offset_addres
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ unsigned long sb_bindex, id;
+
+ offset &= chanb->buf_size - 1;
+@@ -838,7 +850,7 @@ void *lib_ring_buffer_offset_address(str
+ 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;
++ const struct lib_ring_buffer_config *config = &chanb->config;
+ unsigned long sb_bindex, id;
+
+ offset &= chanb->buf_size - 1;
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c
+@@ -1,7 +1,22 @@
+ /*
+ * ring_buffer_frontend.c
+ *
+- * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ *
+ * Ring buffer wait-free buffer synchronization. Producer-consumer and flight
+ * recorder (overwrite) modes. See thesis:
+@@ -34,8 +49,6 @@
+ * - 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>
+@@ -103,7 +116,7 @@ void lib_ring_buffer_free(struct lib_rin
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned int i;
+
+ /*
+@@ -161,7 +174,7 @@ EXPORT_SYMBOL_GPL(channel_reset);
+ 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;
++ 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;
+@@ -253,7 +266,7 @@ static void switch_buffer_timer(unsigned
+ {
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ /*
+ * Only flush buffers periodically if readers are active.
+@@ -275,7 +288,7 @@ static void switch_buffer_timer(unsigned
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (!chan->switch_timer_interval || buf->switch_timer_enabled)
+ return;
+@@ -311,7 +324,7 @@ static void read_buffer_timer(unsigned l
+ {
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ CHAN_WARN_ON(chan, !buf->backend.allocated);
+
+@@ -335,7 +348,7 @@ static void read_buffer_timer(unsigned l
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER
+ || !chan->read_timer_interval
+@@ -360,7 +373,7 @@ static void lib_ring_buffer_start_read_t
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER
+ || !chan->read_timer_interval
+@@ -397,7 +410,7 @@ int __cpuinit lib_ring_buffer_cpu_hp_cal
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (!chan->cpu_hp_enable)
+ return NOTIFY_DONE;
+@@ -452,7 +465,7 @@ static int notrace ring_buffer_tick_nohz
+ {
+ struct channel *chan = container_of(nb, struct channel,
+ tick_nohz_notifier);
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ int cpu = smp_processor_id();
+
+@@ -524,7 +537,7 @@ void notrace lib_ring_buffer_tick_nohz_r
+ */
+ static void channel_unregister_notifiers(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ int cpu;
+
+ channel_iterator_unregister_notifiers(chan);
+@@ -708,7 +721,7 @@ void channel_release(struct kref *kref)
+ void *channel_destroy(struct channel *chan)
+ {
+ int cpu;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ void *priv;
+
+ channel_unregister_notifiers(chan);
+@@ -818,7 +831,7 @@ int lib_ring_buffer_snapshot(struct lib_
+ unsigned long *consumed, unsigned long *produced)
+ {
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long consumed_cur, write_offset;
+ int finalized;
+
+@@ -909,7 +922,7 @@ int lib_ring_buffer_get_subbuf(struct li
+ unsigned long consumed)
+ {
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long consumed_cur, consumed_idx, commit_count, write_offset;
+ int ret;
+ int finalized;
+@@ -1055,7 +1068,7 @@ void lib_ring_buffer_put_subbuf(struct l
+ {
+ struct lib_ring_buffer_backend *bufb = &buf->backend;
+ struct channel *chan = bufb->chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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);
+@@ -1114,7 +1127,7 @@ void lib_ring_buffer_print_subbuffer_err
+ unsigned long cons_offset,
+ int cpu)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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);
+@@ -1140,7 +1153,7 @@ void lib_ring_buffer_print_buffer_errors
+ struct channel *chan,
+ void *priv, int cpu)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long write_offset, cons_offset;
+
+ /*
+@@ -1170,27 +1183,34 @@ 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;
++ 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));
+-
++ if (!strcmp(chan->backend.name, "relay-metadata")) {
++ printk(KERN_DEBUG "ring buffer %s: %lu records written, "
++ "%lu records overrun\n",
++ chan->backend.name,
++ v_read(config, &buf->records_count),
++ v_read(config, &buf->records_overrun));
++ } else {
++ 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);
+ }
+
+@@ -1205,7 +1225,7 @@ void lib_ring_buffer_switch_old_start(st
+ struct switch_offsets *offsets,
+ u64 tsc)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long oldidx = subbuf_index(offsets->old, chan);
+ unsigned long commit_count;
+
+@@ -1249,7 +1269,7 @@ void lib_ring_buffer_switch_old_end(stru
+ struct switch_offsets *offsets,
+ u64 tsc)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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;
+
+@@ -1292,7 +1312,7 @@ void lib_ring_buffer_switch_new_start(st
+ struct switch_offsets *offsets,
+ u64 tsc)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long beginidx = subbuf_index(offsets->begin, chan);
+ unsigned long commit_count;
+
+@@ -1334,7 +1354,7 @@ void lib_ring_buffer_switch_new_end(stru
+ struct switch_offsets *offsets,
+ u64 tsc)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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;
+
+@@ -1376,7 +1396,7 @@ int lib_ring_buffer_try_switch_slow(enum
+ struct switch_offsets *offsets,
+ u64 *tsc)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long off;
+
+ offsets->begin = v_read(config, &buf->offset);
+@@ -1435,7 +1455,7 @@ int lib_ring_buffer_try_switch_slow(enum
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct switch_offsets offsets;
+ unsigned long oldidx;
+ u64 tsc;
+@@ -1496,7 +1516,7 @@ int lib_ring_buffer_try_reserve_slow(str
+ struct switch_offsets *offsets,
+ struct lib_ring_buffer_ctx *ctx)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ unsigned long reserve_commit_diff;
+
+ offsets->begin = v_read(config, &buf->offset);
+@@ -1631,7 +1651,7 @@ int lib_ring_buffer_try_reserve_slow(str
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ struct switch_offsets offsets;
+ int ret;
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c
+@@ -1,16 +1,28 @@
+ /*
+ * 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.
+ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * Author:
+ * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+- * Dual LGPL v2.1/GPL v2 license.
+ */
+
+ #include "../../wrapper/ringbuffer/iterator.h"
+@@ -40,7 +52,7 @@
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer_iter *iter = &buf->iter;
+ int ret;
+
+@@ -225,7 +237,7 @@ void lib_ring_buffer_wait_for_qs(const s
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ struct lttng_ptr_heap *heap;
+ ssize_t len;
+@@ -333,7 +345,7 @@ void lib_ring_buffer_iterator_init(struc
+ }
+
+ /* Add to list of buffers without any current record */
+- if (chan->backend.config->alloc == RING_BUFFER_ALLOC_PER_CPU)
++ if (chan->backend.config.alloc == RING_BUFFER_ALLOC_PER_CPU)
+ list_add(&buf->iter.empty_node, &chan->iter.empty_head);
+ }
+
+@@ -347,7 +359,7 @@ int __cpuinit channel_iterator_cpu_hotpl
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (!chan->hp_iter_enable)
+ return NOTIFY_DONE;
+@@ -369,7 +381,7 @@ int __cpuinit channel_iterator_cpu_hotpl
+
+ int channel_iterator_init(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+@@ -413,7 +425,7 @@ int channel_iterator_init(struct channel
+
+ void channel_iterator_unregister_notifiers(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) {
+ chan->hp_iter_enable = 0;
+@@ -423,7 +435,7 @@ void channel_iterator_unregister_notifie
+
+ void channel_iterator_free(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (config->alloc == RING_BUFFER_ALLOC_PER_CPU)
+ lttng_heap_free(&chan->iter.heap);
+@@ -432,7 +444,7 @@ void channel_iterator_free(struct channe
+ 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;
++ 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);
+ }
+@@ -451,7 +463,7 @@ EXPORT_SYMBOL_GPL(lib_ring_buffer_iterat
+
+ int channel_iterator_open(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ int ret = 0, cpu;
+
+@@ -484,7 +496,7 @@ EXPORT_SYMBOL_GPL(channel_iterator_open)
+
+ void channel_iterator_release(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ int cpu;
+
+@@ -527,7 +539,7 @@ void lib_ring_buffer_iterator_reset(stru
+
+ void channel_iterator_reset(struct channel *chan)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ struct lib_ring_buffer *buf;
+ int cpu;
+
+@@ -558,7 +570,7 @@ ssize_t channel_ring_buffer_file_read(st
+ struct lib_ring_buffer *buf,
+ int fusionmerge)
+ {
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ size_t read_count = 0, read_offset;
+ ssize_t len;
+
+@@ -706,7 +718,7 @@ ssize_t channel_file_read(struct file *f
+ {
+ struct inode *inode = filp->f_dentry->d_inode;
+ struct channel *chan = inode->i_private;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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,
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c
+@@ -3,11 +3,23 @@
+ *
+ * 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>
++ * Copyright (C) 2008-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Re-using content from kernel/relay.c.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; only version 2 of the License.
+ *
+- * This file is released under the GPL v2.
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Re-using code from kernel/relay.c, hence the GPLv2 license for this
++ * file.
+ */
+
+ #include <linux/module.h>
+@@ -24,12 +36,16 @@ static int lib_ring_buffer_fault(struct
+ {
+ 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;
++ 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.
+@@ -74,12 +90,15 @@ static int lib_ring_buffer_mmap_buf(stru
+ {
+ 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;
++ 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;
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c
+@@ -3,11 +3,24 @@
+ *
+ * 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>
++ * Copyright (C) 2008-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Re-using content from kernel/relay.c.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
+ *
+- * This file is released under the GPL v2.
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ * Re-using code from kernel/relay.c, which is why it is licensed under
++ * the GPLv2.
+ */
+
+ #include <linux/module.h>
+@@ -69,7 +82,7 @@ static int subbuf_splice_actor(struct fi
+ {
+ struct lib_ring_buffer *buf = in->private_data;
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ 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];
+@@ -151,7 +164,7 @@ ssize_t lib_ring_buffer_splice_read(stru
+ {
+ struct lib_ring_buffer *buf = in->private_data;
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ ssize_t spliced;
+ int ret;
+
+--- a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
++++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c
+@@ -1,11 +1,23 @@
+ /*
+ * 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.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+@@ -88,7 +100,7 @@ unsigned int lib_ring_buffer_poll(struct
+ 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;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+ int finalized, disabled;
+
+ if (filp->f_mode & FMODE_READ) {
+@@ -165,7 +177,7 @@ long lib_ring_buffer_ioctl(struct file *
+ {
+ struct lib_ring_buffer *buf = filp->private_data;
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (lib_ring_buffer_channel_is_disabled(chan))
+ return -EIO;
+@@ -262,7 +274,7 @@ long lib_ring_buffer_compat_ioctl(struct
+ {
+ struct lib_ring_buffer *buf = filp->private_data;
+ struct channel *chan = buf->backend.chan;
+- const struct lib_ring_buffer_config *config = chan->backend.config;
++ const struct lib_ring_buffer_config *config = &chan->backend.config;
+
+ if (lib_ring_buffer_channel_is_disabled(chan))
+ return -EIO;
+--- a/drivers/staging/lttng/lib/ringbuffer/vatomic.h
++++ b/drivers/staging/lttng/lib/ringbuffer/vatomic.h
+@@ -1,12 +1,24 @@
+-#ifndef _LINUX_RING_BUFFER_VATOMIC_H
+-#define _LINUX_RING_BUFFER_VATOMIC_H
++#ifndef _LIB_RING_BUFFER_VATOMIC_H
++#define _LIB_RING_BUFFER_VATOMIC_H
+
+ /*
+- * linux/ringbuffer/vatomic.h
++ * lib/ringbuffer/vatomic.h
+ *
+- * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <asm/atomic.h>
+@@ -82,4 +94,4 @@ long v_cmpxchg(const struct lib_ring_buf
+ return atomic_long_cmpxchg(&v_a->a, old, _new);
+ }
+
+-#endif /* _LINUX_RING_BUFFER_VATOMIC_H */
++#endif /* _LIB_RING_BUFFER_VATOMIC_H */
+--- a/drivers/staging/lttng/lib/ringbuffer/vfs.h
++++ b/drivers/staging/lttng/lib/ringbuffer/vfs.h
+@@ -1,17 +1,29 @@
+-#ifndef _LINUX_RING_BUFFER_VFS_H
+-#define _LINUX_RING_BUFFER_VFS_H
++#ifndef _LIB_RING_BUFFER_VFS_H
++#define _LIB_RING_BUFFER_VFS_H
+
+ /*
+- * linux/ringbuffer/vfs.h
+- *
+- * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lib/ringbuffer/vfs.h
+ *
+ * Wait-free ring buffer VFS file operations.
+ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
+ * Author:
+ * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+- * Dual LGPL v2.1/GPL v2 license.
+ */
+
+ #include <linux/fs.h>
+@@ -86,4 +98,4 @@ long lib_ring_buffer_compat_ioctl(struct
+ /* flush the current sub-buffer */
+ #define RING_BUFFER_FLUSH _IO(0xF6, 0x0C)
+
+-#endif /* _LINUX_RING_BUFFER_VFS_H */
++#endif /* _LIB_RING_BUFFER_VFS_H */
+--- a/drivers/staging/lttng/ltt-context.c
++++ /dev/null
+@@ -1,93 +0,0 @@
+-/*
+- * 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);
+-}
+--- a/drivers/staging/lttng/ltt-debugfs-abi.c
++++ /dev/null
+@@ -1,777 +0,0 @@
+-/*
+- * 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);
+-}
+--- a/drivers/staging/lttng/ltt-debugfs-abi.h
++++ /dev/null
+@@ -1,153 +0,0 @@
+-#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 256
+-
+-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 */
+--- a/drivers/staging/lttng/ltt-endian.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-#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 */
+--- a/drivers/staging/lttng/ltt-events.c
++++ /dev/null
+@@ -1,1009 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-events.h
++++ /dev/null
+@@ -1,452 +0,0 @@
+-#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 */
+- uint signedness:1;
+- uint 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 */
+- uint 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 */
+- uint 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 */
+- uint 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 */
+--- a/drivers/staging/lttng/ltt-probes.c
++++ /dev/null
+@@ -1,164 +0,0 @@
+-/*
+- * 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,
+-};
+--- a/drivers/staging/lttng/ltt-ring-buffer-client-discard.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-client.h
++++ /dev/null
+@@ -1,569 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h
++++ /dev/null
+@@ -1,330 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c
++++ /dev/null
+@@ -1,21 +0,0 @@
+-/*
+- * 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");
+--- a/drivers/staging/lttng/ltt-tracer-core.h
++++ /dev/null
+@@ -1,28 +0,0 @@
+-#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 */
+--- a/drivers/staging/lttng/ltt-tracer.h
++++ /dev/null
+@@ -1,67 +0,0 @@
+-#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 */
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-abi.c
+@@ -0,0 +1,781 @@
++/*
++ * lttng-abi.c
++ *
++ * LTTng ABI
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ *
++ * 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.
++ */
++
++#include <linux/module.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 "lttng-abi.h"
++#include "lttng-events.h"
++#include "lttng-tracer.h"
++
++/*
++ * This is LTTng's own personal way to create a system call as an external
++ * module. We use ioctl() on /proc/lttng.
++ */
++
++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 lttng_session *session;
++ struct file *session_file;
++ int session_fd, ret;
++
++ session = lttng_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:
++ lttng_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.major = LTTNG_MODULES_MAJOR_VERSION;
++ v.minor = LTTNG_MODULES_MINOR_VERSION;
++ v.patchlevel = LTTNG_MODULES_PATCHLEVEL_VERSION;
++
++ 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 lttng_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_KERNEL_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 lttng_channel *channel = channel_file->private_data;
++ static struct lttng_kernel_event metadata_params = {
++ .instrumentation = LTTNG_KERNEL_TRACEPOINT,
++ .name = "lttng_metadata",
++ };
++ struct lttng_event *event;
++
++ /*
++ * We tolerate no failure path after event creation. It will stay
++ * invariant for the rest of the session.
++ */
++ event = lttng_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 lttng_session *session = session_file->private_data;
++ const struct file_operations *fops = NULL;
++ const char *transport_name;
++ struct lttng_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 = lttng_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 lttng_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 lttng_session_enable(session);
++ case LTTNG_KERNEL_SESSION_STOP:
++ case LTTNG_KERNEL_DISABLE:
++ return lttng_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 lttng_session *session = file->private_data;
++
++ if (session)
++ lttng_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 lttng_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 lttng_channel *channel = channel_file->private_data;
++ struct lttng_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_KERNEL_SYM_NAME_LEN - 1] = '\0';
++ switch (event_param.instrumentation) {
++ case LTTNG_KERNEL_KRETPROBE:
++ event_param.u.kretprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
++ break;
++ case LTTNG_KERNEL_KPROBE:
++ event_param.u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
++ break;
++ case LTTNG_KERNEL_FUNCTION:
++ event_param.u.ftrace.symbol_name[LTTNG_KERNEL_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 = lttng_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 lttng_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 lttng_channel_enable(channel);
++ case LTTNG_KERNEL_DISABLE:
++ return lttng_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 lttng_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 lttng_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 lttng_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 lttng_event_enable(event);
++ case LTTNG_KERNEL_DISABLE:
++ return lttng_event_disable(event);
++ default:
++ return -ENOIOCTLCMD;
++ }
++}
++
++static
++int lttng_event_release(struct inode *inode, struct file *file)
++{
++ struct lttng_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 lttng_abi_init(void)
++{
++ int ret = 0;
++
++ wrapper_vmalloc_sync_all();
++ lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL,
++ &lttng_fops, NULL);
++
++ if (!lttng_proc_dentry) {
++ printk(KERN_ERR "Error creating LTTng control file\n");
++ ret = -ENOMEM;
++ goto error;
++ }
++error:
++ return ret;
++}
++
++void __exit lttng_abi_exit(void)
++{
++ if (lttng_proc_dentry)
++ remove_proc_entry("lttng", NULL);
++}
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-abi.h
+@@ -0,0 +1,176 @@
++#ifndef _LTTNG_ABI_H
++#define _LTTNG_ABI_H
++
++/*
++ * lttng-abi.h
++ *
++ * LTTng ABI header
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/fs.h>
++
++#define LTTNG_KERNEL_SYM_NAME_LEN 256
++
++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.
++ */
++#define LTTNG_KERNEL_CHANNEL_PADDING LTTNG_KERNEL_SYM_NAME_LEN + 32
++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 */
++ char padding[LTTNG_KERNEL_CHANNEL_PADDING];
++};
++
++struct lttng_kernel_kretprobe {
++ uint64_t addr;
++
++ uint64_t offset;
++ char symbol_name[LTTNG_KERNEL_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_KERNEL_SYM_NAME_LEN];
++};
++
++struct lttng_kernel_function_tracer {
++ char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN];
++};
++
++/*
++ * For syscall tracing, name = '\0' means "enable all".
++ */
++#define LTTNG_KERNEL_EVENT_PADDING1 16
++#define LTTNG_KERNEL_EVENT_PADDING2 LTTNG_KERNEL_SYM_NAME_LEN + 32
++struct lttng_kernel_event {
++ char name[LTTNG_KERNEL_SYM_NAME_LEN]; /* event name */
++ enum lttng_kernel_instrumentation instrumentation;
++ char padding[LTTNG_KERNEL_EVENT_PADDING1];
++
++ /* Per instrumentation type configuration */
++ union {
++ struct lttng_kernel_kretprobe kretprobe;
++ struct lttng_kernel_kprobe kprobe;
++ struct lttng_kernel_function_tracer ftrace;
++ char padding[LTTNG_KERNEL_EVENT_PADDING2];
++ } u;
++};
++
++struct lttng_kernel_tracer_version {
++ uint32_t major;
++ uint32_t minor;
++ uint32_t patchlevel;
++};
++
++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_KERNEL_SYM_NAME_LEN];
++};
++
++#define LTTNG_KERNEL_CONTEXT_PADDING1 16
++#define LTTNG_KERNEL_CONTEXT_PADDING2 LTTNG_KERNEL_SYM_NAME_LEN + 32
++struct lttng_kernel_context {
++ enum lttng_kernel_context_type ctx;
++ char padding[LTTNG_KERNEL_CONTEXT_PADDING1];
++
++ union {
++ struct lttng_kernel_perf_counter_ctx perf_counter;
++ char padding[LTTNG_KERNEL_CONTEXT_PADDING2];
++ } 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 /* _LTTNG_ABI_H */
+--- a/drivers/staging/lttng/lttng-calibrate.c
++++ b/drivers/staging/lttng/lttng-calibrate.c
+@@ -1,15 +1,27 @@
+ /*
+ * lttng-calibrate.c
+ *
+- * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng probe calibration.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+-#include "ltt-debugfs-abi.h"
+-#include "ltt-events.h"
++#include "lttng-abi.h"
++#include "lttng-events.h"
+
+ noinline
+ void lttng_calibrate_kretprobe(void)
+--- a/drivers/staging/lttng/lttng-context-nice.c
++++ b/drivers/staging/lttng/lttng-context-nice.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-nice.c
+ *
+ * LTTng nice context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(int));
+ size += sizeof(int);
+ return size;
+ }
+@@ -28,12 +41,12 @@ size_t nice_get_size(size_t offset)
+ static
+ void nice_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ int nice;
+
+ nice = task_nice(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(nice));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(nice));
+ chan->ops->event_write(ctx, &nice, sizeof(nice));
+ }
+
+@@ -51,7 +64,7 @@ int lttng_add_nice_to_ctx(struct lttng_c
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-perf-counters.c
++++ b/drivers/staging/lttng/lttng-context-perf-counters.c
+@@ -1,10 +1,23 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-perf-counters.c
+ *
+ * LTTng performance monitoring counters (perf-counters) integration module.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+@@ -12,18 +25,18 @@
+ #include <linux/perf_event.h>
+ #include <linux/list.h>
+ #include <linux/string.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+ #include "wrapper/perf.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(uint64_t));
+ size += sizeof(uint64_t);
+ return size;
+ }
+@@ -31,7 +44,7 @@ size_t perf_counter_get_size(size_t offs
+ static
+ void perf_counter_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ struct perf_event *event;
+ uint64_t value;
+@@ -54,7 +67,7 @@ void perf_counter_record(struct lttng_ct
+ */
+ value = 0;
+ }
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(value));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(value));
+ chan->ops->event_write(ctx, &value, sizeof(value));
+ }
+
+@@ -230,7 +243,7 @@ int lttng_add_perf_counter_to_ctx(uint32
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-pid.c
++++ b/drivers/staging/lttng/lttng-context-pid.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-pid.c
+ *
+ * LTTng PID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -28,12 +41,12 @@ size_t pid_get_size(size_t offset)
+ static
+ void pid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ pid_t pid;
+
+ pid = task_tgid_nr(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(pid));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(pid));
+ chan->ops->event_write(ctx, &pid, sizeof(pid));
+ }
+
+@@ -51,7 +64,7 @@ int lttng_add_pid_to_ctx(struct lttng_ct
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-ppid.c
++++ b/drivers/staging/lttng/lttng-context-ppid.c
+@@ -1,27 +1,40 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-ppid.c
+ *
+ * LTTng PPID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+ #include <linux/syscalls.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -29,14 +42,14 @@ size_t ppid_get_size(size_t offset)
+ static
+ void ppid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_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));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(ppid));
+ chan->ops->event_write(ctx, &ppid, sizeof(ppid));
+ }
+
+@@ -54,7 +67,7 @@ int lttng_add_ppid_to_ctx(struct lttng_c
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-prio.c
++++ b/drivers/staging/lttng/lttng-context-prio.c
+@@ -1,20 +1,33 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-prio.c
+ *
+ * LTTng priority context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+ #include "wrapper/kallsyms.h"
+-#include "ltt-tracer.h"
++#include "lttng-tracer.h"
+
+ static
+ int (*wrapper_task_prio_sym)(struct task_struct *t);
+@@ -34,7 +47,7 @@ size_t prio_get_size(size_t offset)
+ {
+ size_t size = 0;
+
+- size += lib_ring_buffer_align(offset, ltt_alignof(int));
++ size += lib_ring_buffer_align(offset, lttng_alignof(int));
+ size += sizeof(int);
+ return size;
+ }
+@@ -42,12 +55,12 @@ size_t prio_get_size(size_t offset)
+ static
+ void prio_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ int prio;
+
+ prio = wrapper_task_prio_sym(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(prio));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(prio));
+ chan->ops->event_write(ctx, &prio, sizeof(prio));
+ }
+
+@@ -72,7 +85,7 @@ int lttng_add_prio_to_ctx(struct lttng_c
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-procname.c
++++ b/drivers/staging/lttng/lttng-context-procname.c
+@@ -1,19 +1,32 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-procname.c
+ *
+ * LTTng procname context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-tracer.h"
+
+ static
+ size_t procname_get_size(size_t offset)
+@@ -33,7 +46,7 @@ size_t procname_get_size(size_t offset)
+ static
+ void procname_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ chan->ops->event_write(ctx, current->comm, sizeof(current->comm));
+ }
+@@ -53,7 +66,7 @@ int lttng_add_procname_to_ctx(struct ltt
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-tid.c
++++ b/drivers/staging/lttng/lttng-context-tid.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-tid.c
+ *
+ * LTTng TID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -28,12 +41,12 @@ size_t tid_get_size(size_t offset)
+ static
+ void tid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ pid_t tid;
+
+ tid = task_pid_nr(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(tid));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(tid));
+ chan->ops->event_write(ctx, &tid, sizeof(tid));
+ }
+
+@@ -51,7 +64,7 @@ int lttng_add_tid_to_ctx(struct lttng_ct
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-vpid.c
++++ b/drivers/staging/lttng/lttng-context-vpid.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-vpid.c
+ *
+ * LTTng vPID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -28,7 +41,7 @@ size_t vpid_get_size(size_t offset)
+ static
+ void vpid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ pid_t vpid;
+
+@@ -39,7 +52,7 @@ void vpid_record(struct lttng_ctx_field
+ vpid = 0;
+ else
+ vpid = task_tgid_vnr(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(vpid));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(vpid));
+ chan->ops->event_write(ctx, &vpid, sizeof(vpid));
+ }
+
+@@ -57,7 +70,7 @@ int lttng_add_vpid_to_ctx(struct lttng_c
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-vppid.c
++++ b/drivers/staging/lttng/lttng-context-vppid.c
+@@ -1,27 +1,40 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-vppid.c
+ *
+ * LTTng vPPID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+ #include <linux/syscalls.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -29,7 +42,7 @@ size_t vppid_get_size(size_t offset)
+ static
+ void vppid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ struct task_struct *parent;
+ pid_t vppid;
+@@ -44,7 +57,7 @@ void vppid_record(struct lttng_ctx_field
+ else
+ vppid = task_tgid_vnr(parent);
+ rcu_read_unlock();
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(vppid));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(vppid));
+ chan->ops->event_write(ctx, &vppid, sizeof(vppid));
+ }
+
+@@ -62,7 +75,7 @@ int lttng_add_vppid_to_ctx(struct lttng_
+ 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.alignment = lttng_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;
+--- a/drivers/staging/lttng/lttng-context-vtid.c
++++ b/drivers/staging/lttng/lttng-context-vtid.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * lttng-context-vtid.c
+ *
+ * LTTng vTID context.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/sched.h>
+-#include "ltt-events.h"
++#include "lttng-events.h"
+ #include "wrapper/ringbuffer/frontend_types.h"
+ #include "wrapper/vmalloc.h"
+-#include "ltt-tracer.h"
++#include "lttng-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 += lib_ring_buffer_align(offset, lttng_alignof(pid_t));
+ size += sizeof(pid_t);
+ return size;
+ }
+@@ -28,7 +41,7 @@ size_t vtid_get_size(size_t offset)
+ static
+ void vtid_record(struct lttng_ctx_field *field,
+ struct lib_ring_buffer_ctx *ctx,
+- struct ltt_channel *chan)
++ struct lttng_channel *chan)
+ {
+ pid_t vtid;
+
+@@ -39,7 +52,7 @@ void vtid_record(struct lttng_ctx_field
+ vtid = 0;
+ else
+ vtid = task_pid_vnr(current);
+- lib_ring_buffer_align_ctx(ctx, ltt_alignof(vtid));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(vtid));
+ chan->ops->event_write(ctx, &vtid, sizeof(vtid));
+ }
+
+@@ -57,7 +70,7 @@ int lttng_add_vtid_to_ctx(struct lttng_c
+ 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.alignment = lttng_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;
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-context.c
+@@ -0,0 +1,105 @@
++/*
++ * lttng-context.c
++ *
++ * LTTng trace/channel/event context management.
++ *
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 "lttng-events.h"
++#include "lttng-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);
++}
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-endian.h
+@@ -0,0 +1,43 @@
++#ifndef _LTTNG_ENDIAN_H
++#define _LTTNG_ENDIAN_H
++
++/*
++ * lttng-endian.h
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 /* _LTTNG_ENDIAN_H */
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-events.c
+@@ -0,0 +1,1126 @@
++/*
++ * lttng-events.c
++ *
++ * Holds LTTng per-session event registry.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 <linux/utsname.h>
++#include "wrapper/uuid.h"
++#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
++#include "wrapper/random.h"
++#include "lttng-events.h"
++#include "lttng-tracer.h"
++
++static LIST_HEAD(sessions);
++static LIST_HEAD(lttng_transport_list);
++static DEFINE_MUTEX(sessions_mutex);
++static struct kmem_cache *event_cache;
++
++static void _lttng_event_destroy(struct lttng_event *event);
++static void _lttng_channel_destroy(struct lttng_channel *chan);
++static int _lttng_event_unregister(struct lttng_event *event);
++static
++int _lttng_event_metadata_statedump(struct lttng_session *session,
++ struct lttng_channel *chan,
++ struct lttng_event *event);
++static
++int _lttng_session_metadata_statedump(struct lttng_session *session);
++
++void synchronize_trace(void)
++{
++ synchronize_sched();
++#ifdef CONFIG_PREEMPT_RT
++ synchronize_rcu();
++#endif
++}
++
++struct lttng_session *lttng_session_create(void)
++{
++ struct lttng_session *session;
++
++ mutex_lock(&sessions_mutex);
++ session = kzalloc(sizeof(struct lttng_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 lttng_session_destroy(struct lttng_session *session)
++{
++ struct lttng_channel *chan, *tmpchan;
++ struct lttng_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 = _lttng_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)
++ _lttng_event_destroy(event);
++ list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
++ _lttng_channel_destroy(chan);
++ list_del(&session->list);
++ mutex_unlock(&sessions_mutex);
++ kfree(session);
++}
++
++int lttng_session_enable(struct lttng_session *session)
++{
++ int ret = 0;
++ struct lttng_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 = _lttng_session_metadata_statedump(session);
++ if (ret) {
++ ACCESS_ONCE(session->active) = 0;
++ goto end;
++ }
++ ret = lttng_statedump_start(session);
++ if (ret)
++ ACCESS_ONCE(session->active) = 0;
++end:
++ mutex_unlock(&sessions_mutex);
++ return ret;
++}
++
++int lttng_session_disable(struct lttng_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 lttng_channel_enable(struct lttng_channel *channel)
++{
++ int old;
++
++ if (channel == channel->session->metadata)
++ return -EPERM;
++ old = xchg(&channel->enabled, 1);
++ if (old)
++ return -EEXIST;
++ return 0;
++}
++
++int lttng_channel_disable(struct lttng_channel *channel)
++{
++ int old;
++
++ if (channel == channel->session->metadata)
++ return -EPERM;
++ old = xchg(&channel->enabled, 0);
++ if (!old)
++ return -EEXIST;
++ return 0;
++}
++
++int lttng_event_enable(struct lttng_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 lttng_event_disable(struct lttng_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 lttng_transport *lttng_transport_find(const char *name)
++{
++ struct lttng_transport *transport;
++
++ list_for_each_entry(transport, &lttng_transport_list, node) {
++ if (!strcmp(transport->name, name))
++ return transport;
++ }
++ return NULL;
++}
++
++struct lttng_channel *lttng_channel_create(struct lttng_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 lttng_channel *chan;
++ struct lttng_transport *transport = NULL;
++
++ mutex_lock(&sessions_mutex);
++ if (session->been_active)
++ goto active; /* Refuse to add channel to active session */
++ transport = lttng_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 lttng_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(transport_name,
++ 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 _lttng_channel_destroy(struct lttng_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 lttng_event *lttng_event_create(struct lttng_channel *chan,
++ struct lttng_kernel_event *event_param,
++ void *filter,
++ const struct lttng_event_desc *internal_desc)
++{
++ struct lttng_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 lttng_event structure before tracepoint registration. */
++ smp_wmb();
++ switch (event_param->instrumentation) {
++ case LTTNG_KERNEL_TRACEPOINT:
++ event->desc = lttng_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 lttng_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 lttng_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 = _lttng_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 = _lttng_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 _lttng_event_unregister(struct lttng_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 _lttng_event_destroy(struct lttng_event *event)
++{
++ switch (event->instrumentation) {
++ case LTTNG_KERNEL_TRACEPOINT:
++ lttng_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 lttng_session *session,
++ const char *fmt, ...)
++{
++ struct lib_ring_buffer_ctx ctx;
++ struct lttng_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 _lttng_field_statedump(struct lttng_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 _lttng_context_metadata_statedump(struct lttng_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 = _lttng_field_statedump(session, &field->event_field);
++ if (ret)
++ return ret;
++ }
++ return ret;
++}
++
++static
++int _lttng_fields_metadata_statedump(struct lttng_session *session,
++ struct lttng_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 = _lttng_field_statedump(session, field);
++ if (ret)
++ return ret;
++ }
++ return ret;
++}
++
++static
++int _lttng_event_metadata_statedump(struct lttng_session *session,
++ struct lttng_channel *chan,
++ struct lttng_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 = _lttng_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 = _lttng_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 _lttng_channel_metadata_statedump(struct lttng_session *session,
++ struct lttng_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 = _lttng_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 _lttng_stream_packet_context_declare(struct lttng_session *session)
++{
++ return lttng_metadata_printf(session,
++ "struct packet_context {\n"
++ " uint64_clock_monotonic_t timestamp_begin;\n"
++ " uint64_clock_monotonic_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 _lttng_event_header_declare(struct lttng_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_clock_monotonic_t timestamp;\n"
++ " } compact;\n"
++ " struct {\n"
++ " uint32_t id;\n"
++ " uint64_clock_monotonic_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_clock_monotonic_t timestamp;\n"
++ " } compact;\n"
++ " struct {\n"
++ " uint32_t id;\n"
++ " uint64_clock_monotonic_t timestamp;\n"
++ " } extended;\n"
++ " } v;\n"
++ "} align(%u);\n\n",
++ lttng_alignof(uint32_t) * CHAR_BIT,
++ lttng_alignof(uint16_t) * CHAR_BIT
++ );
++}
++
++ /*
++ * Approximation of NTP time of day to clock monotonic correlation,
++ * taken at start of trace.
++ * Yes, this is only an approximation. Yes, we can (and will) do better
++ * in future versions.
++ */
++static
++uint64_t measure_clock_offset(void)
++{
++ uint64_t offset, monotonic[2], realtime;
++ struct timespec rts = { 0, 0 };
++ unsigned long flags;
++
++ /* Disable interrupts to increase correlation precision. */
++ local_irq_save(flags);
++ monotonic[0] = trace_clock_read64();
++ getnstimeofday(&rts);
++ monotonic[1] = trace_clock_read64();
++ local_irq_restore(flags);
++
++ offset = (monotonic[0] + monotonic[1]) >> 1;
++ realtime = (uint64_t) rts.tv_sec * NSEC_PER_SEC;
++ realtime += rts.tv_nsec;
++ offset = realtime - offset;
++ return offset;
++}
++
++/*
++ * Output metadata into this session's metadata buffers.
++ */
++static
++int _lttng_session_metadata_statedump(struct lttng_session *session)
++{
++ unsigned char *uuid_c = session->uuid.b;
++ unsigned char uuid_s[37], clock_uuid_s[BOOT_ID_LEN];
++ struct lttng_channel *chan;
++ struct lttng_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",
++ lttng_alignof(uint8_t) * CHAR_BIT,
++ lttng_alignof(uint16_t) * CHAR_BIT,
++ lttng_alignof(uint32_t) * CHAR_BIT,
++ lttng_alignof(uint64_t) * CHAR_BIT,
++ CTF_SPEC_MAJOR,
++ CTF_SPEC_MINOR,
++ uuid_s,
++#ifdef __BIG_ENDIAN
++ "be"
++#else
++ "le"
++#endif
++ );
++ if (ret)
++ goto end;
++
++ ret = lttng_metadata_printf(session,
++ "env {\n"
++ " domain = \"kernel\";\n"
++ " sysname = \"%s\";\n"
++ " kernel_release = \"%s\";\n"
++ " kernel_version = \"%s\";\n"
++ " tracer_name = \"lttng-modules\";\n"
++ " tracer_major = %d;\n"
++ " tracer_minor = %d;\n"
++ " tracer_patchlevel = %d;\n"
++ "};\n\n",
++ utsname()->sysname,
++ utsname()->release,
++ utsname()->version,
++ LTTNG_MODULES_MAJOR_VERSION,
++ LTTNG_MODULES_MINOR_VERSION,
++ LTTNG_MODULES_PATCHLEVEL_VERSION
++ );
++ if (ret)
++ goto end;
++
++ ret = lttng_metadata_printf(session,
++ "clock {\n"
++ " name = %s;\n",
++ "monotonic"
++ );
++ if (ret)
++ goto end;
++
++ if (!trace_clock_uuid(clock_uuid_s)) {
++ ret = lttng_metadata_printf(session,
++ " uuid = \"%s\";\n",
++ clock_uuid_s
++ );
++ if (ret)
++ goto end;
++ }
++
++ ret = lttng_metadata_printf(session,
++ " description = \"Monotonic Clock\";\n"
++ " freq = %llu; /* Frequency, in Hz */\n"
++ " /* clock value offset from Epoch is: offset * (1/freq) */\n"
++ " offset = %llu;\n"
++ "};\n\n",
++ (unsigned long long) trace_clock_freq(),
++ (unsigned long long) measure_clock_offset()
++ );
++ if (ret)
++ goto end;
++
++ ret = lttng_metadata_printf(session,
++ "typealias integer {\n"
++ " size = 27; align = 1; signed = false;\n"
++ " map = clock.monotonic.value;\n"
++ "} := uint27_clock_monotonic_t;\n"
++ "\n"
++ "typealias integer {\n"
++ " size = 32; align = %u; signed = false;\n"
++ " map = clock.monotonic.value;\n"
++ "} := uint32_clock_monotonic_t;\n"
++ "\n"
++ "typealias integer {\n"
++ " size = 64; align = %u; signed = false;\n"
++ " map = clock.monotonic.value;\n"
++ "} := uint64_clock_monotonic_t;\n\n",
++ lttng_alignof(uint32_t) * CHAR_BIT,
++ lttng_alignof(uint64_t) * CHAR_BIT
++ );
++ if (ret)
++ goto end;
++
++ ret = _lttng_stream_packet_context_declare(session);
++ if (ret)
++ goto end;
++
++ ret = _lttng_event_header_declare(session);
++ if (ret)
++ goto end;
++
++skip_session:
++ list_for_each_entry(chan, &session->chan, list) {
++ ret = _lttng_channel_metadata_statedump(session, chan);
++ if (ret)
++ goto end;
++ }
++
++ list_for_each_entry(event, &session->events, list) {
++ ret = _lttng_event_metadata_statedump(session, event->chan, event);
++ if (ret)
++ goto end;
++ }
++ session->metadata_dumped = 1;
++end:
++ return ret;
++}
++
++/**
++ * lttng_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 lttng_transport_register(struct lttng_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, &lttng_transport_list);
++ mutex_unlock(&sessions_mutex);
++}
++EXPORT_SYMBOL_GPL(lttng_transport_register);
++
++/**
++ * lttng_transport_unregister - LTT transport unregistration
++ * @transport: transport structure
++ */
++void lttng_transport_unregister(struct lttng_transport *transport)
++{
++ mutex_lock(&sessions_mutex);
++ list_del(&transport->node);
++ mutex_unlock(&sessions_mutex);
++}
++EXPORT_SYMBOL_GPL(lttng_transport_unregister);
++
++static int __init lttng_events_init(void)
++{
++ int ret;
++
++ event_cache = KMEM_CACHE(lttng_event, 0);
++ if (!event_cache)
++ return -ENOMEM;
++ ret = lttng_abi_init();
++ if (ret)
++ goto error_abi;
++ return 0;
++error_abi:
++ kmem_cache_destroy(event_cache);
++ return ret;
++}
++
++module_init(lttng_events_init);
++
++static void __exit lttng_events_exit(void)
++{
++ struct lttng_session *session, *tmpsession;
++
++ lttng_abi_exit();
++ list_for_each_entry_safe(session, tmpsession, &sessions, list)
++ lttng_session_destroy(session);
++ kmem_cache_destroy(event_cache);
++}
++
++module_exit(lttng_events_exit);
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
++MODULE_DESCRIPTION("LTTng Events");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-events.h
+@@ -0,0 +1,466 @@
++#ifndef _LTTNG_EVENTS_H
++#define _LTTNG_EVENTS_H
++
++/*
++ * lttng-events.h
++ *
++ * Holds LTTng per-session event registry.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/list.h>
++#include <linux/kprobes.h>
++#include "wrapper/uuid.h"
++#include "lttng-abi.h"
++
++#undef is_signed_type
++#define is_signed_type(type) (((type)(-1)) < 0)
++
++struct lttng_channel;
++struct lttng_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 = lttng_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,
++ 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 lttng_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 */
++
++/*
++ * lttng_event structure is referred to by the tracing fast path. It must be
++ * kept small.
++ */
++struct lttng_event {
++ unsigned int id;
++ struct lttng_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 */
++ unsigned int metadata_dumped:1;
++};
++
++struct lttng_channel_ops {
++ struct channel *(*channel_create)(const char *name,
++ struct lttng_channel *lttng_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 lttng_transport {
++ char *name;
++ struct module *owner;
++ struct list_head node;
++ struct lttng_channel_ops ops;
++};
++
++struct lttng_channel {
++ unsigned int id;
++ struct channel *chan; /* Channel buffers */
++ int enabled;
++ struct lttng_ctx *ctx;
++ /* Event ID management */
++ struct lttng_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 lttng_channel_ops *ops;
++ struct lttng_transport *transport;
++ struct lttng_event **sc_table; /* for syscall tracing */
++ struct lttng_event **compat_sc_table;
++ struct lttng_event *sc_unknown; /* for unknown syscalls */
++ struct lttng_event *sc_compat_unknown;
++ struct lttng_event *sc_exit; /* for syscall exit */
++ int header_type; /* 0: unset, 1: compact, 2: large */
++ unsigned int metadata_dumped:1;
++};
++
++struct lttng_session {
++ int active; /* Is trace session active ? */
++ int been_active; /* Has trace session been active ? */
++ struct file *file; /* File associated to session */
++ struct lttng_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 */
++ unsigned int metadata_dumped:1;
++};
++
++struct lttng_session *lttng_session_create(void);
++int lttng_session_enable(struct lttng_session *session);
++int lttng_session_disable(struct lttng_session *session);
++void lttng_session_destroy(struct lttng_session *session);
++
++struct lttng_channel *lttng_channel_create(struct lttng_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 lttng_channel *lttng_global_channel_create(struct lttng_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 lttng_event *lttng_event_create(struct lttng_channel *chan,
++ struct lttng_kernel_event *event_param,
++ void *filter,
++ const struct lttng_event_desc *internal_desc);
++
++int lttng_channel_enable(struct lttng_channel *channel);
++int lttng_channel_disable(struct lttng_channel *channel);
++int lttng_event_enable(struct lttng_event *event);
++int lttng_event_disable(struct lttng_event *event);
++
++void lttng_transport_register(struct lttng_transport *transport);
++void lttng_transport_unregister(struct lttng_transport *transport);
++
++void synchronize_trace(void);
++int lttng_abi_init(void);
++void lttng_abi_exit(void);
++
++int lttng_probe_register(struct lttng_probe_desc *desc);
++void lttng_probe_unregister(struct lttng_probe_desc *desc);
++const struct lttng_event_desc *lttng_event_get(const char *name);
++void lttng_event_put(const struct lttng_event_desc *desc);
++int lttng_probes_init(void);
++void lttng_probes_exit(void);
++
++#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
++int lttng_syscalls_register(struct lttng_channel *chan, void *filter);
++int lttng_syscalls_unregister(struct lttng_channel *chan);
++#else
++static inline int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
++{
++ return -ENOSYS;
++}
++
++static inline int lttng_syscalls_unregister(struct lttng_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
++
++extern int lttng_statedump_start(struct lttng_session *session);
++
++#ifdef CONFIG_KPROBES
++int lttng_kprobes_register(const char *name,
++ const char *symbol_name,
++ uint64_t offset,
++ uint64_t addr,
++ struct lttng_event *event);
++void lttng_kprobes_unregister(struct lttng_event *event);
++void lttng_kprobes_destroy_private(struct lttng_event *event);
++#else
++static inline
++int lttng_kprobes_register(const char *name,
++ const char *symbol_name,
++ uint64_t offset,
++ uint64_t addr,
++ struct lttng_event *event)
++{
++ return -ENOSYS;
++}
++
++static inline
++void lttng_kprobes_unregister(struct lttng_event *event)
++{
++}
++
++static inline
++void lttng_kprobes_destroy_private(struct lttng_event *event)
++{
++}
++#endif
++
++#ifdef CONFIG_KRETPROBES
++int lttng_kretprobes_register(const char *name,
++ const char *symbol_name,
++ uint64_t offset,
++ uint64_t addr,
++ struct lttng_event *event_entry,
++ struct lttng_event *event_exit);
++void lttng_kretprobes_unregister(struct lttng_event *event);
++void lttng_kretprobes_destroy_private(struct lttng_event *event);
++#else
++static inline
++int lttng_kretprobes_register(const char *name,
++ const char *symbol_name,
++ uint64_t offset,
++ uint64_t addr,
++ struct lttng_event *event_entry,
++ struct lttng_event *event_exit)
++{
++ return -ENOSYS;
++}
++
++static inline
++void lttng_kretprobes_unregister(struct lttng_event *event)
++{
++}
++
++static inline
++void lttng_kretprobes_destroy_private(struct lttng_event *event)
++{
++}
++#endif
++
++#ifdef CONFIG_DYNAMIC_FTRACE
++int lttng_ftrace_register(const char *name,
++ const char *symbol_name,
++ struct lttng_event *event);
++void lttng_ftrace_unregister(struct lttng_event *event);
++void lttng_ftrace_destroy_private(struct lttng_event *event);
++#else
++static inline
++int lttng_ftrace_register(const char *name,
++ const char *symbol_name,
++ struct lttng_event *event)
++{
++ return -ENOSYS;
++}
++
++static inline
++void lttng_ftrace_unregister(struct lttng_event *event)
++{
++}
++
++static inline
++void lttng_ftrace_destroy_private(struct lttng_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 /* _LTTNG_EVENTS_H */
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-probes.c
+@@ -0,0 +1,176 @@
++/*
++ * lttng-probes.c
++ *
++ * Holds LTTng probes registry.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include <linux/list.h>
++#include <linux/mutex.h>
++#include <linux/seq_file.h>
++
++#include "lttng-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 lttng_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(lttng_probe_register);
++
++void lttng_probe_unregister(struct lttng_probe_desc *desc)
++{
++ mutex_lock(&probe_mutex);
++ list_del(&desc->head);
++ mutex_unlock(&probe_mutex);
++}
++EXPORT_SYMBOL_GPL(lttng_probe_unregister);
++
++const struct lttng_event_desc *lttng_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(lttng_event_get);
++
++void lttng_event_put(const struct lttng_event_desc *event)
++{
++ module_put(event->owner);
++}
++EXPORT_SYMBOL_GPL(lttng_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 event: lttng_metadata.
++ */
++ if (!strcmp(probe_desc->name, "lttng_metadata"))
++ 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,
++};
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-client-discard.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-client-discard.c
++ *
++ * LTTng lib ring buffer client (discard mode).
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-client-mmap-discard.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-client-discard.c
++ *
++ * LTTng lib ring buffer client (discard mode).
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-client-mmap-overwrite.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-client-overwrite.c
++ *
++ * LTTng lib ring buffer client (overwrite mode).
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-client-overwrite.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-client-overwrite.c
++ *
++ * LTTng lib ring buffer client (overwrite mode).
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-client.h
+@@ -0,0 +1,598 @@
++/*
++ * lttng-ring-buffer-client.h
++ *
++ * LTTng lib ring buffer client template.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 "lttng-events.h"
++#include "lttng-tracer.h"
++#include "wrapper/ringbuffer/frontend_types.h"
++
++#define LTTNG_COMPACT_EVENT_BITS 5
++#define LTTNG_COMPACT_TSC_BITS 27
++
++/*
++ * 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 lttng_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 lttng_channel *lttng_chan = channel_get_private(chan);
++ struct lttng_event *event = ctx->priv;
++ size_t orig_offset = offset;
++ size_t padding;
++
++ switch (lttng_chan->header_type) {
++ case 1: /* compact */
++ padding = lib_ring_buffer_align(offset, lttng_alignof(uint32_t));
++ offset += padding;
++ if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
++ offset += sizeof(uint32_t); /* id and timestamp */
++ } else {
++ /* Minimum space taken by LTTNG_COMPACT_EVENT_BITS id */
++ offset += (LTTNG_COMPACT_EVENT_BITS + CHAR_BIT - 1) / CHAR_BIT;
++ /* Align extended struct on largest member */
++ offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t));
++ offset += sizeof(uint32_t); /* id */
++ offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t));
++ offset += sizeof(uint64_t); /* timestamp */
++ }
++ break;
++ case 2: /* large */
++ padding = lib_ring_buffer_align(offset, lttng_alignof(uint16_t));
++ offset += padding;
++ offset += sizeof(uint16_t);
++ if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
++ offset += lib_ring_buffer_align(offset, lttng_alignof(uint32_t));
++ offset += sizeof(uint32_t); /* timestamp */
++ } else {
++ /* Align extended struct on largest member */
++ offset += lib_ring_buffer_align(offset, lttng_alignof(uint64_t));
++ offset += sizeof(uint32_t); /* id */
++ offset += lib_ring_buffer_align(offset, lttng_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, lttng_chan->ctx);
++
++ *pre_header_padding = padding;
++ return offset - orig_offset;
++}
++
++#include "wrapper/ringbuffer/api.h"
++
++static
++void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config,
++ struct lib_ring_buffer_ctx *ctx,
++ uint32_t event_id);
++
++/*
++ * lttng_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 lttng_write_event_header(const struct lib_ring_buffer_config *config,
++ struct lib_ring_buffer_ctx *ctx,
++ uint32_t event_id)
++{
++ struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
++ struct lttng_event *event = ctx->priv;
++
++ if (unlikely(ctx->rflags))
++ goto slow_path;
++
++ switch (lttng_chan->header_type) {
++ case 1: /* compact */
++ {
++ uint32_t id_time = 0;
++
++ bt_bitfield_write(&id_time, uint32_t,
++ 0,
++ LTTNG_COMPACT_EVENT_BITS,
++ event_id);
++ bt_bitfield_write(&id_time, uint32_t,
++ LTTNG_COMPACT_EVENT_BITS,
++ LTTNG_COMPACT_TSC_BITS,
++ 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, lttng_alignof(uint32_t));
++ lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
++ break;
++ }
++ default:
++ WARN_ON_ONCE(1);
++ }
++
++ ctx_record(ctx, lttng_chan, lttng_chan->ctx);
++ ctx_record(ctx, lttng_chan, event->ctx);
++ lib_ring_buffer_align_ctx(ctx, ctx->largest_align);
++
++ return;
++
++slow_path:
++ lttng_write_event_header_slow(config, ctx, event_id);
++}
++
++static
++void lttng_write_event_header_slow(const struct lib_ring_buffer_config *config,
++ struct lib_ring_buffer_ctx *ctx,
++ uint32_t event_id)
++{
++ struct lttng_channel *lttng_chan = channel_get_private(ctx->chan);
++ struct lttng_event *event = ctx->priv;
++
++ switch (lttng_chan->header_type) {
++ case 1: /* compact */
++ if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_RFLAG_EXTENDED))) {
++ uint32_t id_time = 0;
++
++ bt_bitfield_write(&id_time, uint32_t,
++ 0,
++ LTTNG_COMPACT_EVENT_BITS,
++ event_id);
++ bt_bitfield_write(&id_time, uint32_t,
++ LTTNG_COMPACT_EVENT_BITS,
++ LTTNG_COMPACT_TSC_BITS, 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,
++ LTTNG_COMPACT_EVENT_BITS,
++ 31);
++ lib_ring_buffer_write(config, ctx, &id, sizeof(id));
++ /* Align extended struct on largest member */
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t));
++ lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t));
++ lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
++ }
++ break;
++ case 2: /* large */
++ {
++ if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTTNG_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, lttng_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, lttng_alignof(uint64_t));
++ lib_ring_buffer_write(config, ctx, &event_id, sizeof(event_id));
++ lib_ring_buffer_align_ctx(ctx, lttng_alignof(uint64_t));
++ lib_ring_buffer_write(config, ctx, &timestamp, sizeof(timestamp));
++ }
++ break;
++ }
++ default:
++ WARN_ON_ONCE(1);
++ }
++ ctx_record(ctx, lttng_chan, lttng_chan->ctx);
++ ctx_record(ctx, lttng_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 lttng_channel *lttng_chan = channel_get_private(chan);
++ struct lttng_session *session = lttng_chan->session;
++
++ header->magic = CTF_MAGIC_NUMBER;
++ memcpy(header->uuid, session->uuid.b, sizeof(session->uuid));
++ header->stream_id = lttng_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 = LTTNG_COMPACT_TSC_BITS,
++ .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 lttng_channel *lttng_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, lttng_chan, buf_addr,
++ subbuf_size, num_subbuf, switch_timer_interval,
++ read_timer_interval);
++}
++
++static
++void lttng_channel_destroy(struct channel *chan)
++{
++ channel_destroy(chan);
++}
++
++static
++struct lib_ring_buffer *lttng_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 lttng_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 lttng_buffer_read_close(struct lib_ring_buffer *buf)
++{
++ lib_ring_buffer_release_read(buf);
++}
++
++static
++int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx,
++ uint32_t event_id)
++{
++ struct lttng_channel *lttng_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 (lttng_chan->header_type) {
++ case 1: /* compact */
++ if (event_id > 30)
++ ctx->rflags |= LTTNG_RFLAG_EXTENDED;
++ break;
++ case 2: /* large */
++ if (event_id > 65534)
++ ctx->rflags |= LTTNG_RFLAG_EXTENDED;
++ break;
++ default:
++ WARN_ON_ONCE(1);
++ }
++
++ ret = lib_ring_buffer_reserve(&client_config, ctx);
++ if (ret)
++ goto put;
++ lttng_write_event_header(&client_config, ctx, event_id);
++ return 0;
++put:
++ lib_ring_buffer_put_cpu(&client_config);
++ return ret;
++}
++
++static
++void lttng_event_commit(struct lib_ring_buffer_ctx *ctx)
++{
++ lib_ring_buffer_commit(&client_config, ctx);
++ lib_ring_buffer_put_cpu(&client_config);
++}
++
++static
++void lttng_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 lttng_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 lttng_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 *lttng_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 *lttng_get_hp_wait_queue(struct channel *chan)
++{
++ return &chan->hp_wait;
++}
++
++static
++int lttng_is_finalized(struct channel *chan)
++{
++ return lib_ring_buffer_channel_is_finalized(chan);
++}
++
++static
++int lttng_is_disabled(struct channel *chan)
++{
++ return lib_ring_buffer_channel_is_disabled(chan);
++}
++
++static struct lttng_transport lttng_relay_transport = {
++ .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
++ .owner = THIS_MODULE,
++ .ops = {
++ .channel_create = _channel_create,
++ .channel_destroy = lttng_channel_destroy,
++ .buffer_read_open = lttng_buffer_read_open,
++ .buffer_has_read_closed_stream =
++ lttng_buffer_has_read_closed_stream,
++ .buffer_read_close = lttng_buffer_read_close,
++ .event_reserve = lttng_event_reserve,
++ .event_commit = lttng_event_commit,
++ .event_write = lttng_event_write,
++ .event_write_from_user = lttng_event_write_from_user,
++ .event_memset = lttng_event_memset,
++ .packet_avail_size = NULL, /* Would be racy anyway */
++ .get_writer_buf_wait_queue = lttng_get_writer_buf_wait_queue,
++ .get_hp_wait_queue = lttng_get_hp_wait_queue,
++ .is_finalized = lttng_is_finalized,
++ .is_disabled = lttng_is_disabled,
++ },
++};
++
++static int __init lttng_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();
++ lttng_transport_register(&lttng_relay_transport);
++ return 0;
++}
++
++module_init(lttng_ring_buffer_client_init);
++
++static void __exit lttng_ring_buffer_client_exit(void)
++{
++ lttng_transport_unregister(&lttng_relay_transport);
++}
++
++module_exit(lttng_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");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-metadata-client.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-metadata-client.c
++ *
++ * LTTng lib ring buffer metadta client.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-metadata-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-metadata-client.h
+@@ -0,0 +1,342 @@
++/*
++ * lttng-ring-buffer-client.h
++ *
++ * LTTng lib ring buffer client template.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
++#include "lttng-events.h"
++#include "lttng-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 lttng_channel *lttng_chan = channel_get_private(chan);
++ struct lttng_session *session = lttng_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 lttng_channel *lttng_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, lttng_chan, buf_addr,
++ subbuf_size, num_subbuf, switch_timer_interval,
++ read_timer_interval);
++}
++
++static
++void lttng_channel_destroy(struct channel *chan)
++{
++ channel_destroy(chan);
++}
++
++static
++struct lib_ring_buffer *lttng_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 lttng_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 lttng_buffer_read_close(struct lib_ring_buffer *buf)
++{
++ lib_ring_buffer_release_read(buf);
++}
++
++static
++int lttng_event_reserve(struct lib_ring_buffer_ctx *ctx, uint32_t event_id)
++{
++ return lib_ring_buffer_reserve(&client_config, ctx);
++}
++
++static
++void lttng_event_commit(struct lib_ring_buffer_ctx *ctx)
++{
++ lib_ring_buffer_commit(&client_config, ctx);
++}
++
++static
++void lttng_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 lttng_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 lttng_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 lttng_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 *lttng_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 *lttng_get_hp_wait_queue(struct channel *chan)
++{
++ return &chan->hp_wait;
++}
++
++static
++int lttng_is_finalized(struct channel *chan)
++{
++ return lib_ring_buffer_channel_is_finalized(chan);
++}
++
++static
++int lttng_is_disabled(struct channel *chan)
++{
++ return lib_ring_buffer_channel_is_disabled(chan);
++}
++
++static struct lttng_transport lttng_relay_transport = {
++ .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING,
++ .owner = THIS_MODULE,
++ .ops = {
++ .channel_create = _channel_create,
++ .channel_destroy = lttng_channel_destroy,
++ .buffer_read_open = lttng_buffer_read_open,
++ .buffer_has_read_closed_stream =
++ lttng_buffer_has_read_closed_stream,
++ .buffer_read_close = lttng_buffer_read_close,
++ .event_reserve = lttng_event_reserve,
++ .event_commit = lttng_event_commit,
++ .event_write_from_user = lttng_event_write_from_user,
++ .event_memset = lttng_event_memset,
++ .event_write = lttng_event_write,
++ .packet_avail_size = lttng_packet_avail_size,
++ .get_writer_buf_wait_queue = lttng_get_writer_buf_wait_queue,
++ .get_hp_wait_queue = lttng_get_hp_wait_queue,
++ .is_finalized = lttng_is_finalized,
++ .is_disabled = lttng_is_disabled,
++ },
++};
++
++static int __init lttng_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();
++ lttng_transport_register(&lttng_relay_transport);
++ return 0;
++}
++
++module_init(lttng_ring_buffer_client_init);
++
++static void __exit lttng_ring_buffer_client_exit(void)
++{
++ lttng_transport_unregister(&lttng_relay_transport);
++}
++
++module_exit(lttng_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");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-ring-buffer-metadata-mmap-client.c
+@@ -0,0 +1,33 @@
++/*
++ * lttng-ring-buffer-metadata-client.c
++ *
++ * LTTng lib ring buffer metadta client.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include "lttng-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 "lttng-ring-buffer-metadata-client.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers");
++MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client");
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-statedump-impl.c
+@@ -0,0 +1,385 @@
++/*
++ * lttng-statedump.c
++ *
++ * Linux Trace Toolkit Next Generation Kernel State Dump
++ *
++ * Copyright 2005 Jean-Hugues Deschenes <jean-hugues.deschenes@polymtl.ca>
++ * Copyright 2006-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ * Changes:
++ * Eric Clement: Add listing of network IP interface
++ * 2006, 2007 Mathieu Desnoyers Fix kernel threads
++ * Various updates
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/netlink.h>
++#include <linux/inet.h>
++#include <linux/ip.h>
++#include <linux/kthread.h>
++#include <linux/proc_fs.h>
++#include <linux/file.h>
++#include <linux/interrupt.h>
++#include <linux/irqnr.h>
++#include <linux/cpu.h>
++#include <linux/netdevice.h>
++#include <linux/inetdevice.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/fdtable.h>
++#include <linux/swap.h>
++#include <linux/wait.h>
++#include <linux/mutex.h>
++
++#include "lttng-events.h"
++#include "wrapper/irqdesc.h"
++
++#ifdef CONFIG_GENERIC_HARDIRQS
++#include <linux/irq.h>
++#endif
++
++/* Define the tracepoints, but do not build the probes */
++#define CREATE_TRACE_POINTS
++#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
++#define TRACE_INCLUDE_FILE lttng-statedump
++#include "instrumentation/events/lttng-module/lttng-statedump.h"
++
++/*
++ * Protected by the trace lock.
++ */
++static struct delayed_work cpu_work[NR_CPUS];
++static DECLARE_WAIT_QUEUE_HEAD(statedump_wq);
++static atomic_t kernel_threads_to_run;
++
++enum lttng_thread_type {
++ LTTNG_USER_THREAD = 0,
++ LTTNG_KERNEL_THREAD = 1,
++};
++
++enum lttng_execution_mode {
++ LTTNG_USER_MODE = 0,
++ LTTNG_SYSCALL = 1,
++ LTTNG_TRAP = 2,
++ LTTNG_IRQ = 3,
++ LTTNG_SOFTIRQ = 4,
++ LTTNG_MODE_UNKNOWN = 5,
++};
++
++enum lttng_execution_submode {
++ LTTNG_NONE = 0,
++ LTTNG_UNKNOWN = 1,
++};
++
++enum lttng_process_status {
++ LTTNG_UNNAMED = 0,
++ LTTNG_WAIT_FORK = 1,
++ LTTNG_WAIT_CPU = 2,
++ LTTNG_EXIT = 3,
++ LTTNG_ZOMBIE = 4,
++ LTTNG_WAIT = 5,
++ LTTNG_RUN = 6,
++ LTTNG_DEAD = 7,
++};
++
++#ifdef CONFIG_INET
++static
++void lttng_enumerate_device(struct lttng_session *session,
++ struct net_device *dev)
++{
++ struct in_device *in_dev;
++ struct in_ifaddr *ifa;
++
++ if (dev->flags & IFF_UP) {
++ in_dev = in_dev_get(dev);
++ if (in_dev) {
++ for (ifa = in_dev->ifa_list; ifa != NULL;
++ ifa = ifa->ifa_next) {
++ trace_lttng_statedump_network_interface(
++ session, dev, ifa);
++ }
++ in_dev_put(in_dev);
++ }
++ } else {
++ trace_lttng_statedump_network_interface(
++ session, dev, NULL);
++ }
++}
++
++static
++int lttng_enumerate_network_ip_interface(struct lttng_session *session)
++{
++ struct net_device *dev;
++
++ read_lock(&dev_base_lock);
++ for_each_netdev(&init_net, dev)
++ lttng_enumerate_device(session, dev);
++ read_unlock(&dev_base_lock);
++
++ return 0;
++}
++#else /* CONFIG_INET */
++static inline
++int lttng_enumerate_network_ip_interface(struct lttng_session *session)
++{
++ return 0;
++}
++#endif /* CONFIG_INET */
++
++
++static
++void lttng_enumerate_task_fd(struct lttng_session *session,
++ struct task_struct *p, char *tmp)
++{
++ struct fdtable *fdt;
++ struct file *filp;
++ unsigned int i;
++ const unsigned char *path;
++
++ task_lock(p);
++ if (!p->files)
++ goto unlock_task;
++ spin_lock(&p->files->file_lock);
++ fdt = files_fdtable(p->files);
++ for (i = 0; i < fdt->max_fds; i++) {
++ filp = fcheck_files(p->files, i);
++ if (!filp)
++ continue;
++ path = d_path(&filp->f_path, tmp, PAGE_SIZE);
++ /* Make sure we give at least some info */
++ trace_lttng_statedump_file_descriptor(session, p, i,
++ IS_ERR(path) ?
++ filp->f_dentry->d_name.name :
++ path);
++ }
++ spin_unlock(&p->files->file_lock);
++unlock_task:
++ task_unlock(p);
++}
++
++static
++int lttng_enumerate_file_descriptors(struct lttng_session *session)
++{
++ struct task_struct *p;
++ char *tmp = (char *) __get_free_page(GFP_KERNEL);
++
++ /* Enumerate active file descriptors */
++ rcu_read_lock();
++ for_each_process(p)
++ lttng_enumerate_task_fd(session, p, tmp);
++ rcu_read_unlock();
++ free_page((unsigned long) tmp);
++ return 0;
++}
++
++static
++void lttng_enumerate_task_vm_maps(struct lttng_session *session,
++ struct task_struct *p)
++{
++ struct mm_struct *mm;
++ struct vm_area_struct *map;
++ unsigned long ino;
++
++ /* get_task_mm does a task_lock... */
++ mm = get_task_mm(p);
++ if (!mm)
++ return;
++
++ map = mm->mmap;
++ if (map) {
++ down_read(&mm->mmap_sem);
++ while (map) {
++ if (map->vm_file)
++ ino = map->vm_file->f_dentry->d_inode->i_ino;
++ else
++ ino = 0;
++ trace_lttng_statedump_vm_map(session, p, map, ino);
++ map = map->vm_next;
++ }
++ up_read(&mm->mmap_sem);
++ }
++ mmput(mm);
++}
++
++static
++int lttng_enumerate_vm_maps(struct lttng_session *session)
++{
++ struct task_struct *p;
++
++ rcu_read_lock();
++ for_each_process(p)
++ lttng_enumerate_task_vm_maps(session, p);
++ rcu_read_unlock();
++ return 0;
++}
++
++#ifdef CONFIG_GENERIC_HARDIRQS
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
++#define irq_desc_get_chip(desc) get_irq_desc_chip(desc)
++#endif
++
++static
++void lttng_list_interrupts(struct lttng_session *session)
++{
++ unsigned int irq;
++ unsigned long flags = 0;
++ struct irq_desc *desc;
++
++#define irq_to_desc wrapper_irq_to_desc
++ /* needs irq_desc */
++ for_each_irq_desc(irq, desc) {
++ struct irqaction *action;
++ const char *irq_chip_name =
++ irq_desc_get_chip(desc)->name ? : "unnamed_irq_chip";
++
++ local_irq_save(flags);
++ raw_spin_lock(&desc->lock);
++ for (action = desc->action; action; action = action->next) {
++ trace_lttng_statedump_interrupt(session,
++ irq, irq_chip_name, action);
++ }
++ raw_spin_unlock(&desc->lock);
++ local_irq_restore(flags);
++ }
++#undef irq_to_desc
++}
++#else
++static inline
++void list_interrupts(struct lttng_session *session)
++{
++}
++#endif
++
++static
++int lttng_enumerate_process_states(struct lttng_session *session)
++{
++ struct task_struct *g, *p;
++
++ rcu_read_lock();
++ for_each_process(g) {
++ p = g;
++ do {
++ enum lttng_execution_mode mode =
++ LTTNG_MODE_UNKNOWN;
++ enum lttng_execution_submode submode =
++ LTTNG_UNKNOWN;
++ enum lttng_process_status status;
++ enum lttng_thread_type type;
++
++ task_lock(p);
++ if (p->exit_state == EXIT_ZOMBIE)
++ status = LTTNG_ZOMBIE;
++ else if (p->exit_state == EXIT_DEAD)
++ status = LTTNG_DEAD;
++ else if (p->state == TASK_RUNNING) {
++ /* Is this a forked child that has not run yet? */
++ if (list_empty(&p->rt.run_list))
++ status = LTTNG_WAIT_FORK;
++ else
++ /*
++ * All tasks are considered as wait_cpu;
++ * the viewer will sort out if the task
++ * was really running at this time.
++ */
++ status = LTTNG_WAIT_CPU;
++ } else if (p->state &
++ (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)) {
++ /* Task is waiting for something to complete */
++ status = LTTNG_WAIT;
++ } else
++ status = LTTNG_UNNAMED;
++ submode = LTTNG_NONE;
++
++ /*
++ * Verification of t->mm is to filter out kernel
++ * threads; Viewer will further filter out if a
++ * user-space thread was in syscall mode or not.
++ */
++ if (p->mm)
++ type = LTTNG_USER_THREAD;
++ else
++ type = LTTNG_KERNEL_THREAD;
++ trace_lttng_statedump_process_state(session,
++ p, type, mode, submode, status);
++ task_unlock(p);
++ } while_each_thread(g, p);
++ }
++ rcu_read_unlock();
++
++ return 0;
++}
++
++static
++void lttng_statedump_work_func(struct work_struct *work)
++{
++ if (atomic_dec_and_test(&kernel_threads_to_run))
++ /* If we are the last thread, wake up do_lttng_statedump */
++ wake_up(&statedump_wq);
++}
++
++static
++int do_lttng_statedump(struct lttng_session *session)
++{
++ int cpu;
++
++ printk(KERN_DEBUG "LTT state dump thread start\n");
++ trace_lttng_statedump_start(session);
++ lttng_enumerate_process_states(session);
++ lttng_enumerate_file_descriptors(session);
++ lttng_enumerate_vm_maps(session);
++ lttng_list_interrupts(session);
++ lttng_enumerate_network_ip_interface(session);
++
++ /* TODO lttng_dump_idt_table(session); */
++ /* TODO lttng_dump_softirq_vec(session); */
++ /* TODO lttng_list_modules(session); */
++ /* TODO lttng_dump_swap_files(session); */
++
++ /*
++ * Fire off a work queue on each CPU. Their sole purpose in life
++ * is to guarantee that each CPU has been in a state where is was in
++ * syscall mode (i.e. not in a trap, an IRQ or a soft IRQ).
++ */
++ get_online_cpus();
++ atomic_set(&kernel_threads_to_run, num_online_cpus());
++ for_each_online_cpu(cpu) {
++ INIT_DELAYED_WORK(&cpu_work[cpu], lttng_statedump_work_func);
++ schedule_delayed_work_on(cpu, &cpu_work[cpu], 0);
++ }
++ /* Wait for all threads to run */
++ __wait_event(statedump_wq, (atomic_read(&kernel_threads_to_run) != 0));
++ put_online_cpus();
++ /* Our work is done */
++ printk(KERN_DEBUG "LTT state dump end\n");
++ trace_lttng_statedump_end(session);
++ return 0;
++}
++
++/*
++ * Called with session mutex held.
++ */
++int lttng_statedump_start(struct lttng_session *session)
++{
++ printk(KERN_DEBUG "LTTng: state dump begin\n");
++ return do_lttng_statedump(session);
++}
++EXPORT_SYMBOL_GPL(lttng_statedump_start);
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Jean-Hugues Deschenes");
++MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Statedump");
+--- a/drivers/staging/lttng/lttng-syscalls.c
++++ b/drivers/staging/lttng/lttng-syscalls.c
+@@ -1,11 +1,23 @@
+ /*
+ * lttng-syscalls.c
+ *
+- * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng syscall probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+@@ -14,13 +26,12 @@
+ #include <asm/ptrace.h>
+ #include <asm/syscall.h>
+
+-#include "ltt-events.h"
++#include "lttng-events.h"
+
+ #ifndef CONFIG_COMPAT
+-static inline int is_compat_task(void)
+-{
+- return 0;
+-}
++# ifndef is_compat_task
++# define is_compat_task() (0)
++# endif
+ #endif
+
+ static
+@@ -141,7 +152,7 @@ const struct trace_syscall_entry compat_
+
+ #undef CREATE_SYSCALL_TABLE
+
+-static void syscall_entry_unknown(struct ltt_event *event,
++static void syscall_entry_unknown(struct lttng_event *event,
+ struct pt_regs *regs, unsigned int id)
+ {
+ unsigned long args[UNKNOWN_SYSCALL_NRARGS];
+@@ -155,8 +166,8 @@ static void syscall_entry_unknown(struct
+
+ void syscall_entry_probe(void *__data, struct pt_regs *regs, long id)
+ {
+- struct ltt_channel *chan = __data;
+- struct ltt_event *event, *unknown_event;
++ struct lttng_channel *chan = __data;
++ struct lttng_event *event, *unknown_event;
+ const struct trace_syscall_entry *table, *entry;
+ size_t table_len;
+
+@@ -275,7 +286,7 @@ void syscall_entry_probe(void *__data, s
+ /* 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)
++ struct lttng_event **chan_table, struct lttng_channel *chan, void *filter)
+ {
+ const struct lttng_event_desc *desc;
+ unsigned int i;
+@@ -296,10 +307,10 @@ int fill_table(const struct trace_syscal
+ 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';
++ strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
++ ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
+ ev.instrumentation = LTTNG_KERNEL_NOOP;
+- chan_table[i] = ltt_event_create(chan, &ev, filter,
++ chan_table[i] = lttng_event_create(chan, &ev, filter,
+ desc);
+ if (!chan_table[i]) {
+ /*
+@@ -314,7 +325,7 @@ int fill_table(const struct trace_syscal
+ return 0;
+ }
+
+-int lttng_syscalls_register(struct ltt_channel *chan, void *filter)
++int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
+ {
+ struct lttng_kernel_event ev;
+ int ret;
+@@ -323,7 +334,7 @@ int lttng_syscalls_register(struct ltt_c
+
+ if (!chan->sc_table) {
+ /* create syscall table mapping syscall to events */
+- chan->sc_table = kzalloc(sizeof(struct ltt_event *)
++ chan->sc_table = kzalloc(sizeof(struct lttng_event *)
+ * ARRAY_SIZE(sc_table), GFP_KERNEL);
+ if (!chan->sc_table)
+ return -ENOMEM;
+@@ -332,7 +343,7 @@ int lttng_syscalls_register(struct ltt_c
+ #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 *)
++ chan->compat_sc_table = kzalloc(sizeof(struct lttng_event *)
+ * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
+ if (!chan->compat_sc_table)
+ return -ENOMEM;
+@@ -343,10 +354,10 @@ int lttng_syscalls_register(struct ltt_c
+ &__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';
++ strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
++ ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
+ ev.instrumentation = LTTNG_KERNEL_NOOP;
+- chan->sc_unknown = ltt_event_create(chan, &ev, filter,
++ chan->sc_unknown = lttng_event_create(chan, &ev, filter,
+ desc);
+ if (!chan->sc_unknown) {
+ return -EINVAL;
+@@ -358,10 +369,10 @@ int lttng_syscalls_register(struct ltt_c
+ &__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';
++ strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
++ ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
+ ev.instrumentation = LTTNG_KERNEL_NOOP;
+- chan->sc_compat_unknown = ltt_event_create(chan, &ev, filter,
++ chan->sc_compat_unknown = lttng_event_create(chan, &ev, filter,
+ desc);
+ if (!chan->sc_compat_unknown) {
+ return -EINVAL;
+@@ -373,10 +384,10 @@ int lttng_syscalls_register(struct ltt_c
+ &__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';
++ strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
++ ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
+ ev.instrumentation = LTTNG_KERNEL_NOOP;
+- chan->sc_exit = ltt_event_create(chan, &ev, filter,
++ chan->sc_exit = lttng_event_create(chan, &ev, filter,
+ desc);
+ if (!chan->sc_exit) {
+ return -EINVAL;
+@@ -414,7 +425,7 @@ int lttng_syscalls_register(struct ltt_c
+ /*
+ * Only called at session destruction.
+ */
+-int lttng_syscalls_unregister(struct ltt_channel *chan)
++int lttng_syscalls_unregister(struct lttng_channel *chan)
+ {
+ int ret;
+
+@@ -429,7 +440,7 @@ int lttng_syscalls_unregister(struct ltt
+ (void *) syscall_entry_probe, chan);
+ if (ret)
+ return ret;
+- /* ltt_event destroy will be performed by ltt_session_destroy() */
++ /* lttng_event destroy will be performed by lttng_session_destroy() */
+ kfree(chan->sc_table);
+ #ifdef CONFIG_COMPAT
+ kfree(chan->compat_sc_table);
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-tracer-core.h
+@@ -0,0 +1,41 @@
++#ifndef LTTNG_TRACER_CORE_H
++#define LTTNG_TRACER_CORE_H
++
++/*
++ * lttng-tracer-core.h
++ *
++ * This contains the core definitions for the Linux Trace Toolkit Next
++ * Generation tracer.
++ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 lttng_session;
++struct lttng_channel;
++struct lttng_event;
++
++#endif /* LTTNG_TRACER_CORE_H */
+--- /dev/null
++++ b/drivers/staging/lttng/lttng-tracer.h
+@@ -0,0 +1,80 @@
++#ifndef _LTTNG_TRACER_H
++#define _LTTNG_TRACER_H
++
++/*
++ * lttng-tracer.h
++ *
++ * This contains the definitions for the Linux Trace Toolkit Next
++ * Generation tracer.
++ *
++ * Copyright (C) 2005-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 "lttng-tracer-core.h"
++#include "lttng-events.h"
++
++#define LTTNG_MODULES_MAJOR_VERSION 2
++#define LTTNG_MODULES_MINOR_VERSION 0
++#define LTTNG_MODULES_PATCHLEVEL_VERSION 1
++
++#define LTTNG_VERSION_NAME "Annedd'ale"
++#define LTTNG_VERSION_DESCRIPTION \
++ "New type of beer, 100% from Quebec, flavored with sapin beaumier needles, with a touch of hops."
++
++#ifndef CHAR_BIT
++#define CHAR_BIT 8
++#endif
++
++/* Number of bytes to log with a read/write event */
++#define LTTNG_LOG_RW_SIZE 32L
++#define LTTNG_MAX_SMALL_SIZE 0xFFFFU
++
++#ifdef RING_BUFFER_ALIGN
++#define lttng_alignof(type) __alignof__(type)
++#else
++#define lttng_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
++
++/*
++ * Number of milliseconds to retry before failing metadata writes on buffer full
++ * condition. (10 seconds)
++ */
++#define LTTNG_METADATA_TIMEOUT_MSEC 10000
++
++#define LTTNG_RFLAG_EXTENDED RING_BUFFER_RFLAG_END
++#define LTTNG_RFLAG_END (LTTNG_RFLAG_EXTENDED << 1)
++
++#endif /* _LTTNG_TRACER_H */
+--- a/drivers/staging/lttng/probes/Makefile
++++ b/drivers/staging/lttng/probes/Makefile
+@@ -9,6 +9,10 @@ obj-m += lttng-probe-lttng.o
+
+ obj-m += lttng-probe-sched.o
+ obj-m += lttng-probe-irq.o
++obj-m += lttng-probe-signal.o
++obj-m += lttng-probe-timer.o
++
++obj-m += lttng-probe-statedump.o
+
+ ifneq ($(CONFIG_KVM),)
+ obj-m += lttng-probe-kvm.o
+--- a/drivers/staging/lttng/probes/define_trace.h
++++ b/drivers/staging/lttng/probes/define_trace.h
+@@ -2,9 +2,21 @@
+ * define_trace.h
+ *
+ * Copyright (C) 2009 Steven Rostedt <rostedt@goodmis.org>
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /*
+--- a/drivers/staging/lttng/probes/lttng-events-reset.h
++++ b/drivers/staging/lttng/probes/lttng-events-reset.h
+@@ -1,9 +1,21 @@
+ /*
+ * lttng-events-reset.h
+ *
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /* Reset macros used within TRACE_EVENT to "nothing" */
+--- a/drivers/staging/lttng/probes/lttng-events.h
++++ b/drivers/staging/lttng/probes/lttng-events.h
+@@ -2,9 +2,21 @@
+ * lttng-events.h
+ *
+ * Copyright (C) 2009 Steven Rostedt <rostedt@goodmis.org>
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/debugfs.h>
+@@ -12,8 +24,8 @@
+ #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"
++#include "../lttng-events.h"
++#include "../lttng-tracer-core.h"
+
+ /*
+ * Macro declarations used for all stages.
+@@ -319,19 +331,19 @@ static __used struct lttng_probe_desc TP
+
+ #undef __field_full
+ #define __field_full(_type, _item, _order, _base) \
+- __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
++ __event_len += lib_ring_buffer_align(__event_len, lttng_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 += lib_ring_buffer_align(__event_len, lttng_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 += lib_ring_buffer_align(__event_len, lttng_alignof(u32)); \
+ __event_len += sizeof(u32); \
+- __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \
++ __event_len += lib_ring_buffer_align(__event_len, lttng_alignof(_type)); \
+ __dynamic_len[__dynamic_len_idx] = (_length); \
+ __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \
+ __dynamic_len_idx++;
+@@ -382,16 +394,16 @@ static inline size_t __event_get_size__#
+
+ #undef __field_full
+ #define __field_full(_type, _item, _order, _base) \
+- __event_align = max_t(size_t, __event_align, ltt_alignof(_type));
++ __event_align = max_t(size_t, __event_align, lttng_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));
++ __event_align = max_t(size_t, __event_align, lttng_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));
++ __event_align = max_t(size_t, __event_align, lttng_alignof(u32)); \
++ __event_align = max_t(size_t, __event_align, lttng_alignof(_type));
+
+ #undef __string
+ #define __string(_item, _src)
+@@ -506,7 +518,7 @@ __end_field_##_item:
+ __assign_##dest: \
+ { \
+ __typeof__(__typemap.dest) __tmp = (src); \
+- lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__tmp)); \
++ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__tmp)); \
+ __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\
+ } \
+ goto __end_field_##dest;
+@@ -516,7 +528,7 @@ __assign_##dest: \
+ __assign_##dest: \
+ if (0) \
+ (void) __typemap.dest; \
+- lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \
++ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \
+ __chan->ops->event_write(&__ctx, src, len); \
+ goto __end_field_##dest;
+
+@@ -525,12 +537,12 @@ __assign_##dest: \
+ __assign_##dest##_1: \
+ { \
+ u32 __tmpl = __dynamic_len[__dynamic_len_idx]; \
+- lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(u32)); \
++ lib_ring_buffer_align_ctx(&__ctx, lttng_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)); \
++ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \
+ __chan->ops->event_write(&__ctx, src, \
+ sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\
+ goto __end_field_##dest##_2;
+@@ -540,7 +552,7 @@ __assign_##dest##_2: \
+ __assign_##dest: \
+ if (0) \
+ (void) __typemap.dest; \
+- lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \
++ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest)); \
+ __chan->ops->event_write_from_user(&__ctx, src, len); \
+ goto __end_field_##dest;
+
+@@ -555,7 +567,7 @@ __assign_##dest##_2: \
+ \
+ if (0) \
+ (void) __typemap.dest; \
+- lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));\
++ lib_ring_buffer_align_ctx(&__ctx, lttng_alignof(__typemap.dest));\
+ __ustrlen = __get_dynamic_array_len(dest); \
+ if (likely(__ustrlen > 1)) { \
+ __chan->ops->event_write_from_user(&__ctx, src, \
+@@ -592,12 +604,23 @@ __assign_##dest##_2: \
+ #undef TP_fast_assign
+ #define TP_fast_assign(args...) args
+
++/*
++ * For state dump, check that "session" argument (mandatory) matches the
++ * session this event belongs to. Ensures that we write state dump data only
++ * into the started session, not into all sessions.
++ */
++#ifdef TP_SESSION_CHECK
++#define _TP_SESSION_CHECK(session, csession) (session == csession)
++#else /* TP_SESSION_CHECK */
++#define _TP_SESSION_CHECK(session, csession) 1
++#endif /* TP_SESSION_CHECK */
++
+ #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 lttng_event *__event = __data; \
++ struct lttng_channel *__chan = __event->chan; \
+ struct lib_ring_buffer_ctx __ctx; \
+ size_t __event_len, __event_align; \
+ size_t __dynamic_len_idx = 0; \
+@@ -605,8 +628,12 @@ static void __event_probe__##_name(void
+ struct __event_typemap__##_name __typemap; \
+ int __ret; \
+ \
+- if (0) \
++ if (0) { \
+ (void) __dynamic_len_idx; /* don't warn if unused */ \
++ (void) __typemap; /* don't warn if unused */ \
++ } \
++ if (!_TP_SESSION_CHECK(session, __chan->session)) \
++ return; \
+ if (unlikely(!ACCESS_ONCE(__chan->session->active))) \
+ return; \
+ if (unlikely(!ACCESS_ONCE(__chan->enabled))) \
+@@ -632,12 +659,14 @@ static void __event_probe__##_name(void
+ #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 lttng_event *__event = __data; \
++ struct lttng_channel *__chan = __event->chan; \
+ struct lib_ring_buffer_ctx __ctx; \
+ size_t __event_len, __event_align; \
+ int __ret; \
+ \
++ if (!_TP_SESSION_CHECK(session, __chan->session)) \
++ return; \
+ if (unlikely(!ACCESS_ONCE(__chan->session->active))) \
+ return; \
+ if (unlikely(!ACCESS_ONCE(__chan->enabled))) \
+@@ -680,14 +709,14 @@ static void __event_probe__##_name(void
+ static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void)
+ {
+ wrapper_vmalloc_sync_all();
+- return ltt_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM));
++ return lttng_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));
++ lttng_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM));
+ }
+
+ module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM);
+--- a/drivers/staging/lttng/probes/lttng-ftrace.c
++++ b/drivers/staging/lttng/probes/lttng-ftrace.c
+@@ -1,10 +1,23 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * probes/lttng-ftrace.c
+ *
+ * LTTng function tracer integration module.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /*
+@@ -20,17 +33,17 @@
+ #include <linux/module.h>
+ #include <linux/ftrace.h>
+ #include <linux/slab.h>
+-#include "../ltt-events.h"
++#include "../lttng-events.h"
+ #include "../wrapper/ringbuffer/frontend_types.h"
+ #include "../wrapper/ftrace.h"
+ #include "../wrapper/vmalloc.h"
+-#include "../ltt-tracer.h"
++#include "../lttng-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 lttng_event *event = *data;
++ struct lttng_channel *chan = event->chan;
+ struct lib_ring_buffer_ctx ctx;
+ struct {
+ unsigned long ip;
+@@ -46,13 +59,13 @@ void lttng_ftrace_handler(unsigned long
+ return;
+
+ lib_ring_buffer_ctx_init(&ctx, chan->chan, event,
+- sizeof(payload), ltt_alignof(payload), -1);
++ sizeof(payload), lttng_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));
++ lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload));
+ chan->ops->event_write(&ctx, &payload, sizeof(payload));
+ chan->ops->event_commit(&ctx);
+ return;
+@@ -62,7 +75,7 @@ void lttng_ftrace_handler(unsigned long
+ * Create event description
+ */
+ static
+-int lttng_create_ftrace_event(const char *name, struct ltt_event *event)
++int lttng_create_ftrace_event(const char *name, struct lttng_event *event)
+ {
+ struct lttng_event_field *fields;
+ struct lttng_event_desc *desc;
+@@ -86,7 +99,7 @@ int lttng_create_ftrace_event(const char
+ 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.alignment = lttng_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;
+@@ -95,7 +108,7 @@ int lttng_create_ftrace_event(const char
+ 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.alignment = lttng_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;
+@@ -120,7 +133,7 @@ struct ftrace_probe_ops lttng_ftrace_ops
+
+ int lttng_ftrace_register(const char *name,
+ const char *symbol_name,
+- struct ltt_event *event)
++ struct lttng_event *event)
+ {
+ int ret;
+
+@@ -151,14 +164,14 @@ error:
+ }
+ EXPORT_SYMBOL_GPL(lttng_ftrace_register);
+
+-void lttng_ftrace_unregister(struct ltt_event *event)
++void lttng_ftrace_unregister(struct lttng_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)
++void lttng_ftrace_destroy_private(struct lttng_event *event)
+ {
+ kfree(event->u.ftrace.symbol_name);
+ kfree(event->desc->fields);
+--- a/drivers/staging/lttng/probes/lttng-kprobes.c
++++ b/drivers/staging/lttng/probes/lttng-kprobes.c
+@@ -1,26 +1,39 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * probes/lttng-kprobes.c
+ *
+ * LTTng kprobes integration module.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/kprobes.h>
+ #include <linux/slab.h>
+-#include "../ltt-events.h"
++#include "../lttng-events.h"
+ #include "../wrapper/ringbuffer/frontend_types.h"
+ #include "../wrapper/vmalloc.h"
+-#include "../ltt-tracer.h"
++#include "../lttng-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 lttng_event *event =
++ container_of(p, struct lttng_event, u.kprobe.kp);
++ struct lttng_channel *chan = event->chan;
+ struct lib_ring_buffer_ctx ctx;
+ int ret;
+ unsigned long data = (unsigned long) p->addr;
+@@ -33,11 +46,11 @@ int lttng_kprobes_handler_pre(struct kpr
+ return 0;
+
+ lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data),
+- ltt_alignof(data), -1);
++ lttng_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));
++ lib_ring_buffer_align_ctx(&ctx, lttng_alignof(data));
+ chan->ops->event_write(&ctx, &data, sizeof(data));
+ chan->ops->event_commit(&ctx);
+ return 0;
+@@ -47,7 +60,7 @@ int lttng_kprobes_handler_pre(struct kpr
+ * Create event description
+ */
+ static
+-int lttng_create_kprobe_event(const char *name, struct ltt_event *event)
++int lttng_create_kprobe_event(const char *name, struct lttng_event *event)
+ {
+ struct lttng_event_field *field;
+ struct lttng_event_desc *desc;
+@@ -71,7 +84,7 @@ int lttng_create_kprobe_event(const char
+ 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.alignment = lttng_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;
+@@ -92,7 +105,7 @@ int lttng_kprobes_register(const char *n
+ const char *symbol_name,
+ uint64_t offset,
+ uint64_t addr,
+- struct ltt_event *event)
++ struct lttng_event *event)
+ {
+ int ret;
+
+@@ -107,14 +120,14 @@ int lttng_kprobes_register(const char *n
+ 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),
++ kzalloc(LTTNG_KERNEL_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));
++ LTTNG_KERNEL_SYM_NAME_LEN * sizeof(char));
+ event->u.kprobe.kp.symbol_name =
+ event->u.kprobe.symbol_name;
+ }
+@@ -144,13 +157,13 @@ error:
+ }
+ EXPORT_SYMBOL_GPL(lttng_kprobes_register);
+
+-void lttng_kprobes_unregister(struct ltt_event *event)
++void lttng_kprobes_unregister(struct lttng_event *event)
+ {
+ unregister_kprobe(&event->u.kprobe.kp);
+ }
+ EXPORT_SYMBOL_GPL(lttng_kprobes_unregister);
+
+-void lttng_kprobes_destroy_private(struct ltt_event *event)
++void lttng_kprobes_destroy_private(struct lttng_event *event)
+ {
+ kfree(event->u.kprobe.symbol_name);
+ kfree(event->desc->fields);
+--- a/drivers/staging/lttng/probes/lttng-kretprobes.c
++++ b/drivers/staging/lttng/probes/lttng-kretprobes.c
+@@ -1,20 +1,33 @@
+ /*
+- * (C) Copyright 2009-2011 -
+- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * probes/lttng-kretprobes.c
+ *
+ * LTTng kretprobes integration module.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/kprobes.h>
+ #include <linux/slab.h>
+ #include <linux/kref.h>
+-#include "../ltt-events.h"
++#include "../lttng-events.h"
+ #include "../wrapper/ringbuffer/frontend_types.h"
+ #include "../wrapper/vmalloc.h"
+-#include "../ltt-tracer.h"
++#include "../lttng-tracer.h"
+
+ enum lttng_kretprobe_type {
+ EVENT_ENTRY = 0,
+@@ -23,7 +36,7 @@ enum lttng_kretprobe_type {
+
+ struct lttng_krp {
+ struct kretprobe krp;
+- struct ltt_event *event[2]; /* ENTRY and RETURN */
++ struct lttng_event *event[2]; /* ENTRY and RETURN */
+ struct kref kref_register;
+ struct kref kref_alloc;
+ };
+@@ -35,9 +48,9 @@ int _lttng_kretprobes_handler(struct kre
+ {
+ struct lttng_krp *lttng_krp =
+ container_of(krpi->rp, struct lttng_krp, krp);
+- struct ltt_event *event =
++ struct lttng_event *event =
+ lttng_krp->event[type];
+- struct ltt_channel *chan = event->chan;
++ struct lttng_channel *chan = event->chan;
+ struct lib_ring_buffer_ctx ctx;
+ int ret;
+ struct {
+@@ -56,11 +69,11 @@ int _lttng_kretprobes_handler(struct kre
+ payload.parent_ip = (unsigned long) krpi->ret_addr;
+
+ lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(payload),
+- ltt_alignof(payload), -1);
++ lttng_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));
++ lib_ring_buffer_align_ctx(&ctx, lttng_alignof(payload));
+ chan->ops->event_write(&ctx, &payload, sizeof(payload));
+ chan->ops->event_commit(&ctx);
+ return 0;
+@@ -84,7 +97,7 @@ int lttng_kretprobes_handler_return(stru
+ * Create event description
+ */
+ static
+-int lttng_create_kprobe_event(const char *name, struct ltt_event *event,
++int lttng_create_kprobe_event(const char *name, struct lttng_event *event,
+ enum lttng_kretprobe_type type)
+ {
+ struct lttng_event_field *fields;
+@@ -125,7 +138,7 @@ int lttng_create_kprobe_event(const char
+ 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.alignment = lttng_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;
+@@ -134,7 +147,7 @@ int lttng_create_kprobe_event(const char
+ 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.alignment = lttng_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;
+@@ -156,8 +169,8 @@ int lttng_kretprobes_register(const char
+ const char *symbol_name,
+ uint64_t offset,
+ uint64_t addr,
+- struct ltt_event *event_entry,
+- struct ltt_event *event_return)
++ struct lttng_event *event_entry,
++ struct lttng_event *event_return)
+ {
+ int ret;
+ struct lttng_krp *lttng_krp;
+@@ -247,7 +260,7 @@ void _lttng_kretprobes_unregister_releas
+ unregister_kretprobe(&lttng_krp->krp);
+ }
+
+-void lttng_kretprobes_unregister(struct ltt_event *event)
++void lttng_kretprobes_unregister(struct lttng_event *event)
+ {
+ kref_put(&event->u.kretprobe.lttng_krp->kref_register,
+ _lttng_kretprobes_unregister_release);
+@@ -262,7 +275,7 @@ void _lttng_kretprobes_release(struct kr
+ kfree(lttng_krp->krp.kp.symbol_name);
+ }
+
+-void lttng_kretprobes_destroy_private(struct ltt_event *event)
++void lttng_kretprobes_destroy_private(struct lttng_event *event)
+ {
+ kfree(event->desc->fields);
+ kfree(event->desc->name);
+--- a/drivers/staging/lttng/probes/lttng-probe-block.c
++++ b/drivers/staging/lttng/probes/lttng-probe-block.c
+@@ -1,11 +1,23 @@
+ /*
+ * probes/lttng-probe-block.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng block probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+--- a/drivers/staging/lttng/probes/lttng-probe-irq.c
++++ b/drivers/staging/lttng/probes/lttng-probe-irq.c
+@@ -1,11 +1,23 @@
+ /*
+ * probes/lttng-probe-irq.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng irq probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+--- a/drivers/staging/lttng/probes/lttng-probe-kvm.c
++++ b/drivers/staging/lttng/probes/lttng-probe-kvm.c
+@@ -1,11 +1,23 @@
+ /*
+ * probes/lttng-probe-kvm.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng kvm probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+--- a/drivers/staging/lttng/probes/lttng-probe-lttng.c
++++ b/drivers/staging/lttng/probes/lttng-probe-lttng.c
+@@ -1,11 +1,23 @@
+ /*
+ * probes/lttng-probe-core.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng core probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+--- a/drivers/staging/lttng/probes/lttng-probe-sched.c
++++ b/drivers/staging/lttng/probes/lttng-probe-sched.c
+@@ -1,11 +1,23 @@
+ /*
+ * probes/lttng-probe-sched.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng sched probes.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+--- /dev/null
++++ b/drivers/staging/lttng/probes/lttng-probe-signal.c
+@@ -0,0 +1,42 @@
++/*
++ * probes/lttng-probe-signal.c
++ *
++ * LTTng signal probes.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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/signal.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/signal.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
++MODULE_DESCRIPTION("LTTng signal probes");
+--- /dev/null
++++ b/drivers/staging/lttng/probes/lttng-probe-statedump.c
+@@ -0,0 +1,45 @@
++/*
++ * probes/lttng-probe-statedump.c
++ *
++ * LTTng statedump probes.
++ *
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/netlink.h>
++#include <linux/inet.h>
++#include <linux/ip.h>
++#include <linux/netdevice.h>
++#include <linux/inetdevice.h>
++#include "../lttng-events.h"
++
++/*
++ * Create LTTng tracepoint probes.
++ */
++#define LTTNG_PACKAGE_BUILD
++#define CREATE_TRACE_POINTS
++#define TP_SESSION_CHECK
++#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module
++#define TRACE_INCLUDE_FILE lttng-statedump
++
++#include "../instrumentation/events/lttng-module/lttng-statedump.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
++MODULE_DESCRIPTION("LTTng statedump probes");
+--- /dev/null
++++ b/drivers/staging/lttng/probes/lttng-probe-timer.c
+@@ -0,0 +1,43 @@
++/*
++ * probes/lttng-probe-timer.c
++ *
++ * LTTng timer probes.
++ *
++ * Copyright (C) 2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#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 <linux/sched.h>
++#include <trace/events/timer.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/timer.h"
++
++MODULE_LICENSE("GPL and additional rights");
++MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
++MODULE_DESCRIPTION("LTTng timer probes");
+--- a/drivers/staging/lttng/probes/lttng-type-list.h
++++ b/drivers/staging/lttng/probes/lttng-type-list.h
+@@ -1,9 +1,21 @@
+ /*
+ * lttng-type-list.h
+ *
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ /* Type list, used to create metadata */
+--- a/drivers/staging/lttng/probes/lttng-types.c
++++ b/drivers/staging/lttng/probes/lttng-types.c
+@@ -1,17 +1,29 @@
+ /*
+ * probes/lttng-types.c
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng types.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/module.h>
+ #include <linux/types.h>
+ #include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */
+-#include "../ltt-events.h"
++#include "../lttng-events.h"
+ #include "lttng-types.h"
+ #include <linux/hrtimer.h>
+
+--- a/drivers/staging/lttng/probes/lttng-types.h
++++ b/drivers/staging/lttng/probes/lttng-types.h
+@@ -8,18 +8,30 @@
+ /*
+ * probes/lttng-types.h
+ *
+- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+- *
+ * LTTng types.
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/seq_file.h>
+ #include "lttng.h"
+-#include "../ltt-events.h"
+-#include "../ltt-tracer.h"
+-#include "../ltt-endian.h"
++#include "../lttng-events.h"
++#include "../lttng-tracer.h"
++#include "../lttng-endian.h"
+
+ #endif /* _LTTNG_PROBES_LTTNG_TYPES_H */
+
+--- a/drivers/staging/lttng/probes/lttng.h
++++ b/drivers/staging/lttng/probes/lttng.h
+@@ -4,9 +4,21 @@
+ /*
+ * lttng.h
+ *
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #undef PARAMS
+--- a/drivers/staging/lttng/wrapper/ftrace.h
++++ b/drivers/staging/lttng/wrapper/ftrace.h
+@@ -1,14 +1,28 @@
+-#ifndef _LTT_WRAPPER_FTRACE_H
+-#define _LTT_WRAPPER_FTRACE_H
++#ifndef _LTTNG_WRAPPER_FTRACE_H
++#define _LTTNG_WRAPPER_FTRACE_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/ftrace.h
+ *
+ * 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.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/ftrace.h>
+@@ -67,4 +81,4 @@ void wrapper_unregister_ftrace_function_
+ }
+ #endif
+
+-#endif /* _LTT_WRAPPER_FTRACE_H */
++#endif /* _LTTNG_WRAPPER_FTRACE_H */
+--- a/drivers/staging/lttng/wrapper/inline_memcpy.h
++++ b/drivers/staging/lttng/wrapper/inline_memcpy.h
+@@ -1,9 +1,21 @@
+ /*
+ * wrapper/inline_memcpy.h
+ *
+- * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #if !defined(__HAVE_ARCH_INLINE_MEMCPY) && !defined(inline_memcpy)
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/irqdesc.c
+@@ -0,0 +1,58 @@
++/*
++ * wrapper/irqdesc.c
++ *
++ * wrapper around irq_to_desc. Using KALLSYMS to get its address when
++ * available, else we need to have a kernel that exports this function to GPL
++ * modules.
++ *
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#ifdef CONFIG_KALLSYMS
++
++#include <linux/kallsyms.h>
++#include <linux/interrupt.h>
++#include <linux/irqnr.h>
++#include "kallsyms.h"
++#include "irqdesc.h"
++
++static
++struct irq_desc *(*irq_to_desc_sym)(unsigned int irq);
++
++struct irq_desc *wrapper_irq_to_desc(unsigned int irq)
++{
++ if (!irq_to_desc_sym)
++ irq_to_desc_sym = (void *) kallsyms_lookup_funcptr("irq_to_desc");
++ if (irq_to_desc_sym) {
++ return irq_to_desc_sym(irq);
++ } else {
++ printk(KERN_WARNING "LTTng: irq_to_desc symbol lookup failed.\n");
++ return NULL;
++ }
++}
++
++#else
++
++#include <linux/interrupt.h>
++#include <linux/irqnr.h>
++
++struct irq_desc *wrapper_irq_to_desc(unsigned int irq)
++{
++ return irq_to_desc(irq);
++}
++
++#endif
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/irqdesc.h
+@@ -0,0 +1,33 @@
++#ifndef _LTTNG_WRAPPER_IRQDESC_H
++#define _LTTNG_WRAPPER_IRQDESC_H
++
++/*
++ * wrapper/irqdesc.h
++ *
++ * wrapper around irq_to_desc. Using KALLSYMS to get its address when
++ * available, else we need to have a kernel that exports this function to GPL
++ * modules.
++ *
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <linux/interrupt.h>
++#include <linux/irqnr.h>
++
++struct irq_desc *wrapper_irq_to_desc(unsigned int irq);
++
++#endif /* _LTTNG_WRAPPER_IRQDESC_H */
+--- a/drivers/staging/lttng/wrapper/kallsyms.h
++++ b/drivers/staging/lttng/wrapper/kallsyms.h
+@@ -1,18 +1,49 @@
+-#ifndef _LTT_WRAPPER_KALLSYMS_H
+-#define _LTT_WRAPPER_KALLSYMS_H
+-
+-#include <linux/kallsyms.h>
++#ifndef _LTTNG_WRAPPER_KALLSYMS_H
++#define _LTTNG_WRAPPER_KALLSYMS_H
+
+ /*
+- * Copyright (C) 2011 Avik Sil (avik.sil@linaro.org)
++ * wrapper/kallsyms.h
+ *
+ * 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.
++ * Copyright (C) 2011 Avik Sil (avik.sil@linaro.org)
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ * Copyright (C) 2011 Avik Sil (avik.sil@linaro.org)
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
++#include <linux/kallsyms.h>
++
+ static inline
+ unsigned long kallsyms_lookup_funcptr(const char *name)
+ {
+@@ -27,4 +58,4 @@ unsigned long kallsyms_lookup_funcptr(co
+ #endif
+ return addr;
+ }
+-#endif /* _LTT_WRAPPER_KALLSYMS_H */
++#endif /* _LTTNG_WRAPPER_KALLSYMS_H */
+--- a/drivers/staging/lttng/wrapper/perf.h
++++ b/drivers/staging/lttng/wrapper/perf.h
+@@ -1,10 +1,24 @@
+-#ifndef _LTT_WRAPPER_PERF_H
+-#define _LTT_WRAPPER_PERF_H
++#ifndef _LTTNG_WRAPPER_PERF_H
++#define _LTTNG_WRAPPER_PERF_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/perf.h
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/perf_event.h>
+@@ -29,4 +43,4 @@ wrapper_perf_event_create_kernel_counter
+ }
+ #endif
+
+-#endif /* _LTT_WRAPPER_PERF_H */
++#endif /* _LTTNG_WRAPPER_PERF_H */
+--- a/drivers/staging/lttng/wrapper/poll.h
++++ b/drivers/staging/lttng/wrapper/poll.h
+@@ -2,12 +2,32 @@
+ #define _LTTNG_WRAPPER_POLL_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/poll.h
+ *
+ * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+-#include <linux/poll.h>
++ #include <linux/poll.h>
++
++/*
++ * Note: poll_wait_set_exclusive() is defined as no-op. Thundering herd
++ * effect can be noticed with large number of consumer threads.
++ */
+
+ #define poll_wait_set_exclusive(poll_table)
+
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/random.c
+@@ -0,0 +1,77 @@
++/*
++ * wrapper/random.c
++ *
++ * wrapper around bootid read. Using KALLSYMS to get its address when
++ * available, else we need to have a kernel that exports this function to GPL
++ * modules.
++ *
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++/* boot_id depends on sysctl */
++#if defined(CONFIG_SYSCTL)
++
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/sched.h>
++#include <linux/uaccess.h>
++#include "random.h"
++
++/*
++ * Returns string boot id.
++ */
++int wrapper_get_bootid(char *bootid)
++{
++ struct file *file;
++ int ret;
++ ssize_t len;
++ mm_segment_t old_fs;
++
++ file = filp_open("/proc/sys/kernel/random/boot_id", O_RDONLY, 0);
++ if (IS_ERR(file))
++ return PTR_ERR(file);
++
++ old_fs = get_fs();
++ set_fs(KERNEL_DS);
++
++ if (!file->f_op || !file->f_op->read) {
++ ret = -EINVAL;
++ goto end;
++ }
++
++ len = file->f_op->read(file, bootid, BOOT_ID_LEN - 1, &file->f_pos);
++ if (len != BOOT_ID_LEN - 1) {
++ ret = -EINVAL;
++ goto end;
++ }
++
++ bootid[BOOT_ID_LEN - 1] = '\0';
++ ret = 0;
++end:
++ set_fs(old_fs);
++ filp_close(file, current->files);
++ return ret;
++}
++
++#else
++
++int wrapper_get_bootid(char *bootid)
++{
++ return -ENOSYS;
++}
++
++#endif
+--- /dev/null
++++ b/drivers/staging/lttng/wrapper/random.h
+@@ -0,0 +1,32 @@
++#ifndef _LTTNG_WRAPPER_RANDOM_H
++#define _LTTNG_WRAPPER_RANDOM_H
++
++/*
++ * wrapper/random.h
++ *
++ * wrapper around bootid read. Using KALLSYMS to get its address when
++ * available, else we need to have a kernel that exports this function to GPL
++ * modules.
++ *
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#define BOOT_ID_LEN 37
++
++int wrapper_get_bootid(char *bootid);
++
++#endif /* _LTTNG_WRAPPER_RANDOM_H */
+--- a/drivers/staging/lttng/wrapper/spinlock.h
++++ b/drivers/staging/lttng/wrapper/spinlock.h
+@@ -1,10 +1,24 @@
+-#ifndef _LTT_WRAPPER_SPINLOCK_H
+-#define _LTT_WRAPPER_SPINLOCK_H
++#ifndef _LTTNG_WRAPPER_SPINLOCK_H
++#define _LTTNG_WRAPPER_SPINLOCK_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/spinlock.h
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/version.h>
+@@ -23,4 +37,4 @@
+
+
+ #endif
+-#endif /* _LTT_WRAPPER_SPINLOCK_H */
++#endif /* _LTTNG_WRAPPER_SPINLOCK_H */
+--- a/drivers/staging/lttng/wrapper/splice.c
++++ b/drivers/staging/lttng/wrapper/splice.c
+@@ -1,11 +1,25 @@
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/splice.c
+ *
+- * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
++ * wrapper around splice_to_pipe. 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.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #ifdef CONFIG_KALLSYMS
+--- a/drivers/staging/lttng/wrapper/splice.h
++++ b/drivers/staging/lttng/wrapper/splice.h
+@@ -1,14 +1,28 @@
+-#ifndef _LTT_WRAPPER_SPLICE_H
+-#define _LTT_WRAPPER_SPLICE_H
++#ifndef _LTTNG_WRAPPER_SPLICE_H
++#define _LTTNG_WRAPPER_SPLICE_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/splice.h
+ *
+- * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when
++ * wrapper around splice_to_pipe. 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.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/splice.h>
+@@ -20,4 +34,4 @@ ssize_t wrapper_splice_to_pipe(struct pi
+ #define PIPE_DEF_BUFFERS 16
+ #endif
+
+-#endif /* _LTT_WRAPPER_SPLICE_H */
++#endif /* _LTTNG_WRAPPER_SPLICE_H */
+--- a/drivers/staging/lttng/wrapper/trace-clock.h
++++ b/drivers/staging/lttng/wrapper/trace-clock.h
+@@ -1,15 +1,29 @@
++#ifndef _LTTNG_TRACE_CLOCK_H
++#define _LTTNG_TRACE_CLOCK_H
++
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/trace-clock.h
+ *
+ * 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.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+-#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 */
+@@ -18,6 +32,7 @@
+ #include <linux/ktime.h>
+ #include <linux/time.h>
+ #include <linux/hrtimer.h>
++#include "random.h"
+
+ static inline u64 trace_clock_monotonic_wrapper(void)
+ {
+@@ -44,18 +59,24 @@ static inline u64 trace_clock_read64(voi
+ return (u64) trace_clock_monotonic_wrapper();
+ }
+
+-static inline u64 trace_clock_frequency(void)
++static inline u64 trace_clock_freq(void)
+ {
+- return (u64)NSEC_PER_SEC;
++ return (u64) NSEC_PER_SEC;
+ }
+
+-static inline u32 trace_clock_freq_scale(void)
++static inline int trace_clock_uuid(char *uuid)
+ {
+- return 1;
++ return wrapper_get_bootid(uuid);
+ }
+
+ static inline int get_trace_clock(void)
+ {
++ /*
++ * LTTng: Using mainline kernel monotonic clock. NMIs will not be
++ * traced, and expect significant performance degradation compared to
++ * the LTTng trace clocks. Integration of the LTTng 0.x trace clocks
++ * into LTTng 2.0 is planned in a near future.
++ */
+ 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");
+@@ -72,4 +93,4 @@ static inline void put_trace_clock(void)
+
+ #endif /* CONFIG_HAVE_TRACE_CLOCK */
+
+-#endif /* _LTT_TRACE_CLOCK_H */
++#endif /* _LTTNG_TRACE_CLOCK_H */
+--- a/drivers/staging/lttng/wrapper/uuid.h
++++ b/drivers/staging/lttng/wrapper/uuid.h
+@@ -1,10 +1,24 @@
+-#ifndef _LTT_WRAPPER_UUID_H
+-#define _LTT_WRAPPER_UUID_H
++#ifndef _LTTNG_WRAPPER_UUID_H
++#define _LTTNG_WRAPPER_UUID_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/uuid.h
+ *
+- * Dual LGPL v2.1/GPL v2 license.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #include <linux/version.h>
+@@ -26,4 +40,4 @@ void uuid_le_gen(uuid_le *u)
+ }
+
+ #endif
+-#endif /* _LTT_WRAPPER_UUID_H */
++#endif /* _LTTNG_WRAPPER_UUID_H */
+--- a/drivers/staging/lttng/wrapper/vmalloc.h
++++ b/drivers/staging/lttng/wrapper/vmalloc.h
+@@ -1,14 +1,28 @@
+-#ifndef _LTT_WRAPPER_VMALLOC_H
+-#define _LTT_WRAPPER_VMALLOC_H
++#ifndef _LTTNG_WRAPPER_VMALLOC_H
++#define _LTTNG_WRAPPER_VMALLOC_H
+
+ /*
+- * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
++ * wrapper/vmalloc.h
+ *
+ * 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.
++ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; only
++ * version 2.1 of the License.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ #ifdef CONFIG_KALLSYMS
+@@ -46,4 +60,4 @@ void wrapper_vmalloc_sync_all(void)
+ }
+ #endif
+
+-#endif /* _LTT_WRAPPER_VMALLOC_H */
++#endif /* _LTTNG_WRAPPER_VMALLOC_H */
diff --git a/series b/series
index e4832e02d8ab9..b9a235ef5e0cb 100644
--- a/series
+++ b/series
@@ -93,4 +93,4 @@ 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
-
+patches.lttng/lttng-update-to-v2.0.1.patch