blob: e12c0f0510eb5a27bac83fd2a322414064aa4a4d [file] [log] [blame]
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 */