* [lttng-dev] LTTng driver submission for staging (2nd attempt)
@ 2011-11-28 12:42 Mathieu Desnoyers
2011-11-28 12:42 ` [lttng-dev] [PATCH 01/20] lttng lib: lttng priority heap Mathieu Desnoyers
` (20 more replies)
0 siblings, 21 replies; 25+ messages in thread
From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw)
Hi Greg,
This a resend of the LTTng driver patchset for staging. After your
review of the first round, I proceeded to the following modifications:
- Understood that git format-patch must be given the commit prior to the
first commit to include in the patchset as first commit ID, this
adding the missing 0001-lttng-lib-lttng-priority-heap.patch. (cause of
the build failure)
- Added missing (empty) system call instrumentation "override" files,
that were known to git, but discarded by git format-patch. Made sure
they appear in the patches as place-holders by adding a comment in
those files.
- Removed gpl*.txt/lgpl*.txt license files.
- Removed Changelog.
- Added TODO file.
- While going through the TODO, I noticed that I needed to fix the
syscall TRACE_EVENT generation scripts (along with the headers
generated) to complete support of 32-bit compat syscalls on x86-64. I
did these modifications.
- Tested the build on x86-64/x86-32, and run-time tested on x86-32,
using the patchset rather than the git tree commits to ensure you
won't run into any issues on your side.
Diffstat:
drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c | 207
drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h | 117
drivers/staging/lttng/lib/ringbuffer/api.h | 25
drivers/staging/lttng/lib/ringbuffer/backend.h | 250 +
drivers/staging/lttng/lib/ringbuffer/backend_internal.h | 449 ++
drivers/staging/lttng/lib/ringbuffer/backend_types.h | 80
drivers/staging/lttng/lib/ringbuffer/config.h | 298 +
drivers/staging/lttng/lib/ringbuffer/frontend.h | 228 +
drivers/staging/lttng/lib/ringbuffer/frontend_api.h | 358 +
drivers/staging/lttng/lib/ringbuffer/frontend_internal.h | 424 +
drivers/staging/lttng/lib/ringbuffer/frontend_types.h | 176
drivers/staging/lttng/lib/ringbuffer/iterator.h | 70
drivers/staging/lttng/lib/ringbuffer/nohz.h | 30
drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c | 854 +++
drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c | 1721 +++++++
drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c | 798 +++
drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c | 115
drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c | 202
drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c | 387 +
drivers/staging/lttng/lib/ringbuffer/vatomic.h | 85
drivers/staging/lttng/lib/ringbuffer/vfs.h | 89
drivers/staging/lttng/lib/bitfield.h | 400 +
drivers/staging/lttng/lib/bug.h | 29
drivers/staging/lttng/lib/align.h | 61
drivers/staging/lttng/lib/Makefile | 11
drivers/staging/lttng/wrapper/ftrace.h | 70
drivers/staging/lttng/wrapper/inline_memcpy.h | 11
drivers/staging/lttng/wrapper/kallsyms.h | 28
drivers/staging/lttng/wrapper/perf.h | 32
drivers/staging/lttng/wrapper/poll.h | 14
drivers/staging/lttng/wrapper/ringbuffer/api.h | 1
drivers/staging/lttng/wrapper/ringbuffer/backend.h | 1
drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h | 2
drivers/staging/lttng/wrapper/ringbuffer/backend_types.h | 1
drivers/staging/lttng/wrapper/ringbuffer/config.h | 1
drivers/staging/lttng/wrapper/ringbuffer/frontend.h | 1
drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h | 1
drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h | 1
drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h | 1
drivers/staging/lttng/wrapper/ringbuffer/iterator.h | 1
drivers/staging/lttng/wrapper/ringbuffer/nohz.h | 1
drivers/staging/lttng/wrapper/ringbuffer/vatomic.h | 1
drivers/staging/lttng/wrapper/ringbuffer/vfs.h | 1
drivers/staging/lttng/wrapper/spinlock.h | 26
drivers/staging/lttng/wrapper/splice.c | 46
drivers/staging/lttng/wrapper/splice.h | 23
drivers/staging/lttng/wrapper/trace-clock.h | 75
drivers/staging/lttng/wrapper/uuid.h | 29
drivers/staging/lttng/wrapper/vmalloc.h | 49
drivers/staging/lttng/instrumentation/events/README | 7
drivers/staging/lttng/instrumentation/events/lttng-module/block.h | 626 ++
drivers/staging/lttng/instrumentation/events/lttng-module/irq.h | 155
drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h | 312 +
drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h | 34
drivers/staging/lttng/instrumentation/events/lttng-module/sched.h | 400 +
drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h | 76
drivers/staging/lttng/instrumentation/events/mainline/block.h | 569 ++
drivers/staging/lttng/instrumentation/events/mainline/irq.h | 150
drivers/staging/lttng/instrumentation/events/mainline/kvm.h | 312 +
drivers/staging/lttng/instrumentation/events/mainline/sched.h | 397 +
drivers/staging/lttng/instrumentation/events/mainline/syscalls.h | 75
drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 | 263 +
drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 | 291 +
drivers/staging/lttng/instrumentation/syscalls/README | 18
drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h | 3
drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h | 3
drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h | 7
drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h | 14
drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h | 7
drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h | 4
drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h | 55
drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h | 1163 +++++
drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h | 38
drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h | 2232 ++++++++++
drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h | 17
drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h | 1013 ++++
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.h | 2076 +++++++++
drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h | 5
drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile | 1
drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c | 85
drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh | 275 +
drivers/staging/lttng/ltt-ring-buffer-client-discard.c | 21
drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c | 21
drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c | 21
drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c | 21
drivers/staging/lttng/ltt-ring-buffer-client.h | 569 ++
drivers/staging/lttng/ltt-ring-buffer-metadata-client.c | 21
drivers/staging/lttng/ltt-ring-buffer-metadata-client.h | 330 +
drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c | 21
drivers/staging/lttng/ltt-endian.h | 31
drivers/staging/lttng/ltt-events.c | 1009 ++++
drivers/staging/lttng/ltt-events.h | 452 ++
drivers/staging/lttng/ltt-probes.c | 164
drivers/staging/lttng/ltt-tracer-core.h | 28
drivers/staging/lttng/ltt-tracer.h | 67
drivers/staging/lttng/ltt-context.c | 93
drivers/staging/lttng/lttng-context-nice.c | 68
drivers/staging/lttng/lttng-context-perf-counters.c | 271 +
drivers/staging/lttng/lttng-context-pid.c | 68
drivers/staging/lttng/lttng-context-ppid.c | 71
drivers/staging/lttng/lttng-context-prio.c | 89
drivers/staging/lttng/lttng-context-procname.c | 72
drivers/staging/lttng/lttng-context-tid.c | 68
drivers/staging/lttng/lttng-context-vpid.c | 74
drivers/staging/lttng/lttng-context-vppid.c | 79
drivers/staging/lttng/lttng-context-vtid.c | 74
drivers/staging/lttng/lttng-calibrate.c | 30
drivers/staging/lttng/ltt-debugfs-abi.c | 777 +++
drivers/staging/lttng/ltt-debugfs-abi.h | 153
drivers/staging/lttng/LICENSE | 27
drivers/staging/lttng/README | 48
drivers/staging/lttng/TODO | 137
drivers/staging/lttng/lttng-syscalls.c | 438 +
drivers/staging/lttng/probes/Makefile | 37
drivers/staging/lttng/probes/define_trace.h | 132
drivers/staging/lttng/probes/lttng-events-reset.h | 84
drivers/staging/lttng/probes/lttng-events.h | 703 +++
drivers/staging/lttng/probes/lttng-ftrace.c | 188
drivers/staging/lttng/probes/lttng-kprobes.c | 164
drivers/staging/lttng/probes/lttng-kretprobes.c | 277 +
drivers/staging/lttng/probes/lttng-probe-block.c | 31
drivers/staging/lttng/probes/lttng-probe-irq.c | 31
drivers/staging/lttng/probes/lttng-probe-kvm.c | 31
drivers/staging/lttng/probes/lttng-probe-lttng.c | 24
drivers/staging/lttng/probes/lttng-probe-sched.c | 30
drivers/staging/lttng/probes/lttng-type-list.h | 21
drivers/staging/lttng/probes/lttng-types.c | 49
drivers/staging/lttng/probes/lttng-types.h | 72
drivers/staging/lttng/probes/lttng.h | 15
drivers/staging/lttng/Kconfig | 35
drivers/staging/lttng/Makefile | 33
drivers/staging/Kconfig | 2
drivers/staging/Makefile | 1
MAINTAINERS | 7
135 files changed, 25947 insertions(+)
Thanks!
Mathieu
^ permalink raw reply [flat|nested] 25+ messages in thread* [lttng-dev] [PATCH 01/20] lttng lib: lttng priority heap 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 02/20] lttng lib: ring buffer Mathieu Desnoyers ` (19 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- .../staging/lttng/lib/prio_heap/lttng_prio_heap.c | 207 ++++++++++++++++++++ .../staging/lttng/lib/prio_heap/lttng_prio_heap.h | 117 +++++++++++ 2 files changed, 324 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c create mode 100644 drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h diff --git a/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c new file mode 100644 index 0000000..2fce143 --- /dev/null +++ b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.c @@ -0,0 +1,207 @@ +/* + * lttng_prio_heap.c + * + * Priority heap containing pointers. Based on CLRS, chapter 6. + * + * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + +#include <linux/slab.h> +#include "lttng_prio_heap.h" + +#ifdef DEBUG_HEAP +void lttng_check_heap(const struct lttng_ptr_heap *heap) +{ + size_t i; + + if (!heap->len) + return; + + for (i = 1; i < heap->len; i++) + WARN_ON_ONCE(!heap->gt(heap->ptrs[i], heap->ptrs[0])); +} +#endif + +static +size_t parent(size_t i) +{ + return (i -1) >> 1; +} + +static +size_t left(size_t i) +{ + return (i << 1) + 1; +} + +static +size_t right(size_t i) +{ + return (i << 1) + 2; +} + +/* + * Copy of heap->ptrs pointer is invalid after heap_grow. + */ +static +int heap_grow(struct lttng_ptr_heap *heap, size_t new_len) +{ + void **new_ptrs; + + if (heap->alloc_len >= new_len) + return 0; + + heap->alloc_len = max_t(size_t, new_len, heap->alloc_len << 1); + new_ptrs = kmalloc(heap->alloc_len * sizeof(void *), heap->gfpmask); + if (!new_ptrs) + return -ENOMEM; + if (heap->ptrs) + memcpy(new_ptrs, heap->ptrs, heap->len * sizeof(void *)); + kfree(heap->ptrs); + heap->ptrs = new_ptrs; + return 0; +} + +static +int heap_set_len(struct lttng_ptr_heap *heap, size_t new_len) +{ + int ret; + + ret = heap_grow(heap, new_len); + if (ret) + return ret; + heap->len = new_len; + return 0; +} + +int lttng_heap_init(struct lttng_ptr_heap *heap, size_t alloc_len, + gfp_t gfpmask, int gt(void *a, void *b)) +{ + heap->ptrs = NULL; + heap->len = 0; + heap->alloc_len = 0; + heap->gt = gt; + heap->gfpmask = gfpmask; + /* + * Minimum size allocated is 1 entry to ensure memory allocation + * never fails within heap_replace_max. + */ + return heap_grow(heap, max_t(size_t, 1, alloc_len)); +} + +void lttng_heap_free(struct lttng_ptr_heap *heap) +{ + kfree(heap->ptrs); +} + +static void heapify(struct lttng_ptr_heap *heap, size_t i) +{ + void **ptrs = heap->ptrs; + size_t l, r, largest; + + for (;;) { + void *tmp; + + l = left(i); + r = right(i); + if (l < heap->len && heap->gt(ptrs[l], ptrs[i])) + largest = l; + else + largest = i; + if (r < heap->len && heap->gt(ptrs[r], ptrs[largest])) + largest = r; + if (largest == i) + break; + tmp = ptrs[i]; + ptrs[i] = ptrs[largest]; + ptrs[largest] = tmp; + i = largest; + } + lttng_check_heap(heap); +} + +void *lttng_heap_replace_max(struct lttng_ptr_heap *heap, void *p) +{ + void *res; + + if (!heap->len) { + (void) heap_set_len(heap, 1); + heap->ptrs[0] = p; + lttng_check_heap(heap); + return NULL; + } + + /* Replace the current max and heapify */ + res = heap->ptrs[0]; + heap->ptrs[0] = p; + heapify(heap, 0); + return res; +} + +int lttng_heap_insert(struct lttng_ptr_heap *heap, void *p) +{ + void **ptrs; + size_t pos; + int ret; + + ret = heap_set_len(heap, heap->len + 1); + if (ret) + return ret; + ptrs = heap->ptrs; + pos = heap->len - 1; + while (pos > 0 && heap->gt(p, ptrs[parent(pos)])) { + /* Move parent down until we find the right spot */ + ptrs[pos] = ptrs[parent(pos)]; + pos = parent(pos); + } + ptrs[pos] = p; + lttng_check_heap(heap); + return 0; +} + +void *lttng_heap_remove(struct lttng_ptr_heap *heap) +{ + switch (heap->len) { + case 0: + return NULL; + case 1: + (void) heap_set_len(heap, 0); + return heap->ptrs[0]; + } + /* Shrink, replace the current max by previous last entry and heapify */ + heap_set_len(heap, heap->len - 1); + /* len changed. previous last entry is at heap->len */ + return lttng_heap_replace_max(heap, heap->ptrs[heap->len]); +} + +void *lttng_heap_cherrypick(struct lttng_ptr_heap *heap, void *p) +{ + size_t pos, len = heap->len; + + for (pos = 0; pos < len; pos++) + if (heap->ptrs[pos] == p) + goto found; + return NULL; +found: + if (heap->len == 1) { + (void) heap_set_len(heap, 0); + lttng_check_heap(heap); + return heap->ptrs[0]; + } + /* Replace p with previous last entry and heapify. */ + heap_set_len(heap, heap->len - 1); + /* len changed. previous last entry is at heap->len */ + heap->ptrs[pos] = heap->ptrs[heap->len]; + heapify(heap, pos); + return p; +} diff --git a/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h new file mode 100644 index 0000000..ea8dbb8 --- /dev/null +++ b/drivers/staging/lttng/lib/prio_heap/lttng_prio_heap.h @@ -0,0 +1,117 @@ +#ifndef _LTTNG_PRIO_HEAP_H +#define _LTTNG_PRIO_HEAP_H + +/* + * lttng_prio_heap.h + * + * Priority heap containing pointers. Based on CLRS, chapter 6. + * + * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + +#include <linux/gfp.h> + +struct lttng_ptr_heap { + size_t len, alloc_len; + void **ptrs; + int (*gt)(void *a, void *b); + gfp_t gfpmask; +}; + +#ifdef DEBUG_HEAP +void lttng_check_heap(const struct lttng_ptr_heap *heap); +#else +static inline +void lttng_check_heap(const struct lttng_ptr_heap *heap) +{ +} +#endif + +/** + * lttng_heap_maximum - return the largest element in the heap + * @heap: the heap to be operated on + * + * Returns the largest element in the heap, without performing any modification + * to the heap structure. Returns NULL if the heap is empty. + */ +static inline void *lttng_heap_maximum(const struct lttng_ptr_heap *heap) +{ + lttng_check_heap(heap); + return heap->len ? heap->ptrs[0] : NULL; +} + +/** + * lttng_heap_init - initialize the heap + * @heap: the heap to initialize + * @alloc_len: number of elements initially allocated + * @gfp: allocation flags + * @gt: function to compare the elements + * + * Returns -ENOMEM if out of memory. + */ +extern int lttng_heap_init(struct lttng_ptr_heap *heap, + size_t alloc_len, gfp_t gfpmask, + int gt(void *a, void *b)); + +/** + * lttng_heap_free - free the heap + * @heap: the heap to free + */ +extern void lttng_heap_free(struct lttng_ptr_heap *heap); + +/** + * lttng_heap_insert - insert an element into the heap + * @heap: the heap to be operated on + * @p: the element to add + * + * Insert an element into the heap. + * + * Returns -ENOMEM if out of memory. + */ +extern int lttng_heap_insert(struct lttng_ptr_heap *heap, void *p); + +/** + * lttng_heap_remove - remove the largest element from the heap + * @heap: the heap to be operated on + * + * Returns the largest element in the heap. It removes this element from the + * heap. Returns NULL if the heap is empty. + */ +extern void *lttng_heap_remove(struct lttng_ptr_heap *heap); + +/** + * lttng_heap_cherrypick - remove a given element from the heap + * @heap: the heap to be operated on + * @p: the element + * + * Remove the given element from the heap. Return the element if present, else + * return NULL. This algorithm has a complexity of O(n), which is higher than + * O(log(n)) provided by the rest of this API. + */ +extern void *lttng_heap_cherrypick(struct lttng_ptr_heap *heap, void *p); + +/** + * lttng_heap_replace_max - replace the the largest element from the heap + * @heap: the heap to be operated on + * @p: the pointer to be inserted as topmost element replacement + * + * Returns the largest element in the heap. It removes this element from the + * heap. The heap is rebalanced only once after the insertion. Returns NULL if + * the heap is empty. + * + * This is the equivalent of calling heap_remove() and then heap_insert(), but + * it only rebalances the heap once. It never allocates memory. + */ +extern void *lttng_heap_replace_max(struct lttng_ptr_heap *heap, void *p); + +#endif /* _LTTNG_PRIO_HEAP_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 02/20] lttng lib: ring buffer 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 01/20] lttng lib: lttng priority heap Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 03/20] lttng lib: portable bitfield read/write header Mathieu Desnoyers ` (18 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lib/ringbuffer/api.h | 25 + drivers/staging/lttng/lib/ringbuffer/backend.h | 250 +++ .../lttng/lib/ringbuffer/backend_internal.h | 449 +++++ .../staging/lttng/lib/ringbuffer/backend_types.h | 80 + drivers/staging/lttng/lib/ringbuffer/config.h | 298 ++++ drivers/staging/lttng/lib/ringbuffer/frontend.h | 228 +++ .../staging/lttng/lib/ringbuffer/frontend_api.h | 358 ++++ .../lttng/lib/ringbuffer/frontend_internal.h | 424 +++++ .../staging/lttng/lib/ringbuffer/frontend_types.h | 176 ++ drivers/staging/lttng/lib/ringbuffer/iterator.h | 70 + drivers/staging/lttng/lib/ringbuffer/nohz.h | 30 + .../lttng/lib/ringbuffer/ring_buffer_backend.c | 854 ++++++++++ .../lttng/lib/ringbuffer/ring_buffer_frontend.c | 1721 ++++++++++++++++++++ .../lttng/lib/ringbuffer/ring_buffer_iterator.c | 798 +++++++++ .../lttng/lib/ringbuffer/ring_buffer_mmap.c | 115 ++ .../lttng/lib/ringbuffer/ring_buffer_splice.c | 202 +++ .../staging/lttng/lib/ringbuffer/ring_buffer_vfs.c | 387 +++++ drivers/staging/lttng/lib/ringbuffer/vatomic.h | 85 + drivers/staging/lttng/lib/ringbuffer/vfs.h | 89 + 19 files changed, 6639 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/ringbuffer/api.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend_internal.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/backend_types.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/config.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_api.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_internal.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/frontend_types.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/iterator.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/nohz.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c create mode 100644 drivers/staging/lttng/lib/ringbuffer/vatomic.h create mode 100644 drivers/staging/lttng/lib/ringbuffer/vfs.h diff --git a/drivers/staging/lttng/lib/ringbuffer/api.h b/drivers/staging/lttng/lib/ringbuffer/api.h new file mode 100644 index 0000000..f8a1145 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/api.h @@ -0,0 +1,25 @@ +#ifndef _LINUX_RING_BUFFER_API_H +#define _LINUX_RING_BUFFER_API_H + +/* + * linux/ringbuffer/api.h + * + * Copyright (C) 2010 - Mathieu Desnoyers "mathieu.desnoyers at efficios.com" + * + * Ring Buffer API. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" +#include "../../wrapper/ringbuffer/vfs.h" + +/* + * ring_buffer_frontend_api.h contains static inline functions that depend on + * client static inlines. Hence the inclusion of this "api" header only + * within the client. + */ +#include "../../wrapper/ringbuffer/frontend_api.h" + +#endif /* _LINUX_RING_BUFFER_API_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/backend.h b/drivers/staging/lttng/lib/ringbuffer/backend.h new file mode 100644 index 0000000..541dc53 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/backend.h @@ -0,0 +1,250 @@ +#ifndef _LINUX_RING_BUFFER_BACKEND_H +#define _LINUX_RING_BUFFER_BACKEND_H + +/* + * linux/ringbuffer/backend.h + * + * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer backend (API). + * + * Dual LGPL v2.1/GPL v2 license. + * + * Credits to Steven Rostedt for proposing to use an extra-subbuffer owned by + * the reader in flight recorder mode. + */ + +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/wait.h> +#include <linux/poll.h> +#include <linux/list.h> +#include <linux/fs.h> +#include <linux/mm.h> + +/* Internal helpers */ +#include "../../wrapper/ringbuffer/backend_internal.h" +#include "../../wrapper/ringbuffer/frontend_internal.h" + +/* Ring buffer backend API */ + +/* Ring buffer backend access (read/write) */ + +extern size_t lib_ring_buffer_read(struct lib_ring_buffer_backend *bufb, + size_t offset, void *dest, size_t len); + +extern int __lib_ring_buffer_copy_to_user(struct lib_ring_buffer_backend *bufb, + size_t offset, void __user *dest, + size_t len); + +extern int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb, + size_t offset, void *dest, size_t len); + +extern struct page ** +lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb, size_t offset, + void ***virt); + +/* + * Return the address where a given offset is located. + * Should be used to get the current subbuffer header pointer. Given we know + * it's never on a page boundary, it's safe to write directly to this address, + * as long as the write is never bigger than a page size. + */ +extern void * +lib_ring_buffer_offset_address(struct lib_ring_buffer_backend *bufb, + size_t offset); +extern void * +lib_ring_buffer_read_offset_address(struct lib_ring_buffer_backend *bufb, + size_t offset); + +/** + * lib_ring_buffer_write - write data to a buffer backend + * @config : ring buffer instance configuration + * @ctx: ring buffer context. (input arguments only) + * @src : source pointer to copy from + * @len : length of data to copy + * + * This function copies "len" bytes of data from a source pointer to a buffer + * backend, at the current context offset. This is more or less a buffer + * backend-specific memcpy() operation. Calls the slow path (_ring_buffer_write) + * if copy is crossing a page boundary. + */ +static inline +void lib_ring_buffer_write(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + const void *src, size_t len) +{ + struct lib_ring_buffer_backend *bufb = &ctx->buf->backend; + struct channel_backend *chanb = &ctx->chan->backend; + size_t sbidx, index; + size_t offset = ctx->buf_offset; + ssize_t pagecpy; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(ctx->chan, + config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + if (likely(pagecpy == len)) + lib_ring_buffer_do_copy(config, + rpages->p[index].virt + + (offset & ~PAGE_MASK), + src, len); + else + _lib_ring_buffer_write(bufb, offset, src, len, 0); + ctx->buf_offset += len; +} + +/** + * lib_ring_buffer_memset - write len bytes of c to a buffer backend + * @config : ring buffer instance configuration + * @bufb : ring buffer backend + * @offset : offset within the buffer + * @c : the byte to copy + * @len : number of bytes to copy + * + * This function writes "len" bytes of "c" to a buffer backend, at a specific + * offset. This is more or less a buffer backend-specific memset() operation. + * Calls the slow path (_ring_buffer_memset) if write is crossing a page + * boundary. + */ +static inline +void lib_ring_buffer_memset(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, int c, size_t len) +{ + + struct lib_ring_buffer_backend *bufb = &ctx->buf->backend; + struct channel_backend *chanb = &ctx->chan->backend; + size_t sbidx, index; + size_t offset = ctx->buf_offset; + ssize_t pagecpy; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(ctx->chan, + config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + if (likely(pagecpy == len)) + lib_ring_buffer_do_memset(rpages->p[index].virt + + (offset & ~PAGE_MASK), + c, len); + else + _lib_ring_buffer_memset(bufb, offset, c, len, 0); + ctx->buf_offset += len; +} + +/** + * lib_ring_buffer_copy_from_user - write userspace data to a buffer backend + * @config : ring buffer instance configuration + * @ctx: ring buffer context. (input arguments only) + * @src : userspace source pointer to copy from + * @len : length of data to copy + * + * This function copies "len" bytes of data from a userspace pointer to a + * buffer backend, at the current context offset. This is more or less a buffer + * backend-specific memcpy() operation. Calls the slow path + * (_ring_buffer_write_from_user) if copy is crossing a page boundary. + */ +static inline +void lib_ring_buffer_copy_from_user(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + const void __user *src, size_t len) +{ + struct lib_ring_buffer_backend *bufb = &ctx->buf->backend; + struct channel_backend *chanb = &ctx->chan->backend; + size_t sbidx, index; + size_t offset = ctx->buf_offset; + ssize_t pagecpy; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + unsigned long ret; + + offset &= chanb->buf_size - 1; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + pagecpy = min_t(size_t, len, (-offset) & ~PAGE_MASK); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(ctx->chan, + config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + + if (unlikely(!access_ok(VERIFY_READ, src, len))) + goto fill_buffer; + + if (likely(pagecpy == len)) { + ret = lib_ring_buffer_do_copy_from_user( + rpages->p[index].virt + (offset & ~PAGE_MASK), + src, len); + if (unlikely(ret > 0)) { + len -= (pagecpy - ret); + offset += (pagecpy - ret); + goto fill_buffer; + } + } else { + _lib_ring_buffer_copy_from_user(bufb, offset, src, len, 0); + } + ctx->buf_offset += len; + + return; + +fill_buffer: + /* + * In the error path we call the slow path version to avoid + * the pollution of static inline code. + */ + _lib_ring_buffer_memset(bufb, offset, 0, len, 0); +} + +/* + * This accessor counts the number of unread records in a buffer. + * It only provides a consistent value if no reads not writes are performed + * concurrently. + */ +static inline +unsigned long lib_ring_buffer_get_records_unread( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + struct lib_ring_buffer_backend *bufb = &buf->backend; + struct lib_ring_buffer_backend_pages *pages; + unsigned long records_unread = 0, sb_bindex, id; + unsigned int i; + + for (i = 0; i < bufb->chan->backend.num_subbuf; i++) { + id = bufb->buf_wsb[i].id; + sb_bindex = subbuffer_id_get_index(config, id); + pages = bufb->array[sb_bindex]; + records_unread += v_read(config, &pages->records_unread); + } + if (config->mode == RING_BUFFER_OVERWRITE) { + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + pages = bufb->array[sb_bindex]; + records_unread += v_read(config, &pages->records_unread); + } + return records_unread; +} + +ssize_t lib_ring_buffer_file_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags); +loff_t lib_ring_buffer_no_llseek(struct file *file, loff_t offset, int origin); + +#endif /* _LINUX_RING_BUFFER_BACKEND_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/backend_internal.h b/drivers/staging/lttng/lib/ringbuffer/backend_internal.h new file mode 100644 index 0000000..442f357 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/backend_internal.h @@ -0,0 +1,449 @@ +#ifndef _LINUX_RING_BUFFER_BACKEND_INTERNAL_H +#define _LINUX_RING_BUFFER_BACKEND_INTERNAL_H + +/* + * linux/ringbuffer/backend_internal.h + * + * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer backend (internal helpers). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/config.h" +#include "../../wrapper/ringbuffer/backend_types.h" +#include "../../wrapper/ringbuffer/frontend_types.h" +#include <linux/string.h> +#include <linux/uaccess.h> + +/* Ring buffer backend API presented to the frontend */ + +/* Ring buffer and channel backend create/free */ + +int lib_ring_buffer_backend_create(struct lib_ring_buffer_backend *bufb, + struct channel_backend *chan, int cpu); +void channel_backend_unregister_notifiers(struct channel_backend *chanb); +void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb); +int channel_backend_init(struct channel_backend *chanb, + const char *name, + const struct lib_ring_buffer_config *config, + void *priv, size_t subbuf_size, + size_t num_subbuf); +void channel_backend_free(struct channel_backend *chanb); + +void lib_ring_buffer_backend_reset(struct lib_ring_buffer_backend *bufb); +void channel_backend_reset(struct channel_backend *chanb); + +int lib_ring_buffer_backend_init(void); +void lib_ring_buffer_backend_exit(void); + +extern void _lib_ring_buffer_write(struct lib_ring_buffer_backend *bufb, + size_t offset, const void *src, size_t len, + ssize_t pagecpy); +extern void _lib_ring_buffer_memset(struct lib_ring_buffer_backend *bufb, + size_t offset, int c, size_t len, + ssize_t pagecpy); +extern void _lib_ring_buffer_copy_from_user(struct lib_ring_buffer_backend *bufb, + size_t offset, const void *src, + size_t len, ssize_t pagecpy); + +/* + * Subbuffer ID bits for overwrite mode. Need to fit within a single word to be + * exchanged atomically. + * + * Top half word, except lowest bit, belongs to "offset", which is used to keep + * to count the produced buffers. For overwrite mode, this provides the + * consumer with the capacity to read subbuffers in order, handling the + * situation where producers would write up to 2^15 buffers (or 2^31 for 64-bit + * systems) concurrently with a single execution of get_subbuf (between offset + * sampling and subbuffer ID exchange). + */ + +#define HALF_ULONG_BITS (BITS_PER_LONG >> 1) + +#define SB_ID_OFFSET_SHIFT (HALF_ULONG_BITS + 1) +#define SB_ID_OFFSET_COUNT (1UL << SB_ID_OFFSET_SHIFT) +#define SB_ID_OFFSET_MASK (~(SB_ID_OFFSET_COUNT - 1)) +/* + * Lowest bit of top word half belongs to noref. Used only for overwrite mode. + */ +#define SB_ID_NOREF_SHIFT (SB_ID_OFFSET_SHIFT - 1) +#define SB_ID_NOREF_COUNT (1UL << SB_ID_NOREF_SHIFT) +#define SB_ID_NOREF_MASK SB_ID_NOREF_COUNT +/* + * In overwrite mode: lowest half of word is used for index. + * Limit of 2^16 subbuffers per buffer on 32-bit, 2^32 on 64-bit. + * In producer-consumer mode: whole word used for index. + */ +#define SB_ID_INDEX_SHIFT 0 +#define SB_ID_INDEX_COUNT (1UL << SB_ID_INDEX_SHIFT) +#define SB_ID_INDEX_MASK (SB_ID_NOREF_COUNT - 1) + +/* + * Construct the subbuffer id from offset, index and noref. Use only the index + * for producer-consumer mode (offset and noref are only used in overwrite + * mode). + */ +static inline +unsigned long subbuffer_id(const struct lib_ring_buffer_config *config, + unsigned long offset, unsigned long noref, + unsigned long index) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + return (offset << SB_ID_OFFSET_SHIFT) + | (noref << SB_ID_NOREF_SHIFT) + | index; + else + return index; +} + +/* + * Compare offset with the offset contained within id. Return 1 if the offset + * bits are identical, else 0. + */ +static inline +int subbuffer_id_compare_offset(const struct lib_ring_buffer_config *config, + unsigned long id, unsigned long offset) +{ + return (id & SB_ID_OFFSET_MASK) == (offset << SB_ID_OFFSET_SHIFT); +} + +static inline +unsigned long subbuffer_id_get_index(const struct lib_ring_buffer_config *config, + unsigned long id) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + return id & SB_ID_INDEX_MASK; + else + return id; +} + +static inline +unsigned long subbuffer_id_is_noref(const struct lib_ring_buffer_config *config, + unsigned long id) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + return !!(id & SB_ID_NOREF_MASK); + else + return 1; +} + +/* + * Only used by reader on subbuffer ID it has exclusive access to. No volatile + * needed. + */ +static inline +void subbuffer_id_set_noref(const struct lib_ring_buffer_config *config, + unsigned long *id) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + *id |= SB_ID_NOREF_MASK; +} + +static inline +void subbuffer_id_set_noref_offset(const struct lib_ring_buffer_config *config, + unsigned long *id, unsigned long offset) +{ + unsigned long tmp; + + if (config->mode == RING_BUFFER_OVERWRITE) { + tmp = *id; + tmp &= ~SB_ID_OFFSET_MASK; + tmp |= offset << SB_ID_OFFSET_SHIFT; + tmp |= SB_ID_NOREF_MASK; + /* Volatile store, read concurrently by readers. */ + ACCESS_ONCE(*id) = tmp; + } +} + +/* No volatile access, since already used locally */ +static inline +void subbuffer_id_clear_noref(const struct lib_ring_buffer_config *config, + unsigned long *id) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + *id &= ~SB_ID_NOREF_MASK; +} + +/* + * For overwrite mode, cap the number of subbuffers per buffer to: + * 2^16 on 32-bit architectures + * 2^32 on 64-bit architectures + * This is required to fit in the index part of the ID. Return 0 on success, + * -EPERM on failure. + */ +static inline +int subbuffer_id_check_index(const struct lib_ring_buffer_config *config, + unsigned long num_subbuf) +{ + if (config->mode == RING_BUFFER_OVERWRITE) + return (num_subbuf > (1UL << HALF_ULONG_BITS)) ? -EPERM : 0; + else + return 0; +} + +static inline +void subbuffer_count_record(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id); + v_inc(config, &bufb->array[sb_bindex]->records_commit); +} + +/* + * Reader has exclusive subbuffer access for record consumption. No need to + * perform the decrement atomically. + */ +static inline +void subbuffer_consume_record(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb) +{ + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id); + CHAN_WARN_ON(bufb->chan, + !v_read(config, &bufb->array[sb_bindex]->records_unread)); + /* Non-atomic decrement protected by exclusive subbuffer access */ + _v_dec(config, &bufb->array[sb_bindex]->records_unread); + v_inc(config, &bufb->records_read); +} + +static inline +unsigned long subbuffer_get_records_count( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id); + return v_read(config, &bufb->array[sb_bindex]->records_commit); +} + +/* + * Must be executed at subbuffer delivery when the writer has _exclusive_ + * subbuffer access. See ring_buffer_check_deliver() for details. + * ring_buffer_get_records_count() must be called to get the records count + * before this function, because it resets the records_commit count. + */ +static inline +unsigned long subbuffer_count_records_overrun( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + struct lib_ring_buffer_backend_pages *pages; + unsigned long overruns, sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id); + pages = bufb->array[sb_bindex]; + overruns = v_read(config, &pages->records_unread); + v_set(config, &pages->records_unread, + v_read(config, &pages->records_commit)); + v_set(config, &pages->records_commit, 0); + + return overruns; +} + +static inline +void subbuffer_set_data_size(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx, + unsigned long data_size) +{ + struct lib_ring_buffer_backend_pages *pages; + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id); + pages = bufb->array[sb_bindex]; + pages->data_size = data_size; +} + +static inline +unsigned long subbuffer_get_read_data_size( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb) +{ + struct lib_ring_buffer_backend_pages *pages; + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id); + pages = bufb->array[sb_bindex]; + return pages->data_size; +} + +static inline +unsigned long subbuffer_get_data_size( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + struct lib_ring_buffer_backend_pages *pages; + unsigned long sb_bindex; + + sb_bindex = subbuffer_id_get_index(config, bufb->buf_wsb[idx].id); + pages = bufb->array[sb_bindex]; + return pages->data_size; +} + +/** + * lib_ring_buffer_clear_noref - Clear the noref subbuffer flag, called by + * writer. + */ +static inline +void lib_ring_buffer_clear_noref(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx) +{ + unsigned long id, new_id; + + if (config->mode != RING_BUFFER_OVERWRITE) + return; + + /* + * Performing a volatile access to read the sb_pages, because we want to + * read a coherent version of the pointer and the associated noref flag. + */ + id = ACCESS_ONCE(bufb->buf_wsb[idx].id); + for (;;) { + /* This check is called on the fast path for each record. */ + if (likely(!subbuffer_id_is_noref(config, id))) { + /* + * Store after load dependency ordering the writes to + * the subbuffer after load and test of the noref flag + * matches the memory barrier implied by the cmpxchg() + * in update_read_sb_index(). + */ + return; /* Already writing to this buffer */ + } + new_id = id; + subbuffer_id_clear_noref(config, &new_id); + new_id = cmpxchg(&bufb->buf_wsb[idx].id, id, new_id); + if (likely(new_id == id)) + break; + id = new_id; + } +} + +/** + * lib_ring_buffer_set_noref_offset - Set the noref subbuffer flag and offset, + * called by writer. + */ +static inline +void lib_ring_buffer_set_noref_offset(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + unsigned long idx, unsigned long offset) +{ + if (config->mode != RING_BUFFER_OVERWRITE) + return; + + /* + * Because ring_buffer_set_noref() is only called by a single thread + * (the one which updated the cc_sb value), there are no concurrent + * updates to take care of: other writers have not updated cc_sb, so + * they cannot set the noref flag, and concurrent readers cannot modify + * the pointer because the noref flag is not set yet. + * The smp_wmb() in ring_buffer_commit() takes care of ordering writes + * to the subbuffer before this set noref operation. + * subbuffer_set_noref() uses a volatile store to deal with concurrent + * readers of the noref flag. + */ + CHAN_WARN_ON(bufb->chan, + subbuffer_id_is_noref(config, bufb->buf_wsb[idx].id)); + /* + * Memory barrier that ensures counter stores are ordered before set + * noref and offset. + */ + smp_mb(); + subbuffer_id_set_noref_offset(config, &bufb->buf_wsb[idx].id, offset); +} + +/** + * update_read_sb_index - Read-side subbuffer index update. + */ +static inline +int update_read_sb_index(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + struct channel_backend *chanb, + unsigned long consumed_idx, + unsigned long consumed_count) +{ + unsigned long old_id, new_id; + + if (config->mode == RING_BUFFER_OVERWRITE) { + /* + * Exchange the target writer subbuffer with our own unused + * subbuffer. No need to use ACCESS_ONCE() here to read the + * old_wpage, because the value read will be confirmed by the + * following cmpxchg(). + */ + old_id = bufb->buf_wsb[consumed_idx].id; + if (unlikely(!subbuffer_id_is_noref(config, old_id))) + return -EAGAIN; + /* + * Make sure the offset count we are expecting matches the one + * indicated by the writer. + */ + if (unlikely(!subbuffer_id_compare_offset(config, old_id, + consumed_count))) + return -EAGAIN; + CHAN_WARN_ON(bufb->chan, + !subbuffer_id_is_noref(config, bufb->buf_rsb.id)); + subbuffer_id_set_noref_offset(config, &bufb->buf_rsb.id, + consumed_count); + new_id = cmpxchg(&bufb->buf_wsb[consumed_idx].id, old_id, + bufb->buf_rsb.id); + if (unlikely(old_id != new_id)) + return -EAGAIN; + bufb->buf_rsb.id = new_id; + } else { + /* No page exchange, use the writer page directly */ + bufb->buf_rsb.id = bufb->buf_wsb[consumed_idx].id; + } + return 0; +} + +/* + * Use the architecture-specific memcpy implementation for constant-sized + * inputs, but rely on an inline memcpy for length statically unknown. + * The function call to memcpy is just way too expensive for a fast path. + */ +#define lib_ring_buffer_do_copy(config, dest, src, len) \ +do { \ + size_t __len = (len); \ + if (__builtin_constant_p(len)) \ + memcpy(dest, src, __len); \ + else \ + inline_memcpy(dest, src, __len); \ +} while (0) + +/* + * We use __copy_from_user to copy userspace data since we already + * did the access_ok for the whole range. + */ +static inline +unsigned long lib_ring_buffer_do_copy_from_user(void *dest, + const void __user *src, + unsigned long len) +{ + return __copy_from_user(dest, src, len); +} + +/* + * write len bytes to dest with c + */ +static inline +void lib_ring_buffer_do_memset(char *dest, int c, + unsigned long len) +{ + unsigned long i; + + for (i = 0; i < len; i++) + dest[i] = c; +} + +#endif /* _LINUX_RING_BUFFER_BACKEND_INTERNAL_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/backend_types.h b/drivers/staging/lttng/lib/ringbuffer/backend_types.h new file mode 100644 index 0000000..1d301de --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/backend_types.h @@ -0,0 +1,80 @@ +#ifndef _LINUX_RING_BUFFER_BACKEND_TYPES_H +#define _LINUX_RING_BUFFER_BACKEND_TYPES_H + +/* + * linux/ringbuffer/backend_types.h + * + * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer backend (types). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/cpumask.h> +#include <linux/types.h> + +struct lib_ring_buffer_backend_page { + void *virt; /* page virtual address (cached) */ + struct page *page; /* pointer to page structure */ +}; + +struct lib_ring_buffer_backend_pages { + unsigned long mmap_offset; /* offset of the subbuffer in mmap */ + union v_atomic records_commit; /* current records committed count */ + union v_atomic records_unread; /* records to read */ + unsigned long data_size; /* Amount of data to read from subbuf */ + struct lib_ring_buffer_backend_page p[]; +}; + +struct lib_ring_buffer_backend_subbuffer { + /* Identifier for subbuf backend pages. Exchanged atomically. */ + unsigned long id; /* backend subbuffer identifier */ +}; + +/* + * Forward declaration of frontend-specific channel and ring_buffer. + */ +struct channel; +struct lib_ring_buffer; + +struct lib_ring_buffer_backend { + /* Array of ring_buffer_backend_subbuffer for writer */ + struct lib_ring_buffer_backend_subbuffer *buf_wsb; + /* ring_buffer_backend_subbuffer for reader */ + struct lib_ring_buffer_backend_subbuffer buf_rsb; + /* + * Pointer array of backend pages, for whole buffer. + * Indexed by ring_buffer_backend_subbuffer identifier (id) index. + */ + struct lib_ring_buffer_backend_pages **array; + unsigned int num_pages_per_subbuf; + + struct channel *chan; /* Associated channel */ + int cpu; /* This buffer's cpu. -1 if global. */ + union v_atomic records_read; /* Number of records read */ + unsigned int allocated:1; /* Bool: is buffer allocated ? */ +}; + +struct channel_backend { + unsigned long buf_size; /* Size of the buffer */ + unsigned long subbuf_size; /* Sub-buffer size */ + unsigned int subbuf_size_order; /* Order of sub-buffer size */ + unsigned int num_subbuf_order; /* + * Order of number of sub-buffers/buffer + * for writer. + */ + unsigned int buf_size_order; /* Order of buffer size */ + int extra_reader_sb:1; /* Bool: has extra reader subbuffer */ + struct lib_ring_buffer *buf; /* Channel per-cpu buffers */ + + unsigned long num_subbuf; /* Number of sub-buffers for writer */ + u64 start_tsc; /* Channel creation TSC value */ + void *priv; /* Client-specific information */ + struct notifier_block cpu_hp_notifier; /* CPU hotplug notifier */ + const struct lib_ring_buffer_config *config; /* Ring buffer configuration */ + cpumask_var_t cpumask; /* Allocated per-cpu buffers cpumask */ + char name[NAME_MAX]; /* Channel name */ +}; + +#endif /* _LINUX_RING_BUFFER_BACKEND_TYPES_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/config.h b/drivers/staging/lttng/lib/ringbuffer/config.h new file mode 100644 index 0000000..fd73d55 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/config.h @@ -0,0 +1,298 @@ +#ifndef _LINUX_RING_BUFFER_CONFIG_H +#define _LINUX_RING_BUFFER_CONFIG_H + +/* + * linux/ringbuffer/config.h + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer configuration header. Note: after declaring the standard inline + * functions, clients should also include linux/ringbuffer/api.h. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/types.h> +#include <linux/percpu.h> +#include "../align.h" + +struct lib_ring_buffer; +struct channel; +struct lib_ring_buffer_config; +struct lib_ring_buffer_ctx; + +/* + * Ring buffer client callbacks. Only used by slow path, never on fast path. + * For the fast path, record_header_size(), ring_buffer_clock_read() should be + * provided as inline functions too. These may simply return 0 if not used by + * the client. + */ +struct lib_ring_buffer_client_cb { + /* Mandatory callbacks */ + + /* A static inline version is also required for fast path */ + u64 (*ring_buffer_clock_read) (struct channel *chan); + size_t (*record_header_size) (const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx); + + /* Slow path only, at subbuffer switch */ + size_t (*subbuffer_header_size) (void); + void (*buffer_begin) (struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx); + void (*buffer_end) (struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx, unsigned long data_size); + + /* Optional callbacks (can be set to NULL) */ + + /* Called at buffer creation/finalize */ + int (*buffer_create) (struct lib_ring_buffer *buf, void *priv, + int cpu, const char *name); + /* + * Clients should guarantee that no new reader handle can be opened + * after finalize. + */ + void (*buffer_finalize) (struct lib_ring_buffer *buf, void *priv, int cpu); + + /* + * Extract header length, payload length and timestamp from event + * record. Used by buffer iterators. Timestamp is only used by channel + * iterator. + */ + void (*record_get) (const struct lib_ring_buffer_config *config, + struct channel *chan, struct lib_ring_buffer *buf, + size_t offset, size_t *header_len, + size_t *payload_len, u64 *timestamp); +}; + +/* + * Ring buffer instance configuration. + * + * Declare as "static const" within the client object to ensure the inline fast + * paths can be optimized. + * + * alloc/sync pairs: + * + * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_PER_CPU : + * Per-cpu buffers with per-cpu synchronization. Tracing must be performed + * with preemption disabled (lib_ring_buffer_get_cpu() and + * lib_ring_buffer_put_cpu()). + * + * RING_BUFFER_ALLOC_PER_CPU and RING_BUFFER_SYNC_GLOBAL : + * Per-cpu buffer with global synchronization. Tracing can be performed with + * preemption enabled, statistically stays on the local buffers. + * + * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_PER_CPU : + * Should only be used for buffers belonging to a single thread or protected + * by mutual exclusion by the client. Note that periodical sub-buffer switch + * should be disabled in this kind of configuration. + * + * RING_BUFFER_ALLOC_GLOBAL and RING_BUFFER_SYNC_GLOBAL : + * Global shared buffer with global synchronization. + * + * wakeup: + * + * RING_BUFFER_WAKEUP_BY_TIMER uses per-cpu deferrable timers to poll the + * buffers and wake up readers if data is ready. Mainly useful for tracers which + * don't want to call into the wakeup code on the tracing path. Use in + * combination with "read_timer_interval" channel_create() argument. + * + * RING_BUFFER_WAKEUP_BY_WRITER directly wakes up readers when a subbuffer is + * ready to read. Lower latencies before the reader is woken up. Mainly suitable + * for drivers. + * + * RING_BUFFER_WAKEUP_NONE does not perform any wakeup whatsoever. The client + * has the responsibility to perform wakeups. + */ +struct lib_ring_buffer_config { + enum { + RING_BUFFER_ALLOC_PER_CPU, + RING_BUFFER_ALLOC_GLOBAL, + } alloc; + enum { + RING_BUFFER_SYNC_PER_CPU, /* Wait-free */ + RING_BUFFER_SYNC_GLOBAL, /* Lock-free */ + } sync; + enum { + RING_BUFFER_OVERWRITE, /* Overwrite when buffer full */ + RING_BUFFER_DISCARD, /* Discard when buffer full */ + } mode; + enum { + RING_BUFFER_SPLICE, + RING_BUFFER_MMAP, + RING_BUFFER_READ, /* TODO */ + RING_BUFFER_ITERATOR, + RING_BUFFER_NONE, + } output; + enum { + RING_BUFFER_PAGE, + RING_BUFFER_VMAP, /* TODO */ + RING_BUFFER_STATIC, /* TODO */ + } backend; + enum { + RING_BUFFER_NO_OOPS_CONSISTENCY, + RING_BUFFER_OOPS_CONSISTENCY, + } oops; + enum { + RING_BUFFER_IPI_BARRIER, + RING_BUFFER_NO_IPI_BARRIER, + } ipi; + enum { + RING_BUFFER_WAKEUP_BY_TIMER, /* wake up performed by timer */ + RING_BUFFER_WAKEUP_BY_WRITER, /* + * writer wakes up reader, + * not lock-free + * (takes spinlock). + */ + } wakeup; + /* + * tsc_bits: timestamp bits saved at each record. + * 0 and 64 disable the timestamp compression scheme. + */ + unsigned int tsc_bits; + struct lib_ring_buffer_client_cb cb; +}; + +/* + * ring buffer context + * + * Context passed to lib_ring_buffer_reserve(), lib_ring_buffer_commit(), + * lib_ring_buffer_try_discard_reserve(), lib_ring_buffer_align_ctx() and + * lib_ring_buffer_write(). + */ +struct lib_ring_buffer_ctx { + /* input received by lib_ring_buffer_reserve(), saved here. */ + struct channel *chan; /* channel */ + void *priv; /* client private data */ + size_t data_size; /* size of payload */ + int largest_align; /* + * alignment of the largest element + * in the payload + */ + int cpu; /* processor id */ + + /* output from lib_ring_buffer_reserve() */ + struct lib_ring_buffer *buf; /* + * buffer corresponding to processor id + * for this channel + */ + size_t slot_size; /* size of the reserved slot */ + unsigned long buf_offset; /* offset following the record header */ + unsigned long pre_offset; /* + * Initial offset position _before_ + * the record is written. Positioned + * prior to record header alignment + * padding. + */ + u64 tsc; /* time-stamp counter value */ + unsigned int rflags; /* reservation flags */ +}; + +/** + * lib_ring_buffer_ctx_init - initialize ring buffer context + * @ctx: ring buffer context to initialize + * @chan: channel + * @priv: client private data + * @data_size: size of record data payload + * @largest_align: largest alignment within data payload types + * @cpu: processor id + */ +static inline +void lib_ring_buffer_ctx_init(struct lib_ring_buffer_ctx *ctx, + struct channel *chan, void *priv, + size_t data_size, int largest_align, + int cpu) +{ + ctx->chan = chan; + ctx->priv = priv; + ctx->data_size = data_size; + ctx->largest_align = largest_align; + ctx->cpu = cpu; + ctx->rflags = 0; +} + +/* + * Reservation flags. + * + * RING_BUFFER_RFLAG_FULL_TSC + * + * This flag is passed to record_header_size() and to the primitive used to + * write the record header. It indicates that the full 64-bit time value is + * needed in the record header. If this flag is not set, the record header needs + * only to contain "tsc_bits" bit of time value. + * + * Reservation flags can be added by the client, starting from + * "(RING_BUFFER_FLAGS_END << 0)". It can be used to pass information from + * record_header_size() to lib_ring_buffer_write_record_header(). + */ +#define RING_BUFFER_RFLAG_FULL_TSC (1U << 0) +#define RING_BUFFER_RFLAG_END (1U << 1) + +/* + * We need to define RING_BUFFER_ALIGN_ATTR so it is known early at + * compile-time. We have to duplicate the "config->align" information and the + * definition here because config->align is used both in the slow and fast + * paths, but RING_BUFFER_ALIGN_ATTR is only available for the client code. + */ +#ifdef RING_BUFFER_ALIGN + +# define RING_BUFFER_ALIGN_ATTR /* Default arch alignment */ + +/* + * Calculate the offset needed to align the type. + * size_of_type must be non-zero. + */ +static inline +unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type) +{ + return offset_align(align_drift, size_of_type); +} + +#else + +# define RING_BUFFER_ALIGN_ATTR __attribute__((packed)) + +/* + * Calculate the offset needed to align the type. + * size_of_type must be non-zero. + */ +static inline +unsigned int lib_ring_buffer_align(size_t align_drift, size_t size_of_type) +{ + return 0; +} + +#endif + +/** + * lib_ring_buffer_align_ctx - Align context offset on "alignment" + * @ctx: ring buffer context. + */ +static inline +void lib_ring_buffer_align_ctx(struct lib_ring_buffer_ctx *ctx, + size_t alignment) +{ + ctx->buf_offset += lib_ring_buffer_align(ctx->buf_offset, + alignment); +} + +/* + * lib_ring_buffer_check_config() returns 0 on success. + * Used internally to check for valid configurations at channel creation. + */ +static inline +int lib_ring_buffer_check_config(const struct lib_ring_buffer_config *config, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + if (config->alloc == RING_BUFFER_ALLOC_GLOBAL + && config->sync == RING_BUFFER_SYNC_PER_CPU + && switch_timer_interval) + return -EINVAL; + return 0; +} + +#include "../../wrapper/ringbuffer/vatomic.h" + +#endif /* _LINUX_RING_BUFFER_CONFIG_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend.h b/drivers/staging/lttng/lib/ringbuffer/frontend.h new file mode 100644 index 0000000..01af77a --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/frontend.h @@ -0,0 +1,228 @@ +#ifndef _LINUX_RING_BUFFER_FRONTEND_H +#define _LINUX_RING_BUFFER_FRONTEND_H + +/* + * linux/ringbuffer/frontend.h + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring Buffer Library Synchronization Header (API). + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * See ring_buffer_frontend.c for more information on wait-free algorithms. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/pipe_fs_i.h> +#include <linux/rcupdate.h> +#include <linux/cpumask.h> +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/splice.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/sched.h> +#include <linux/cache.h> +#include <linux/time.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/stat.h> +#include <linux/cpu.h> +#include <linux/fs.h> + +#include <asm/atomic.h> +#include <asm/local.h> + +/* Internal helpers */ +#include "../../wrapper/ringbuffer/frontend_internal.h" + +/* Buffer creation/removal and setup operations */ + +/* + * switch_timer_interval is the time interval (in us) to fill sub-buffers with + * padding to let readers get those sub-buffers. Used for live streaming. + * + * read_timer_interval is the time interval (in us) to wake up pending readers. + * + * buf_addr is a pointer the the beginning of the preallocated buffer contiguous + * address mapping. It is used only by RING_BUFFER_STATIC configuration. It can + * be set to NULL for other backends. + */ + +extern +struct channel *channel_create(const struct lib_ring_buffer_config *config, + const char *name, void *priv, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); + +/* + * channel_destroy returns the private data pointer. It finalizes all channel's + * buffers, waits for readers to release all references, and destroys the + * channel. + */ +extern +void *channel_destroy(struct channel *chan); + + +/* Buffer read operations */ + +/* + * Iteration on channel cpumask needs to issue a read barrier to match the write + * barrier in cpu hotplug. It orders the cpumask read before read of per-cpu + * buffer data. The per-cpu buffer is never removed by cpu hotplug; teardown is + * only performed at channel destruction. + */ +#define for_each_channel_cpu(cpu, chan) \ + for ((cpu) = -1; \ + ({ (cpu) = cpumask_next(cpu, (chan)->backend.cpumask); \ + smp_read_barrier_depends(); (cpu) < nr_cpu_ids; });) + +extern struct lib_ring_buffer *channel_get_ring_buffer( + const struct lib_ring_buffer_config *config, + struct channel *chan, int cpu); +extern int lib_ring_buffer_open_read(struct lib_ring_buffer *buf); +extern void lib_ring_buffer_release_read(struct lib_ring_buffer *buf); + +/* + * Read sequence: snapshot, many get_subbuf/put_subbuf, move_consumer. + */ +extern int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf, + unsigned long *consumed, + unsigned long *produced); +extern void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf, + unsigned long consumed_new); + +extern int lib_ring_buffer_get_subbuf(struct lib_ring_buffer *buf, + unsigned long consumed); +extern void lib_ring_buffer_put_subbuf(struct lib_ring_buffer *buf); + +/* + * lib_ring_buffer_get_next_subbuf/lib_ring_buffer_put_next_subbuf are helpers + * to read sub-buffers sequentially. + */ +static inline int lib_ring_buffer_get_next_subbuf(struct lib_ring_buffer *buf) +{ + int ret; + + ret = lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, + &buf->prod_snapshot); + if (ret) + return ret; + ret = lib_ring_buffer_get_subbuf(buf, buf->cons_snapshot); + return ret; +} + +static inline void lib_ring_buffer_put_next_subbuf(struct lib_ring_buffer *buf) +{ + lib_ring_buffer_put_subbuf(buf); + lib_ring_buffer_move_consumer(buf, subbuf_align(buf->cons_snapshot, + buf->backend.chan)); +} + +extern void channel_reset(struct channel *chan); +extern void lib_ring_buffer_reset(struct lib_ring_buffer *buf); + +static inline +unsigned long lib_ring_buffer_get_offset(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->offset); +} + +static inline +unsigned long lib_ring_buffer_get_consumed(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return atomic_long_read(&buf->consumed); +} + +/* + * Must call lib_ring_buffer_is_finalized before reading counters (memory + * ordering enforced with respect to trace teardown). + */ +static inline +int lib_ring_buffer_is_finalized(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + int finalized = ACCESS_ONCE(buf->finalized); + /* + * Read finalized before counters. + */ + smp_rmb(); + return finalized; +} + +static inline +int lib_ring_buffer_channel_is_finalized(const struct channel *chan) +{ + return chan->finalized; +} + +static inline +int lib_ring_buffer_channel_is_disabled(const struct channel *chan) +{ + return atomic_read(&chan->record_disabled); +} + +static inline +unsigned long lib_ring_buffer_get_read_data_size( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return subbuffer_get_read_data_size(config, &buf->backend); +} + +static inline +unsigned long lib_ring_buffer_get_records_count( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->records_count); +} + +static inline +unsigned long lib_ring_buffer_get_records_overrun( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->records_overrun); +} + +static inline +unsigned long lib_ring_buffer_get_records_lost_full( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->records_lost_full); +} + +static inline +unsigned long lib_ring_buffer_get_records_lost_wrap( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->records_lost_wrap); +} + +static inline +unsigned long lib_ring_buffer_get_records_lost_big( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->records_lost_big); +} + +static inline +unsigned long lib_ring_buffer_get_records_read( + const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + return v_read(config, &buf->backend.records_read); +} + +#endif /* _LINUX_RING_BUFFER_FRONTEND_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_api.h b/drivers/staging/lttng/lib/ringbuffer/frontend_api.h new file mode 100644 index 0000000..391e593 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/frontend_api.h @@ -0,0 +1,358 @@ +#ifndef _LINUX_RING_BUFFER_FRONTEND_API_H +#define _LINUX_RING_BUFFER_FRONTEND_API_H + +/* + * linux/ringbuffer/frontend_api.h + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring Buffer Library Synchronization Header (buffer write API). + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * See ring_buffer_frontend.c for more information on wait-free algorithms. + * See linux/ringbuffer/frontend.h for channel allocation and read-side API. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/frontend.h" +#include <linux/errno.h> + +/** + * lib_ring_buffer_get_cpu - Precedes ring buffer reserve/commit. + * + * Disables preemption (acts as a RCU read-side critical section) and keeps a + * ring buffer nesting count as supplementary safety net to ensure tracer client + * code will never trigger an endless recursion. Returns the processor ID on + * success, -EPERM on failure (nesting count too high). + * + * asm volatile and "memory" clobber prevent the compiler from moving + * instructions out of the ring buffer nesting count. This is required to ensure + * that probe side-effects which can cause recursion (e.g. unforeseen traps, + * divisions by 0, ...) are triggered within the incremented nesting count + * section. + */ +static inline +int lib_ring_buffer_get_cpu(const struct lib_ring_buffer_config *config) +{ + int cpu, nesting; + + rcu_read_lock_sched_notrace(); + cpu = smp_processor_id(); + nesting = ++per_cpu(lib_ring_buffer_nesting, cpu); + barrier(); + + if (unlikely(nesting > 4)) { + WARN_ON_ONCE(1); + per_cpu(lib_ring_buffer_nesting, cpu)--; + rcu_read_unlock_sched_notrace(); + return -EPERM; + } else + return cpu; +} + +/** + * lib_ring_buffer_put_cpu - Follows ring buffer reserve/commit. + */ +static inline +void lib_ring_buffer_put_cpu(const struct lib_ring_buffer_config *config) +{ + barrier(); + __get_cpu_var(lib_ring_buffer_nesting)--; + rcu_read_unlock_sched_notrace(); +} + +/* + * lib_ring_buffer_try_reserve is called by lib_ring_buffer_reserve(). It is not + * part of the API per se. + * + * returns 0 if reserve ok, or 1 if the slow path must be taken. + */ +static inline +int lib_ring_buffer_try_reserve(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + unsigned long *o_begin, unsigned long *o_end, + unsigned long *o_old, size_t *before_hdr_pad) +{ + struct channel *chan = ctx->chan; + struct lib_ring_buffer *buf = ctx->buf; + *o_begin = v_read(config, &buf->offset); + *o_old = *o_begin; + + ctx->tsc = lib_ring_buffer_clock_read(chan); + if ((int64_t) ctx->tsc == -EIO) + return 1; + + /* + * Prefetch cacheline for read because we have to read the previous + * commit counter to increment it and commit seq value to compare it to + * the commit counter. + */ + prefetch(&buf->commit_hot[subbuf_index(*o_begin, chan)]); + + if (last_tsc_overflow(config, buf, ctx->tsc)) + ctx->rflags |= RING_BUFFER_RFLAG_FULL_TSC; + + if (unlikely(subbuf_offset(*o_begin, chan) == 0)) + return 1; + + ctx->slot_size = record_header_size(config, chan, *o_begin, + before_hdr_pad, ctx); + ctx->slot_size += + lib_ring_buffer_align(*o_begin + ctx->slot_size, + ctx->largest_align) + ctx->data_size; + if (unlikely((subbuf_offset(*o_begin, chan) + ctx->slot_size) + > chan->backend.subbuf_size)) + return 1; + + /* + * Record fits in the current buffer and we are not on a switch + * boundary. It's safe to write. + */ + *o_end = *o_begin + ctx->slot_size; + + if (unlikely((subbuf_offset(*o_end, chan)) == 0)) + /* + * The offset_end will fall at the very beginning of the next + * subbuffer. + */ + return 1; + + return 0; +} + +/** + * lib_ring_buffer_reserve - Reserve space in a ring buffer. + * @config: ring buffer instance configuration. + * @ctx: ring buffer context. (input and output) Must be already initialized. + * + * Atomic wait-free slot reservation. The reserved space starts at the context + * "pre_offset". Its length is "slot_size". The associated time-stamp is "tsc". + * + * Return : + * 0 on success. + * -EAGAIN if channel is disabled. + * -ENOSPC if event size is too large for packet. + * -ENOBUFS if there is currently not enough space in buffer for the event. + * -EIO if data cannot be written into the buffer for any other reason. + */ + +static inline +int lib_ring_buffer_reserve(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx) +{ + struct channel *chan = ctx->chan; + struct lib_ring_buffer *buf; + unsigned long o_begin, o_end, o_old; + size_t before_hdr_pad = 0; + + if (atomic_read(&chan->record_disabled)) + return -EAGAIN; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + buf = per_cpu_ptr(chan->backend.buf, ctx->cpu); + else + buf = chan->backend.buf; + if (atomic_read(&buf->record_disabled)) + return -EAGAIN; + ctx->buf = buf; + + /* + * Perform retryable operations. + */ + if (unlikely(lib_ring_buffer_try_reserve(config, ctx, &o_begin, + &o_end, &o_old, &before_hdr_pad))) + goto slow_path; + + if (unlikely(v_cmpxchg(config, &ctx->buf->offset, o_old, o_end) + != o_old)) + goto slow_path; + + /* + * Atomically update last_tsc. This update races against concurrent + * atomic updates, but the race will always cause supplementary full TSC + * record headers, never the opposite (missing a full TSC record header + * when it would be needed). + */ + save_last_tsc(config, ctx->buf, ctx->tsc); + + /* + * Push the reader if necessary + */ + lib_ring_buffer_reserve_push_reader(ctx->buf, chan, o_end - 1); + + /* + * Clear noref flag for this subbuffer. + */ + lib_ring_buffer_clear_noref(config, &ctx->buf->backend, + subbuf_index(o_end - 1, chan)); + + ctx->pre_offset = o_begin; + ctx->buf_offset = o_begin + before_hdr_pad; + return 0; +slow_path: + return lib_ring_buffer_reserve_slow(ctx); +} + +/** + * lib_ring_buffer_switch - Perform a sub-buffer switch for a per-cpu buffer. + * @config: ring buffer instance configuration. + * @buf: buffer + * @mode: buffer switch mode (SWITCH_ACTIVE or SWITCH_FLUSH) + * + * This operation is completely reentrant : can be called while tracing is + * active with absolutely no lock held. + * + * Note, however, that as a v_cmpxchg is used for some atomic operations and + * requires to be executed locally for per-CPU buffers, this function must be + * called from the CPU which owns the buffer for a ACTIVE flush, with preemption + * disabled, for RING_BUFFER_SYNC_PER_CPU configuration. + */ +static inline +void lib_ring_buffer_switch(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, enum switch_mode mode) +{ + lib_ring_buffer_switch_slow(buf, mode); +} + +/* See ring_buffer_frontend_api.h for lib_ring_buffer_reserve(). */ + +/** + * lib_ring_buffer_commit - Commit an record. + * @config: ring buffer instance configuration. + * @ctx: ring buffer context. (input arguments only) + * + * Atomic unordered slot commit. Increments the commit count in the + * specified sub-buffer, and delivers it if necessary. + */ +static inline +void lib_ring_buffer_commit(const struct lib_ring_buffer_config *config, + const struct lib_ring_buffer_ctx *ctx) +{ + struct channel *chan = ctx->chan; + struct lib_ring_buffer *buf = ctx->buf; + unsigned long offset_end = ctx->buf_offset; + unsigned long endidx = subbuf_index(offset_end - 1, chan); + unsigned long commit_count; + + /* + * Must count record before incrementing the commit count. + */ + subbuffer_count_record(config, &buf->backend, endidx); + + /* + * Order all writes to buffer before the commit count update that will + * determine that the subbuffer is full. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + /* + * Must write slot data before incrementing commit count. This + * compiler barrier is upgraded into a smp_mb() by the IPI sent + * by get_subbuf(). + */ + barrier(); + } else + smp_wmb(); + + v_add(config, ctx->slot_size, &buf->commit_hot[endidx].cc); + + /* + * commit count read can race with concurrent OOO commit count updates. + * This is only needed for lib_ring_buffer_check_deliver (for + * non-polling delivery only) and for + * lib_ring_buffer_write_commit_counter. The race can only cause the + * counter to be read with the same value more than once, which could + * cause : + * - Multiple delivery for the same sub-buffer (which is handled + * gracefully by the reader code) if the value is for a full + * sub-buffer. It's important that we can never miss a sub-buffer + * delivery. Re-reading the value after the v_add ensures this. + * - Reading a commit_count with a higher value that what was actually + * added to it for the lib_ring_buffer_write_commit_counter call + * (again caused by a concurrent committer). It does not matter, + * because this function is interested in the fact that the commit + * count reaches back the reserve offset for a specific sub-buffer, + * which is completely independent of the order. + */ + commit_count = v_read(config, &buf->commit_hot[endidx].cc); + + lib_ring_buffer_check_deliver(config, buf, chan, offset_end - 1, + commit_count, endidx); + /* + * Update used size at each commit. It's needed only for extracting + * ring_buffer buffers from vmcore, after crash. + */ + lib_ring_buffer_write_commit_counter(config, buf, chan, endidx, + ctx->buf_offset, commit_count, + ctx->slot_size); +} + +/** + * lib_ring_buffer_try_discard_reserve - Try discarding a record. + * @config: ring buffer instance configuration. + * @ctx: ring buffer context. (input arguments only) + * + * Only succeeds if no other record has been written after the record to + * discard. If discard fails, the record must be committed to the buffer. + * + * Returns 0 upon success, -EPERM if the record cannot be discarded. + */ +static inline +int lib_ring_buffer_try_discard_reserve(const struct lib_ring_buffer_config *config, + const struct lib_ring_buffer_ctx *ctx) +{ + struct lib_ring_buffer *buf = ctx->buf; + unsigned long end_offset = ctx->pre_offset + ctx->slot_size; + + /* + * We need to ensure that if the cmpxchg succeeds and discards the + * record, the next record will record a full TSC, because it cannot + * rely on the last_tsc associated with the discarded record to detect + * overflows. The only way to ensure this is to set the last_tsc to 0 + * (assuming no 64-bit TSC overflow), which forces to write a 64-bit + * timestamp in the next record. + * + * Note: if discard fails, we must leave the TSC in the record header. + * It is needed to keep track of TSC overflows for the following + * records. + */ + save_last_tsc(config, buf, 0ULL); + + if (likely(v_cmpxchg(config, &buf->offset, end_offset, ctx->pre_offset) + != end_offset)) + return -EPERM; + else + return 0; +} + +static inline +void channel_record_disable(const struct lib_ring_buffer_config *config, + struct channel *chan) +{ + atomic_inc(&chan->record_disabled); +} + +static inline +void channel_record_enable(const struct lib_ring_buffer_config *config, + struct channel *chan) +{ + atomic_dec(&chan->record_disabled); +} + +static inline +void lib_ring_buffer_record_disable(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + atomic_inc(&buf->record_disabled); +} + +static inline +void lib_ring_buffer_record_enable(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf) +{ + atomic_dec(&buf->record_disabled); +} + +#endif /* _LINUX_RING_BUFFER_FRONTEND_API_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h b/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h new file mode 100644 index 0000000..3bd5721 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/frontend_internal.h @@ -0,0 +1,424 @@ +#ifndef _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H +#define _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H + +/* + * linux/ringbuffer/frontend_internal.h + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring Buffer Library Synchronization Header (internal helpers). + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * See ring_buffer_frontend.c for more information on wait-free algorithms. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/config.h" +#include "../../wrapper/ringbuffer/backend_types.h" +#include "../../wrapper/ringbuffer/frontend_types.h" +#include "../../lib/prio_heap/lttng_prio_heap.h" /* For per-CPU read-side iterator */ + +/* Buffer offset macros */ + +/* buf_trunc mask selects only the buffer number. */ +static inline +unsigned long buf_trunc(unsigned long offset, struct channel *chan) +{ + return offset & ~(chan->backend.buf_size - 1); + +} + +/* Select the buffer number value (counter). */ +static inline +unsigned long buf_trunc_val(unsigned long offset, struct channel *chan) +{ + return buf_trunc(offset, chan) >> chan->backend.buf_size_order; +} + +/* buf_offset mask selects only the offset within the current buffer. */ +static inline +unsigned long buf_offset(unsigned long offset, struct channel *chan) +{ + return offset & (chan->backend.buf_size - 1); +} + +/* subbuf_offset mask selects the offset within the current subbuffer. */ +static inline +unsigned long subbuf_offset(unsigned long offset, struct channel *chan) +{ + return offset & (chan->backend.subbuf_size - 1); +} + +/* subbuf_trunc mask selects the subbuffer number. */ +static inline +unsigned long subbuf_trunc(unsigned long offset, struct channel *chan) +{ + return offset & ~(chan->backend.subbuf_size - 1); +} + +/* subbuf_align aligns the offset to the next subbuffer. */ +static inline +unsigned long subbuf_align(unsigned long offset, struct channel *chan) +{ + return (offset + chan->backend.subbuf_size) + & ~(chan->backend.subbuf_size - 1); +} + +/* subbuf_index returns the index of the current subbuffer within the buffer. */ +static inline +unsigned long subbuf_index(unsigned long offset, struct channel *chan) +{ + return buf_offset(offset, chan) >> chan->backend.subbuf_size_order; +} + +/* + * Last TSC comparison functions. Check if the current TSC overflows tsc_bits + * bits from the last TSC read. When overflows are detected, the full 64-bit + * timestamp counter should be written in the record header. Reads and writes + * last_tsc atomically. + */ + +#if (BITS_PER_LONG == 32) +static inline +void save_last_tsc(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, u64 tsc) +{ + if (config->tsc_bits == 0 || config->tsc_bits == 64) + return; + + /* + * Ensure the compiler performs this update in a single instruction. + */ + v_set(config, &buf->last_tsc, (unsigned long)(tsc >> config->tsc_bits)); +} + +static inline +int last_tsc_overflow(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, u64 tsc) +{ + unsigned long tsc_shifted; + + if (config->tsc_bits == 0 || config->tsc_bits == 64) + return 0; + + tsc_shifted = (unsigned long)(tsc >> config->tsc_bits); + if (unlikely(tsc_shifted + - (unsigned long)v_read(config, &buf->last_tsc))) + return 1; + else + return 0; +} +#else +static inline +void save_last_tsc(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, u64 tsc) +{ + if (config->tsc_bits == 0 || config->tsc_bits == 64) + return; + + v_set(config, &buf->last_tsc, (unsigned long)tsc); +} + +static inline +int last_tsc_overflow(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, u64 tsc) +{ + if (config->tsc_bits == 0 || config->tsc_bits == 64) + return 0; + + if (unlikely((tsc - v_read(config, &buf->last_tsc)) + >> config->tsc_bits)) + return 1; + else + return 0; +} +#endif + +extern +int lib_ring_buffer_reserve_slow(struct lib_ring_buffer_ctx *ctx); + +extern +void lib_ring_buffer_switch_slow(struct lib_ring_buffer *buf, + enum switch_mode mode); + +/* Buffer write helpers */ + +static inline +void lib_ring_buffer_reserve_push_reader(struct lib_ring_buffer *buf, + struct channel *chan, + unsigned long offset) +{ + unsigned long consumed_old, consumed_new; + + do { + consumed_old = atomic_long_read(&buf->consumed); + /* + * If buffer is in overwrite mode, push the reader consumed + * count if the write position has reached it and we are not + * at the first iteration (don't push the reader farther than + * the writer). This operation can be done concurrently by many + * writers in the same buffer, the writer being at the farthest + * write position sub-buffer index in the buffer being the one + * which will win this loop. + */ + if (unlikely(subbuf_trunc(offset, chan) + - subbuf_trunc(consumed_old, chan) + >= chan->backend.buf_size)) + consumed_new = subbuf_align(consumed_old, chan); + else + return; + } while (unlikely(atomic_long_cmpxchg(&buf->consumed, consumed_old, + consumed_new) != consumed_old)); +} + +static inline +void lib_ring_buffer_vmcore_check_deliver(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + unsigned long commit_count, + unsigned long idx) +{ + if (config->oops == RING_BUFFER_OOPS_CONSISTENCY) + v_set(config, &buf->commit_hot[idx].seq, commit_count); +} + +static inline +int lib_ring_buffer_poll_deliver(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + struct channel *chan) +{ + unsigned long consumed_old, consumed_idx, commit_count, write_offset; + + consumed_old = atomic_long_read(&buf->consumed); + consumed_idx = subbuf_index(consumed_old, chan); + commit_count = v_read(config, &buf->commit_cold[consumed_idx].cc_sb); + /* + * No memory barrier here, since we are only interested + * in a statistically correct polling result. The next poll will + * get the data is we are racing. The mb() that ensures correct + * memory order is in get_subbuf. + */ + write_offset = v_read(config, &buf->offset); + + /* + * Check that the subbuffer we are trying to consume has been + * already fully committed. + */ + + if (((commit_count - chan->backend.subbuf_size) + & chan->commit_count_mask) + - (buf_trunc(consumed_old, chan) + >> chan->backend.num_subbuf_order) + != 0) + return 0; + + /* + * Check that we are not about to read the same subbuffer in + * which the writer head is. + */ + if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_old, chan) + == 0) + return 0; + + return 1; + +} + +static inline +int lib_ring_buffer_pending_data(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + struct channel *chan) +{ + return !!subbuf_offset(v_read(config, &buf->offset), chan); +} + +static inline +unsigned long lib_ring_buffer_get_data_size(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + unsigned long idx) +{ + return subbuffer_get_data_size(config, &buf->backend, idx); +} + +/* + * Check if all space reservation in a buffer have been committed. This helps + * knowing if an execution context is nested (for per-cpu buffers only). + * This is a very specific ftrace use-case, so we keep this as "internal" API. + */ +static inline +int lib_ring_buffer_reserve_committed(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + struct channel *chan) +{ + unsigned long offset, idx, commit_count; + + CHAN_WARN_ON(chan, config->alloc != RING_BUFFER_ALLOC_PER_CPU); + CHAN_WARN_ON(chan, config->sync != RING_BUFFER_SYNC_PER_CPU); + + /* + * Read offset and commit count in a loop so they are both read + * atomically wrt interrupts. By deal with interrupt concurrency by + * restarting both reads if the offset has been pushed. Note that given + * we only have to deal with interrupt concurrency here, an interrupt + * modifying the commit count will also modify "offset", so it is safe + * to only check for offset modifications. + */ + do { + offset = v_read(config, &buf->offset); + idx = subbuf_index(offset, chan); + commit_count = v_read(config, &buf->commit_hot[idx].cc); + } while (offset != v_read(config, &buf->offset)); + + return ((buf_trunc(offset, chan) >> chan->backend.num_subbuf_order) + - (commit_count & chan->commit_count_mask) == 0); +} + +static inline +void lib_ring_buffer_check_deliver(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + struct channel *chan, + unsigned long offset, + unsigned long commit_count, + unsigned long idx) +{ + unsigned long old_commit_count = commit_count + - chan->backend.subbuf_size; + u64 tsc; + + /* Check if all commits have been done */ + if (unlikely((buf_trunc(offset, chan) >> chan->backend.num_subbuf_order) + - (old_commit_count & chan->commit_count_mask) == 0)) { + /* + * If we succeeded at updating cc_sb below, we are the subbuffer + * writer delivering the subbuffer. Deals with concurrent + * updates of the "cc" value without adding a add_return atomic + * operation to the fast path. + * + * We are doing the delivery in two steps: + * - First, we cmpxchg() cc_sb to the new value + * old_commit_count + 1. This ensures that we are the only + * subbuffer user successfully filling the subbuffer, but we + * do _not_ set the cc_sb value to "commit_count" yet. + * Therefore, other writers that would wrap around the ring + * buffer and try to start writing to our subbuffer would + * have to drop records, because it would appear as + * non-filled. + * We therefore have exclusive access to the subbuffer control + * structures. This mutual exclusion with other writers is + * crucially important to perform record overruns count in + * flight recorder mode locklessly. + * - When we are ready to release the subbuffer (either for + * reading or for overrun by other writers), we simply set the + * cc_sb value to "commit_count" and perform delivery. + * + * The subbuffer size is least 2 bytes (minimum size: 1 page). + * This guarantees that old_commit_count + 1 != commit_count. + */ + if (likely(v_cmpxchg(config, &buf->commit_cold[idx].cc_sb, + old_commit_count, old_commit_count + 1) + == old_commit_count)) { + /* + * Start of exclusive subbuffer access. We are + * guaranteed to be the last writer in this subbuffer + * and any other writer trying to access this subbuffer + * in this state is required to drop records. + */ + tsc = config->cb.ring_buffer_clock_read(chan); + v_add(config, + subbuffer_get_records_count(config, + &buf->backend, idx), + &buf->records_count); + v_add(config, + subbuffer_count_records_overrun(config, + &buf->backend, + idx), + &buf->records_overrun); + config->cb.buffer_end(buf, tsc, idx, + lib_ring_buffer_get_data_size(config, + buf, + idx)); + + /* + * Set noref flag and offset for this subbuffer id. + * Contains a memory barrier that ensures counter stores + * are ordered before set noref and offset. + */ + lib_ring_buffer_set_noref_offset(config, &buf->backend, idx, + buf_trunc_val(offset, chan)); + + /* + * Order set_noref and record counter updates before the + * end of subbuffer exclusive access. Orders with + * respect to writers coming into the subbuffer after + * wrap around, and also order wrt concurrent readers. + */ + smp_mb(); + /* End of exclusive subbuffer access */ + v_set(config, &buf->commit_cold[idx].cc_sb, + commit_count); + lib_ring_buffer_vmcore_check_deliver(config, buf, + commit_count, idx); + + /* + * RING_BUFFER_WAKEUP_BY_WRITER wakeup is not lock-free. + */ + if (config->wakeup == RING_BUFFER_WAKEUP_BY_WRITER + && atomic_long_read(&buf->active_readers) + && lib_ring_buffer_poll_deliver(config, buf, chan)) { + wake_up_interruptible(&buf->read_wait); + wake_up_interruptible(&chan->read_wait); + } + + } + } +} + +/* + * lib_ring_buffer_write_commit_counter + * + * For flight recording. must be called after commit. + * This function increments the subbuffer's commit_seq counter each time the + * commit count reaches back the reserve offset (modulo subbuffer size). It is + * useful for crash dump. + */ +static inline +void lib_ring_buffer_write_commit_counter(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer *buf, + struct channel *chan, + unsigned long idx, + unsigned long buf_offset, + unsigned long commit_count, + size_t slot_size) +{ + unsigned long offset, commit_seq_old; + + if (config->oops != RING_BUFFER_OOPS_CONSISTENCY) + return; + + offset = buf_offset + slot_size; + + /* + * subbuf_offset includes commit_count_mask. We can simply + * compare the offsets within the subbuffer without caring about + * buffer full/empty mismatch because offset is never zero here + * (subbuffer header and record headers have non-zero length). + */ + if (unlikely(subbuf_offset(offset - commit_count, chan))) + return; + + commit_seq_old = v_read(config, &buf->commit_hot[idx].seq); + while ((long) (commit_seq_old - commit_count) < 0) + commit_seq_old = v_cmpxchg(config, &buf->commit_hot[idx].seq, + commit_seq_old, commit_count); +} + +extern int lib_ring_buffer_create(struct lib_ring_buffer *buf, + struct channel_backend *chanb, int cpu); +extern void lib_ring_buffer_free(struct lib_ring_buffer *buf); + +/* Keep track of trap nesting inside ring buffer code */ +DECLARE_PER_CPU(unsigned int, lib_ring_buffer_nesting); + +#endif /* _LINUX_RING_BUFFER_FRONTEND_INTERNAL_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/frontend_types.h b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h new file mode 100644 index 0000000..5c7437f --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/frontend_types.h @@ -0,0 +1,176 @@ +#ifndef _LINUX_RING_BUFFER_FRONTEND_TYPES_H +#define _LINUX_RING_BUFFER_FRONTEND_TYPES_H + +/* + * linux/ringbuffer/frontend_types.h + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring Buffer Library Synchronization Header (types). + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * See ring_buffer_frontend.c for more information on wait-free algorithms. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/kref.h> +#include "../../wrapper/ringbuffer/config.h" +#include "../../wrapper/ringbuffer/backend_types.h" +#include "../../wrapper/spinlock.h" +#include "../../lib/prio_heap/lttng_prio_heap.h" /* For per-CPU read-side iterator */ + +/* + * A switch is done during tracing or as a final flush after tracing (so it + * won't write in the new sub-buffer). + */ +enum switch_mode { SWITCH_ACTIVE, SWITCH_FLUSH }; + +/* channel-level read-side iterator */ +struct channel_iter { + /* Prio heap of buffers. Lowest timestamps at the top. */ + struct lttng_ptr_heap heap; /* Heap of struct lib_ring_buffer ptrs */ + struct list_head empty_head; /* Empty buffers linked-list head */ + int read_open; /* Opened for reading ? */ + u64 last_qs; /* Last quiescent state timestamp */ + u64 last_timestamp; /* Last timestamp (for WARN_ON) */ + int last_cpu; /* Last timestamp cpu */ + /* + * read() file operation state. + */ + unsigned long len_left; +}; + +/* channel: collection of per-cpu ring buffers. */ +struct channel { + atomic_t record_disabled; + unsigned long commit_count_mask; /* + * Commit count mask, removing + * the MSBs corresponding to + * bits used to represent the + * subbuffer index. + */ + + struct channel_backend backend; /* Associated backend */ + + unsigned long switch_timer_interval; /* Buffer flush (jiffies) */ + unsigned long read_timer_interval; /* Reader wakeup (jiffies) */ + struct notifier_block cpu_hp_notifier; /* CPU hotplug notifier */ + struct notifier_block tick_nohz_notifier; /* CPU nohz notifier */ + struct notifier_block hp_iter_notifier; /* hotplug iterator notifier */ + int cpu_hp_enable:1; /* Enable CPU hotplug notif. */ + int hp_iter_enable:1; /* Enable hp iter notif. */ + wait_queue_head_t read_wait; /* reader wait queue */ + wait_queue_head_t hp_wait; /* CPU hotplug wait queue */ + int finalized; /* Has channel been finalized */ + struct channel_iter iter; /* Channel read-side iterator */ + struct kref ref; /* Reference count */ +}; + +/* Per-subbuffer commit counters used on the hot path */ +struct commit_counters_hot { + union v_atomic cc; /* Commit counter */ + union v_atomic seq; /* Consecutive commits */ +}; + +/* Per-subbuffer commit counters used only on cold paths */ +struct commit_counters_cold { + union v_atomic cc_sb; /* Incremented _once_ at sb switch */ +}; + +/* Per-buffer read iterator */ +struct lib_ring_buffer_iter { + u64 timestamp; /* Current record timestamp */ + size_t header_len; /* Current record header length */ + size_t payload_len; /* Current record payload length */ + + struct list_head empty_node; /* Linked list of empty buffers */ + unsigned long consumed, read_offset, data_size; + enum { + ITER_GET_SUBBUF = 0, + ITER_TEST_RECORD, + ITER_NEXT_RECORD, + ITER_PUT_SUBBUF, + } state; + int allocated:1; + int read_open:1; /* Opened for reading ? */ +}; + +/* ring buffer state */ +struct lib_ring_buffer { + /* First 32 bytes cache-hot cacheline */ + union v_atomic offset; /* Current offset in the buffer */ + struct commit_counters_hot *commit_hot; + /* Commit count per sub-buffer */ + atomic_long_t consumed; /* + * Current offset in the buffer + * standard atomic access (shared) + */ + atomic_t record_disabled; + /* End of first 32 bytes cacheline */ + union v_atomic last_tsc; /* + * Last timestamp written in the buffer. + */ + + struct lib_ring_buffer_backend backend; /* Associated backend */ + + struct commit_counters_cold *commit_cold; + /* Commit count per sub-buffer */ + atomic_long_t active_readers; /* + * Active readers count + * standard atomic access (shared) + */ + /* Dropped records */ + union v_atomic records_lost_full; /* Buffer full */ + union v_atomic records_lost_wrap; /* Nested wrap-around */ + union v_atomic records_lost_big; /* Events too big */ + union v_atomic records_count; /* Number of records written */ + union v_atomic records_overrun; /* Number of overwritten records */ + wait_queue_head_t read_wait; /* reader buffer-level wait queue */ + wait_queue_head_t write_wait; /* writer buffer-level wait queue (for metadata only) */ + int finalized; /* buffer has been finalized */ + struct timer_list switch_timer; /* timer for periodical switch */ + struct timer_list read_timer; /* timer for read poll */ + raw_spinlock_t raw_tick_nohz_spinlock; /* nohz entry lock/trylock */ + struct lib_ring_buffer_iter iter; /* read-side iterator */ + unsigned long get_subbuf_consumed; /* Read-side consumed */ + unsigned long prod_snapshot; /* Producer count snapshot */ + unsigned long cons_snapshot; /* Consumer count snapshot */ + int get_subbuf:1; /* Sub-buffer being held by reader */ + int switch_timer_enabled:1; /* Protected by ring_buffer_nohz_lock */ + int read_timer_enabled:1; /* Protected by ring_buffer_nohz_lock */ +}; + +static inline +void *channel_get_private(struct channel *chan) +{ + return chan->backend.priv; +} + +/* + * Issue warnings and disable channels upon internal error. + * Can receive struct lib_ring_buffer or struct lib_ring_buffer_backend + * parameters. + */ +#define CHAN_WARN_ON(c, cond) \ + ({ \ + struct channel *__chan; \ + int _____ret = unlikely(cond); \ + if (_____ret) { \ + if (__same_type(*(c), struct channel_backend)) \ + __chan = container_of((void *) (c), \ + struct channel, \ + backend); \ + else if (__same_type(*(c), struct channel)) \ + __chan = (void *) (c); \ + else \ + BUG_ON(1); \ + atomic_inc(&__chan->record_disabled); \ + WARN_ON(1); \ + } \ + _____ret; \ + }) + +#endif /* _LINUX_RING_BUFFER_FRONTEND_TYPES_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/iterator.h b/drivers/staging/lttng/lib/ringbuffer/iterator.h new file mode 100644 index 0000000..f2bd50d --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/iterator.h @@ -0,0 +1,70 @@ +#ifndef _LINUX_RING_BUFFER_ITERATOR_H +#define _LINUX_RING_BUFFER_ITERATOR_H + +/* + * linux/ringbuffer/iterator.h + * + * (C) Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer and channel iterators. + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" + +/* + * lib_ring_buffer_get_next_record advances the buffer read position to the next + * record. It returns either the size of the next record, -EAGAIN if there is + * currently no data available, or -ENODATA if no data is available and buffer + * is finalized. + */ +extern ssize_t lib_ring_buffer_get_next_record(struct channel *chan, + struct lib_ring_buffer *buf); + +/* + * channel_get_next_record advances the buffer read position to the next record. + * It returns either the size of the next record, -EAGAIN if there is currently + * no data available, or -ENODATA if no data is available and buffer is + * finalized. + * Returns the current buffer in ret_buf. + */ +extern ssize_t channel_get_next_record(struct channel *chan, + struct lib_ring_buffer **ret_buf); + +/** + * read_current_record - copy the buffer current record into dest. + * @buf: ring buffer + * @dest: destination where the record should be copied + * + * dest should be large enough to contain the record. Returns the number of + * bytes copied. + */ +static inline size_t read_current_record(struct lib_ring_buffer *buf, void *dest) +{ + return lib_ring_buffer_read(&buf->backend, buf->iter.read_offset, + dest, buf->iter.payload_len); +} + +extern int lib_ring_buffer_iterator_open(struct lib_ring_buffer *buf); +extern void lib_ring_buffer_iterator_release(struct lib_ring_buffer *buf); +extern int channel_iterator_open(struct channel *chan); +extern void channel_iterator_release(struct channel *chan); + +extern const struct file_operations channel_payload_file_operations; +extern const struct file_operations lib_ring_buffer_payload_file_operations; + +/* + * Used internally. + */ +int channel_iterator_init(struct channel *chan); +void channel_iterator_unregister_notifiers(struct channel *chan); +void channel_iterator_free(struct channel *chan); +void channel_iterator_reset(struct channel *chan); +void lib_ring_buffer_iterator_reset(struct lib_ring_buffer *buf); + +#endif /* _LINUX_RING_BUFFER_ITERATOR_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/nohz.h b/drivers/staging/lttng/lib/ringbuffer/nohz.h new file mode 100644 index 0000000..3c31072 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/nohz.h @@ -0,0 +1,30 @@ +#ifndef _LINUX_RING_BUFFER_NOHZ_H +#define _LINUX_RING_BUFFER_NOHZ_H + +/* + * ringbuffer/nohz.h + * + * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef CONFIG_LIB_RING_BUFFER +void lib_ring_buffer_tick_nohz_flush(void); +void lib_ring_buffer_tick_nohz_stop(void); +void lib_ring_buffer_tick_nohz_restart(void); +#else +static inline void lib_ring_buffer_tick_nohz_flush(void) +{ +} + +static inline void lib_ring_buffer_tick_nohz_stop(void) +{ +} + +static inline void lib_ring_buffer_tick_nohz_restart(void) +{ +} +#endif + +#endif /* _LINUX_RING_BUFFER_NOHZ_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c new file mode 100644 index 0000000..d1b5b8c --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_backend.c @@ -0,0 +1,854 @@ +/* + * ring_buffer_backend.c + * + * Copyright (C) 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/stddef.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/cpu.h> +#include <linux/mm.h> + +#include "../../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "../../wrapper/ringbuffer/config.h" +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" + +/** + * lib_ring_buffer_backend_allocate - allocate a channel buffer + * @config: ring buffer instance configuration + * @buf: the buffer struct + * @size: total size of the buffer + * @num_subbuf: number of subbuffers + * @extra_reader_sb: need extra subbuffer for reader + */ +static +int lib_ring_buffer_backend_allocate(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_backend *bufb, + size_t size, size_t num_subbuf, + int extra_reader_sb) +{ + struct channel_backend *chanb = &bufb->chan->backend; + unsigned long j, num_pages, num_pages_per_subbuf, page_idx = 0; + unsigned long subbuf_size, mmap_offset = 0; + unsigned long num_subbuf_alloc; + struct page **pages; + void **virt; + unsigned long i; + + num_pages = size >> PAGE_SHIFT; + num_pages_per_subbuf = num_pages >> get_count_order(num_subbuf); + subbuf_size = chanb->subbuf_size; + num_subbuf_alloc = num_subbuf; + + if (extra_reader_sb) { + num_pages += num_pages_per_subbuf; /* Add pages for reader */ + num_subbuf_alloc++; + } + + pages = kmalloc_node(ALIGN(sizeof(*pages) * num_pages, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (unlikely(!pages)) + goto pages_error; + + virt = kmalloc_node(ALIGN(sizeof(*virt) * num_pages, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (unlikely(!virt)) + goto virt_error; + + bufb->array = kmalloc_node(ALIGN(sizeof(*bufb->array) + * num_subbuf_alloc, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (unlikely(!bufb->array)) + goto array_error; + + for (i = 0; i < num_pages; i++) { + pages[i] = alloc_pages_node(cpu_to_node(max(bufb->cpu, 0)), + GFP_KERNEL | __GFP_ZERO, 0); + if (unlikely(!pages[i])) + goto depopulate; + virt[i] = page_address(pages[i]); + } + bufb->num_pages_per_subbuf = num_pages_per_subbuf; + + /* Allocate backend pages array elements */ + for (i = 0; i < num_subbuf_alloc; i++) { + bufb->array[i] = + kzalloc_node(ALIGN( + sizeof(struct lib_ring_buffer_backend_pages) + + sizeof(struct lib_ring_buffer_backend_page) + * num_pages_per_subbuf, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (!bufb->array[i]) + goto free_array; + } + + /* Allocate write-side subbuffer table */ + bufb->buf_wsb = kzalloc_node(ALIGN( + sizeof(struct lib_ring_buffer_backend_subbuffer) + * num_subbuf, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(bufb->cpu, 0))); + if (unlikely(!bufb->buf_wsb)) + goto free_array; + + for (i = 0; i < num_subbuf; i++) + bufb->buf_wsb[i].id = subbuffer_id(config, 0, 1, i); + + /* Assign read-side subbuffer table */ + if (extra_reader_sb) + bufb->buf_rsb.id = subbuffer_id(config, 0, 1, + num_subbuf_alloc - 1); + else + bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); + + /* Assign pages to page index */ + for (i = 0; i < num_subbuf_alloc; i++) { + for (j = 0; j < num_pages_per_subbuf; j++) { + CHAN_WARN_ON(chanb, page_idx > num_pages); + bufb->array[i]->p[j].virt = virt[page_idx]; + bufb->array[i]->p[j].page = pages[page_idx]; + page_idx++; + } + if (config->output == RING_BUFFER_MMAP) { + bufb->array[i]->mmap_offset = mmap_offset; + mmap_offset += subbuf_size; + } + } + + /* + * If kmalloc ever uses vmalloc underneath, make sure the buffer pages + * will not fault. + */ + wrapper_vmalloc_sync_all(); + kfree(virt); + kfree(pages); + return 0; + +free_array: + for (i = 0; (i < num_subbuf_alloc && bufb->array[i]); i++) + kfree(bufb->array[i]); +depopulate: + /* Free all allocated pages */ + for (i = 0; (i < num_pages && pages[i]); i++) + __free_page(pages[i]); + kfree(bufb->array); +array_error: + kfree(virt); +virt_error: + kfree(pages); +pages_error: + return -ENOMEM; +} + +int lib_ring_buffer_backend_create(struct lib_ring_buffer_backend *bufb, + struct channel_backend *chanb, int cpu) +{ + const struct lib_ring_buffer_config *config = chanb->config; + + bufb->chan = container_of(chanb, struct channel, backend); + bufb->cpu = cpu; + + return lib_ring_buffer_backend_allocate(config, bufb, chanb->buf_size, + chanb->num_subbuf, + chanb->extra_reader_sb); +} + +void lib_ring_buffer_backend_free(struct lib_ring_buffer_backend *bufb) +{ + struct channel_backend *chanb = &bufb->chan->backend; + unsigned long i, j, num_subbuf_alloc; + + num_subbuf_alloc = chanb->num_subbuf; + if (chanb->extra_reader_sb) + num_subbuf_alloc++; + + kfree(bufb->buf_wsb); + for (i = 0; i < num_subbuf_alloc; i++) { + for (j = 0; j < bufb->num_pages_per_subbuf; j++) + __free_page(bufb->array[i]->p[j].page); + kfree(bufb->array[i]); + } + kfree(bufb->array); + bufb->allocated = 0; +} + +void lib_ring_buffer_backend_reset(struct lib_ring_buffer_backend *bufb) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + unsigned long num_subbuf_alloc; + unsigned int i; + + num_subbuf_alloc = chanb->num_subbuf; + if (chanb->extra_reader_sb) + num_subbuf_alloc++; + + for (i = 0; i < chanb->num_subbuf; i++) + bufb->buf_wsb[i].id = subbuffer_id(config, 0, 1, i); + if (chanb->extra_reader_sb) + bufb->buf_rsb.id = subbuffer_id(config, 0, 1, + num_subbuf_alloc - 1); + else + bufb->buf_rsb.id = subbuffer_id(config, 0, 1, 0); + + for (i = 0; i < num_subbuf_alloc; i++) { + /* Don't reset mmap_offset */ + v_set(config, &bufb->array[i]->records_commit, 0); + v_set(config, &bufb->array[i]->records_unread, 0); + bufb->array[i]->data_size = 0; + /* Don't reset backend page and virt addresses */ + } + /* Don't reset num_pages_per_subbuf, cpu, allocated */ + v_set(config, &bufb->records_read, 0); +} + +/* + * The frontend is responsible for also calling ring_buffer_backend_reset for + * each buffer when calling channel_backend_reset. + */ +void channel_backend_reset(struct channel_backend *chanb) +{ + struct channel *chan = container_of(chanb, struct channel, backend); + const struct lib_ring_buffer_config *config = chanb->config; + + /* + * Don't reset buf_size, subbuf_size, subbuf_size_order, + * num_subbuf_order, buf_size_order, extra_reader_sb, num_subbuf, + * priv, notifiers, config, cpumask and name. + */ + chanb->start_tsc = config->cb.ring_buffer_clock_read(chan); +} + +#ifdef CONFIG_HOTPLUG_CPU +/** + * lib_ring_buffer_cpu_hp_callback - CPU hotplug callback + * @nb: notifier block + * @action: hotplug action to take + * @hcpu: CPU number + * + * Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD) + */ +static +int __cpuinit lib_ring_buffer_cpu_hp_callback(struct notifier_block *nb, + unsigned long action, + void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct channel_backend *chanb = container_of(nb, struct channel_backend, + cpu_hp_notifier); + const struct lib_ring_buffer_config *config = chanb->config; + struct lib_ring_buffer *buf; + int ret; + + CHAN_WARN_ON(chanb, config->alloc == RING_BUFFER_ALLOC_GLOBAL); + + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + buf = per_cpu_ptr(chanb->buf, cpu); + ret = lib_ring_buffer_create(buf, chanb, cpu); + if (ret) { + printk(KERN_ERR + "ring_buffer_cpu_hp_callback: cpu %d " + "buffer creation failed\n", cpu); + return NOTIFY_BAD; + } + break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: + /* No need to do a buffer switch here, because it will happen + * when tracing is stopped, or will be done by switch timer CPU + * DEAD callback. */ + break; + } + return NOTIFY_OK; +} +#endif + +/** + * channel_backend_init - initialize a channel backend + * @chanb: channel backend + * @name: channel name + * @config: client ring buffer configuration + * @priv: client private data + * @parent: dentry of parent directory, %NULL for root directory + * @subbuf_size: size of sub-buffers (> PAGE_SIZE, power of 2) + * @num_subbuf: number of sub-buffers (power of 2) + * + * Returns channel pointer if successful, %NULL otherwise. + * + * Creates per-cpu channel buffers using the sizes and attributes + * specified. The created channel buffer files will be named + * name_0...name_N-1. File permissions will be %S_IRUSR. + * + * Called with CPU hotplug disabled. + */ +int channel_backend_init(struct channel_backend *chanb, + const char *name, + const struct lib_ring_buffer_config *config, + void *priv, size_t subbuf_size, size_t num_subbuf) +{ + struct channel *chan = container_of(chanb, struct channel, backend); + unsigned int i; + int ret; + + if (!name) + return -EPERM; + + if (!(subbuf_size && num_subbuf)) + return -EPERM; + + /* Check that the subbuffer size is larger than a page. */ + if (subbuf_size < PAGE_SIZE) + return -EINVAL; + + /* + * Make sure the number of subbuffers and subbuffer size are power of 2. + */ + CHAN_WARN_ON(chanb, hweight32(subbuf_size) != 1); + CHAN_WARN_ON(chanb, hweight32(num_subbuf) != 1); + + ret = subbuffer_id_check_index(config, num_subbuf); + if (ret) + return ret; + + chanb->priv = priv; + chanb->buf_size = num_subbuf * subbuf_size; + chanb->subbuf_size = subbuf_size; + chanb->buf_size_order = get_count_order(chanb->buf_size); + chanb->subbuf_size_order = get_count_order(subbuf_size); + chanb->num_subbuf_order = get_count_order(num_subbuf); + chanb->extra_reader_sb = + (config->mode == RING_BUFFER_OVERWRITE) ? 1 : 0; + chanb->num_subbuf = num_subbuf; + strlcpy(chanb->name, name, NAME_MAX); + chanb->config = config; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + if (!zalloc_cpumask_var(&chanb->cpumask, GFP_KERNEL)) + return -ENOMEM; + } + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + /* Allocating the buffer per-cpu structures */ + chanb->buf = alloc_percpu(struct lib_ring_buffer); + if (!chanb->buf) + goto free_cpumask; + + /* + * In case of non-hotplug cpu, if the ring-buffer is allocated + * in early initcall, it will not be notified of secondary cpus. + * In that off case, we need to allocate for all possible cpus. + */ +#ifdef CONFIG_HOTPLUG_CPU + /* + * buf->backend.allocated test takes care of concurrent CPU + * hotplug. + * Priority higher than frontend, so we create the ring buffer + * before we start the timer. + */ + chanb->cpu_hp_notifier.notifier_call = + lib_ring_buffer_cpu_hp_callback; + chanb->cpu_hp_notifier.priority = 5; + register_hotcpu_notifier(&chanb->cpu_hp_notifier); + + get_online_cpus(); + for_each_online_cpu(i) { + ret = lib_ring_buffer_create(per_cpu_ptr(chanb->buf, i), + chanb, i); + if (ret) + goto free_bufs; /* cpu hotplug locked */ + } + put_online_cpus(); +#else + for_each_possible_cpu(i) { + ret = lib_ring_buffer_create(per_cpu_ptr(chanb->buf, i), + chanb, i); + if (ret) + goto free_bufs; /* cpu hotplug locked */ + } +#endif + } else { + chanb->buf = kzalloc(sizeof(struct lib_ring_buffer), GFP_KERNEL); + if (!chanb->buf) + goto free_cpumask; + ret = lib_ring_buffer_create(chanb->buf, chanb, -1); + if (ret) + goto free_bufs; + } + chanb->start_tsc = config->cb.ring_buffer_clock_read(chan); + + return 0; + +free_bufs: + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + for_each_possible_cpu(i) { + struct lib_ring_buffer *buf = per_cpu_ptr(chanb->buf, i); + + if (!buf->backend.allocated) + continue; + lib_ring_buffer_free(buf); + } +#ifdef CONFIG_HOTPLUG_CPU + put_online_cpus(); +#endif + free_percpu(chanb->buf); + } else + kfree(chanb->buf); +free_cpumask: + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + free_cpumask_var(chanb->cpumask); + return -ENOMEM; +} + +/** + * channel_backend_unregister_notifiers - unregister notifiers + * @chan: the channel + * + * Holds CPU hotplug. + */ +void channel_backend_unregister_notifiers(struct channel_backend *chanb) +{ + const struct lib_ring_buffer_config *config = chanb->config; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + unregister_hotcpu_notifier(&chanb->cpu_hp_notifier); +} + +/** + * channel_backend_free - destroy the channel + * @chan: the channel + * + * Destroy all channel buffers and frees the channel. + */ +void channel_backend_free(struct channel_backend *chanb) +{ + const struct lib_ring_buffer_config *config = chanb->config; + unsigned int i; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + for_each_possible_cpu(i) { + struct lib_ring_buffer *buf = per_cpu_ptr(chanb->buf, i); + + if (!buf->backend.allocated) + continue; + lib_ring_buffer_free(buf); + } + free_cpumask_var(chanb->cpumask); + free_percpu(chanb->buf); + } else { + struct lib_ring_buffer *buf = chanb->buf; + + CHAN_WARN_ON(chanb, !buf->backend.allocated); + lib_ring_buffer_free(buf); + kfree(buf); + } +} + +/** + * lib_ring_buffer_write - write data to a ring_buffer buffer. + * @bufb : buffer backend + * @offset : offset within the buffer + * @src : source address + * @len : length to write + * @pagecpy : page size copied so far + */ +void _lib_ring_buffer_write(struct lib_ring_buffer_backend *bufb, size_t offset, + const void *src, size_t len, ssize_t pagecpy) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t sbidx, index; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + do { + len -= pagecpy; + src += pagecpy; + offset += pagecpy; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + + /* + * Underlying layer should never ask for writes across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + + pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK)); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + lib_ring_buffer_do_copy(config, + rpages->p[index].virt + + (offset & ~PAGE_MASK), + src, pagecpy); + } while (unlikely(len != pagecpy)); +} +EXPORT_SYMBOL_GPL(_lib_ring_buffer_write); + + +/** + * lib_ring_buffer_memset - write len bytes of c to a ring_buffer buffer. + * @bufb : buffer backend + * @offset : offset within the buffer + * @c : the byte to write + * @len : length to write + * @pagecpy : page size copied so far + */ +void _lib_ring_buffer_memset(struct lib_ring_buffer_backend *bufb, + size_t offset, + int c, size_t len, ssize_t pagecpy) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t sbidx, index; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + do { + len -= pagecpy; + offset += pagecpy; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + + /* + * Underlying layer should never ask for writes across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + + pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK)); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + lib_ring_buffer_do_memset(rpages->p[index].virt + + (offset & ~PAGE_MASK), + c, pagecpy); + } while (unlikely(len != pagecpy)); +} +EXPORT_SYMBOL_GPL(_lib_ring_buffer_memset); + + +/** + * lib_ring_buffer_copy_from_user - write user data to a ring_buffer buffer. + * @bufb : buffer backend + * @offset : offset within the buffer + * @src : source address + * @len : length to write + * @pagecpy : page size copied so far + * + * This function deals with userspace pointers, it should never be called + * directly without having the src pointer checked with access_ok() + * previously. + */ +void _lib_ring_buffer_copy_from_user(struct lib_ring_buffer_backend *bufb, + size_t offset, + const void __user *src, size_t len, + ssize_t pagecpy) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t sbidx, index; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + int ret; + + do { + len -= pagecpy; + src += pagecpy; + offset += pagecpy; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + + /* + * Underlying layer should never ask for writes across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + + pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK)); + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + ret = lib_ring_buffer_do_copy_from_user(rpages->p[index].virt + + (offset & ~PAGE_MASK), + src, pagecpy) != 0; + if (ret > 0) { + offset += (pagecpy - ret); + len -= (pagecpy - ret); + _lib_ring_buffer_memset(bufb, offset, 0, len, 0); + break; /* stop copy */ + } + } while (unlikely(len != pagecpy)); +} +EXPORT_SYMBOL_GPL(_lib_ring_buffer_copy_from_user); + +/** + * lib_ring_buffer_read - read data from ring_buffer_buffer. + * @bufb : buffer backend + * @offset : offset within the buffer + * @dest : destination address + * @len : length to copy to destination + * + * Should be protected by get_subbuf/put_subbuf. + * Returns the length copied. + */ +size_t lib_ring_buffer_read(struct lib_ring_buffer_backend *bufb, size_t offset, + void *dest, size_t len) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t index; + ssize_t pagecpy, orig_len; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + orig_len = len; + offset &= chanb->buf_size - 1; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + if (unlikely(!len)) + return 0; + for (;;) { + pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK)); + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + memcpy(dest, rpages->p[index].virt + (offset & ~PAGE_MASK), + pagecpy); + len -= pagecpy; + if (likely(!len)) + break; + dest += pagecpy; + offset += pagecpy; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + /* + * Underlying layer should never ask for reads across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + } + return orig_len; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_read); + +/** + * __lib_ring_buffer_copy_to_user - read data from ring_buffer to userspace + * @bufb : buffer backend + * @offset : offset within the buffer + * @dest : destination userspace address + * @len : length to copy to destination + * + * Should be protected by get_subbuf/put_subbuf. + * access_ok() must have been performed on dest addresses prior to call this + * function. + * Returns -EFAULT on error, 0 if ok. + */ +int __lib_ring_buffer_copy_to_user(struct lib_ring_buffer_backend *bufb, + size_t offset, void __user *dest, size_t len) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t index; + ssize_t pagecpy; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + if (unlikely(!len)) + return 0; + for (;;) { + pagecpy = min_t(size_t, len, PAGE_SIZE - (offset & ~PAGE_MASK)); + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + if (__copy_to_user(dest, + rpages->p[index].virt + (offset & ~PAGE_MASK), + pagecpy)) + return -EFAULT; + len -= pagecpy; + if (likely(!len)) + break; + dest += pagecpy; + offset += pagecpy; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + /* + * Underlying layer should never ask for reads across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + } + return 0; +} +EXPORT_SYMBOL_GPL(__lib_ring_buffer_copy_to_user); + +/** + * lib_ring_buffer_read_cstr - read a C-style string from ring_buffer. + * @bufb : buffer backend + * @offset : offset within the buffer + * @dest : destination address + * @len : destination's length + * + * return string's length + * Should be protected by get_subbuf/put_subbuf. + */ +int lib_ring_buffer_read_cstr(struct lib_ring_buffer_backend *bufb, size_t offset, + void *dest, size_t len) +{ + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + size_t index; + ssize_t pagecpy, pagelen, strpagelen, orig_offset; + char *str; + struct lib_ring_buffer_backend_pages *rpages; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + orig_offset = offset; + for (;;) { + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + str = (char *)rpages->p[index].virt + (offset & ~PAGE_MASK); + pagelen = PAGE_SIZE - (offset & ~PAGE_MASK); + strpagelen = strnlen(str, pagelen); + if (len) { + pagecpy = min_t(size_t, len, strpagelen); + if (dest) { + memcpy(dest, str, pagecpy); + dest += pagecpy; + } + len -= pagecpy; + } + offset += strpagelen; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + if (strpagelen < pagelen) + break; + /* + * Underlying layer should never ask for reads across + * subbuffers. + */ + CHAN_WARN_ON(chanb, offset >= chanb->buf_size); + } + if (dest && len) + ((char *)dest)[0] = 0; + return offset - orig_offset; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_read_cstr); + +/** + * lib_ring_buffer_read_get_page - Get a whole page to read from + * @bufb : buffer backend + * @offset : offset within the buffer + * @virt : pointer to page address (output) + * + * Should be protected by get_subbuf/put_subbuf. + * Returns the pointer to the page struct pointer. + */ +struct page **lib_ring_buffer_read_get_page(struct lib_ring_buffer_backend *bufb, + size_t offset, void ***virt) +{ + size_t index; + struct lib_ring_buffer_backend_pages *rpages; + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + *virt = &rpages->p[index].virt; + return &rpages->p[index].page; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_read_get_page); + +/** + * lib_ring_buffer_read_offset_address - get address of a buffer location + * @bufb : buffer backend + * @offset : offset within the buffer. + * + * Return the address where a given offset is located (for read). + * Should be used to get the current subbuffer header pointer. Given we know + * it's never on a page boundary, it's safe to write directly to this address, + * as long as the write is never bigger than a page size. + */ +void *lib_ring_buffer_read_offset_address(struct lib_ring_buffer_backend *bufb, + size_t offset) +{ + size_t index; + struct lib_ring_buffer_backend_pages *rpages; + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + id = bufb->buf_rsb.id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + return rpages->p[index].virt + (offset & ~PAGE_MASK); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_read_offset_address); + +/** + * lib_ring_buffer_offset_address - get address of a location within the buffer + * @bufb : buffer backend + * @offset : offset within the buffer. + * + * Return the address where a given offset is located. + * Should be used to get the current subbuffer header pointer. Given we know + * it's always at the beginning of a page, it's safe to write directly to this + * address, as long as the write is never bigger than a page size. + */ +void *lib_ring_buffer_offset_address(struct lib_ring_buffer_backend *bufb, + size_t offset) +{ + size_t sbidx, index; + struct lib_ring_buffer_backend_pages *rpages; + struct channel_backend *chanb = &bufb->chan->backend; + const struct lib_ring_buffer_config *config = chanb->config; + unsigned long sb_bindex, id; + + offset &= chanb->buf_size - 1; + sbidx = offset >> chanb->subbuf_size_order; + index = (offset & (chanb->subbuf_size - 1)) >> PAGE_SHIFT; + id = bufb->buf_wsb[sbidx].id; + sb_bindex = subbuffer_id_get_index(config, id); + rpages = bufb->array[sb_bindex]; + CHAN_WARN_ON(chanb, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, id)); + return rpages->p[index].virt + (offset & ~PAGE_MASK); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_offset_address); diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c new file mode 100644 index 0000000..802f5cd --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_frontend.c @@ -0,0 +1,1721 @@ +/* + * ring_buffer_frontend.c + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer wait-free buffer synchronization. Producer-consumer and flight + * recorder (overwrite) modes. See thesis: + * + * Desnoyers, Mathieu (2009), "Low-Impact Operating System Tracing", Ph.D. + * dissertation, Ecole Polytechnique de Montreal. + * http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf + * + * - Algorithm presentation in Chapter 5: + * "Lockless Multi-Core High-Throughput Buffering". + * - Algorithm formal verification in Section 8.6: + * "Formal verification of LTTng" + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Inspired from LTT and RelayFS: + * Karim Yaghmour <karim at opersys.com> + * Tom Zanussi <zanussi at us.ibm.com> + * Bob Wisniewski <bob at watson.ibm.com> + * And from K42 : + * Bob Wisniewski <bob at watson.ibm.com> + * + * Buffer reader semantic : + * + * - get_subbuf_size + * while buffer is not finalized and empty + * - get_subbuf + * - if return value != 0, continue + * - splice one subbuffer worth of data to a pipe + * - splice the data from pipe to disk/network + * - put_subbuf + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/percpu.h> + +#include "../../wrapper/ringbuffer/config.h" +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" +#include "../../wrapper/ringbuffer/iterator.h" +#include "../../wrapper/ringbuffer/nohz.h" + +/* + * Internal structure representing offsets to use at a sub-buffer switch. + */ +struct switch_offsets { + unsigned long begin, end, old; + size_t pre_header_padding, size; + unsigned int switch_new_start:1, switch_new_end:1, switch_old_start:1, + switch_old_end:1; +}; + +#ifdef CONFIG_NO_HZ +enum tick_nohz_val { + TICK_NOHZ_STOP, + TICK_NOHZ_FLUSH, + TICK_NOHZ_RESTART, +}; + +static ATOMIC_NOTIFIER_HEAD(tick_nohz_notifier); +#endif /* CONFIG_NO_HZ */ + +static DEFINE_PER_CPU(spinlock_t, ring_buffer_nohz_lock); + +DEFINE_PER_CPU(unsigned int, lib_ring_buffer_nesting); +EXPORT_PER_CPU_SYMBOL(lib_ring_buffer_nesting); + +static +void lib_ring_buffer_print_errors(struct channel *chan, + struct lib_ring_buffer *buf, int cpu); + +/* + * Must be called under cpu hotplug protection. + */ +void lib_ring_buffer_free(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + + lib_ring_buffer_print_errors(chan, buf, buf->backend.cpu); + kfree(buf->commit_hot); + kfree(buf->commit_cold); + + lib_ring_buffer_backend_free(&buf->backend); +} + +/** + * lib_ring_buffer_reset - Reset ring buffer to initial values. + * @buf: Ring buffer. + * + * Effectively empty the ring buffer. Should be called when the buffer is not + * used for writing. The ring buffer can be opened for reading, but the reader + * should not be using the iterator concurrently with reset. The previous + * current iterator record is reset. + */ +void lib_ring_buffer_reset(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned int i; + + /* + * Reset iterator first. It will put the subbuffer if it currently holds + * it. + */ + lib_ring_buffer_iterator_reset(buf); + v_set(config, &buf->offset, 0); + for (i = 0; i < chan->backend.num_subbuf; i++) { + v_set(config, &buf->commit_hot[i].cc, 0); + v_set(config, &buf->commit_hot[i].seq, 0); + v_set(config, &buf->commit_cold[i].cc_sb, 0); + } + atomic_long_set(&buf->consumed, 0); + atomic_set(&buf->record_disabled, 0); + v_set(config, &buf->last_tsc, 0); + lib_ring_buffer_backend_reset(&buf->backend); + /* Don't reset number of active readers */ + v_set(config, &buf->records_lost_full, 0); + v_set(config, &buf->records_lost_wrap, 0); + v_set(config, &buf->records_lost_big, 0); + v_set(config, &buf->records_count, 0); + v_set(config, &buf->records_overrun, 0); + buf->finalized = 0; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_reset); + +/** + * channel_reset - Reset channel to initial values. + * @chan: Channel. + * + * Effectively empty the channel. Should be called when the channel is not used + * for writing. The channel can be opened for reading, but the reader should not + * be using the iterator concurrently with reset. The previous current iterator + * record is reset. + */ +void channel_reset(struct channel *chan) +{ + /* + * Reset iterators first. Will put the subbuffer if held for reading. + */ + channel_iterator_reset(chan); + atomic_set(&chan->record_disabled, 0); + /* Don't reset commit_count_mask, still valid */ + channel_backend_reset(&chan->backend); + /* Don't reset switch/read timer interval */ + /* Don't reset notifiers and notifier enable bits */ + /* Don't reset reader reference count */ +} +EXPORT_SYMBOL_GPL(channel_reset); + +/* + * Must be called under cpu hotplug protection. + */ +int lib_ring_buffer_create(struct lib_ring_buffer *buf, + struct channel_backend *chanb, int cpu) +{ + const struct lib_ring_buffer_config *config = chanb->config; + struct channel *chan = container_of(chanb, struct channel, backend); + void *priv = chanb->priv; + size_t subbuf_header_size; + u64 tsc; + int ret; + + /* Test for cpu hotplug */ + if (buf->backend.allocated) + return 0; + + /* + * Paranoia: per cpu dynamic allocation is not officially documented as + * zeroing the memory, so let's do it here too, just in case. + */ + memset(buf, 0, sizeof(*buf)); + + ret = lib_ring_buffer_backend_create(&buf->backend, &chan->backend, cpu); + if (ret) + return ret; + + buf->commit_hot = + kzalloc_node(ALIGN(sizeof(*buf->commit_hot) + * chan->backend.num_subbuf, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(cpu, 0))); + if (!buf->commit_hot) { + ret = -ENOMEM; + goto free_chanbuf; + } + + buf->commit_cold = + kzalloc_node(ALIGN(sizeof(*buf->commit_cold) + * chan->backend.num_subbuf, + 1 << INTERNODE_CACHE_SHIFT), + GFP_KERNEL, cpu_to_node(max(cpu, 0))); + if (!buf->commit_cold) { + ret = -ENOMEM; + goto free_commit; + } + + init_waitqueue_head(&buf->read_wait); + init_waitqueue_head(&buf->write_wait); + raw_spin_lock_init(&buf->raw_tick_nohz_spinlock); + + /* + * Write the subbuffer header for first subbuffer so we know the total + * duration of data gathering. + */ + subbuf_header_size = config->cb.subbuffer_header_size(); + v_set(config, &buf->offset, subbuf_header_size); + subbuffer_id_clear_noref(config, &buf->backend.buf_wsb[0].id); + tsc = config->cb.ring_buffer_clock_read(buf->backend.chan); + config->cb.buffer_begin(buf, tsc, 0); + v_add(config, subbuf_header_size, &buf->commit_hot[0].cc); + + if (config->cb.buffer_create) { + ret = config->cb.buffer_create(buf, priv, cpu, chanb->name); + if (ret) + goto free_init; + } + + /* + * Ensure the buffer is ready before setting it to allocated and setting + * the cpumask. + * Used for cpu hotplug vs cpumask iteration. + */ + smp_wmb(); + buf->backend.allocated = 1; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + CHAN_WARN_ON(chan, cpumask_test_cpu(cpu, + chan->backend.cpumask)); + cpumask_set_cpu(cpu, chan->backend.cpumask); + } + + return 0; + + /* Error handling */ +free_init: + kfree(buf->commit_cold); +free_commit: + kfree(buf->commit_hot); +free_chanbuf: + lib_ring_buffer_backend_free(&buf->backend); + return ret; +} + +static void switch_buffer_timer(unsigned long data) +{ + struct lib_ring_buffer *buf = (struct lib_ring_buffer *)data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + /* + * Only flush buffers periodically if readers are active. + */ + if (atomic_long_read(&buf->active_readers)) + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + mod_timer_pinned(&buf->switch_timer, + jiffies + chan->switch_timer_interval); + else + mod_timer(&buf->switch_timer, + jiffies + chan->switch_timer_interval); +} + +/* + * Called with ring_buffer_nohz_lock held for per-cpu buffers. + */ +static void lib_ring_buffer_start_switch_timer(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (!chan->switch_timer_interval || buf->switch_timer_enabled) + return; + init_timer(&buf->switch_timer); + buf->switch_timer.function = switch_buffer_timer; + buf->switch_timer.expires = jiffies + chan->switch_timer_interval; + buf->switch_timer.data = (unsigned long)buf; + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + add_timer_on(&buf->switch_timer, buf->backend.cpu); + else + add_timer(&buf->switch_timer); + buf->switch_timer_enabled = 1; +} + +/* + * Called with ring_buffer_nohz_lock held for per-cpu buffers. + */ +static void lib_ring_buffer_stop_switch_timer(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + + if (!chan->switch_timer_interval || !buf->switch_timer_enabled) + return; + + del_timer_sync(&buf->switch_timer); + buf->switch_timer_enabled = 0; +} + +/* + * Polling timer to check the channels for data. + */ +static void read_buffer_timer(unsigned long data) +{ + struct lib_ring_buffer *buf = (struct lib_ring_buffer *)data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + CHAN_WARN_ON(chan, !buf->backend.allocated); + + if (atomic_long_read(&buf->active_readers) + && lib_ring_buffer_poll_deliver(config, buf, chan)) { + wake_up_interruptible(&buf->read_wait); + wake_up_interruptible(&chan->read_wait); + } + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + mod_timer_pinned(&buf->read_timer, + jiffies + chan->read_timer_interval); + else + mod_timer(&buf->read_timer, + jiffies + chan->read_timer_interval); +} + +/* + * Called with ring_buffer_nohz_lock held for per-cpu buffers. + */ +static void lib_ring_buffer_start_read_timer(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER + || !chan->read_timer_interval + || buf->read_timer_enabled) + return; + + init_timer(&buf->read_timer); + buf->read_timer.function = read_buffer_timer; + buf->read_timer.expires = jiffies + chan->read_timer_interval; + buf->read_timer.data = (unsigned long)buf; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + add_timer_on(&buf->read_timer, buf->backend.cpu); + else + add_timer(&buf->read_timer); + buf->read_timer_enabled = 1; +} + +/* + * Called with ring_buffer_nohz_lock held for per-cpu buffers. + */ +static void lib_ring_buffer_stop_read_timer(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (config->wakeup != RING_BUFFER_WAKEUP_BY_TIMER + || !chan->read_timer_interval + || !buf->read_timer_enabled) + return; + + del_timer_sync(&buf->read_timer); + /* + * do one more check to catch data that has been written in the last + * timer period. + */ + if (lib_ring_buffer_poll_deliver(config, buf, chan)) { + wake_up_interruptible(&buf->read_wait); + wake_up_interruptible(&chan->read_wait); + } + buf->read_timer_enabled = 0; +} + +#ifdef CONFIG_HOTPLUG_CPU +/** + * lib_ring_buffer_cpu_hp_callback - CPU hotplug callback + * @nb: notifier block + * @action: hotplug action to take + * @hcpu: CPU number + * + * Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD) + */ +static +int __cpuinit lib_ring_buffer_cpu_hp_callback(struct notifier_block *nb, + unsigned long action, + void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct channel *chan = container_of(nb, struct channel, + cpu_hp_notifier); + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, cpu); + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (!chan->cpu_hp_enable) + return NOTIFY_DONE; + + CHAN_WARN_ON(chan, config->alloc == RING_BUFFER_ALLOC_GLOBAL); + + switch (action) { + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + wake_up_interruptible(&chan->hp_wait); + lib_ring_buffer_start_switch_timer(buf); + lib_ring_buffer_start_read_timer(buf); + return NOTIFY_OK; + + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + lib_ring_buffer_stop_switch_timer(buf); + lib_ring_buffer_stop_read_timer(buf); + return NOTIFY_OK; + + case CPU_DEAD: + case CPU_DEAD_FROZEN: + /* + * Performing a buffer switch on a remote CPU. Performed by + * the CPU responsible for doing the hotunplug after the target + * CPU stopped running completely. Ensures that all data + * from that remote CPU is flushed. + */ + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} +#endif + +#if defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) +/* + * For per-cpu buffers, call the reader wakeups before switching the buffer, so + * that wake-up-tracing generated events are flushed before going idle (in + * tick_nohz). We test if the spinlock is locked to deal with the race where + * readers try to sample the ring buffer before we perform the switch. We let + * the readers retry in that case. If there is data in the buffer, the wake up + * is going to forbid the CPU running the reader thread from going idle. + */ +static int notrace ring_buffer_tick_nohz_callback(struct notifier_block *nb, + unsigned long val, + void *data) +{ + struct channel *chan = container_of(nb, struct channel, + tick_nohz_notifier); + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + int cpu = smp_processor_id(); + + if (config->alloc != RING_BUFFER_ALLOC_PER_CPU) { + /* + * We don't support keeping the system idle with global buffers + * and streaming active. In order to do so, we would need to + * sample a non-nohz-cpumask racelessly with the nohz updates + * without adding synchronization overhead to nohz. Leave this + * use-case out for now. + */ + return 0; + } + + buf = channel_get_ring_buffer(config, chan, cpu); + switch (val) { + case TICK_NOHZ_FLUSH: + raw_spin_lock(&buf->raw_tick_nohz_spinlock); + if (config->wakeup == RING_BUFFER_WAKEUP_BY_TIMER + && chan->read_timer_interval + && atomic_long_read(&buf->active_readers) + && (lib_ring_buffer_poll_deliver(config, buf, chan) + || lib_ring_buffer_pending_data(config, buf, chan))) { + wake_up_interruptible(&buf->read_wait); + wake_up_interruptible(&chan->read_wait); + } + if (chan->switch_timer_interval) + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + raw_spin_unlock(&buf->raw_tick_nohz_spinlock); + break; + case TICK_NOHZ_STOP: + spin_lock(&__get_cpu_var(ring_buffer_nohz_lock)); + lib_ring_buffer_stop_switch_timer(buf); + lib_ring_buffer_stop_read_timer(buf); + spin_unlock(&__get_cpu_var(ring_buffer_nohz_lock)); + break; + case TICK_NOHZ_RESTART: + spin_lock(&__get_cpu_var(ring_buffer_nohz_lock)); + lib_ring_buffer_start_read_timer(buf); + lib_ring_buffer_start_switch_timer(buf); + spin_unlock(&__get_cpu_var(ring_buffer_nohz_lock)); + break; + } + + return 0; +} + +void notrace lib_ring_buffer_tick_nohz_flush(void) +{ + atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_FLUSH, + NULL); +} + +void notrace lib_ring_buffer_tick_nohz_stop(void) +{ + atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_STOP, + NULL); +} + +void notrace lib_ring_buffer_tick_nohz_restart(void) +{ + atomic_notifier_call_chain(&tick_nohz_notifier, TICK_NOHZ_RESTART, + NULL); +} +#endif /* defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) */ + +/* + * Holds CPU hotplug. + */ +static void channel_unregister_notifiers(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + int cpu; + + channel_iterator_unregister_notifiers(chan); + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { +#ifdef CONFIG_NO_HZ + /* + * Remove the nohz notifier first, so we are certain we stop + * the timers. + */ + atomic_notifier_chain_unregister(&tick_nohz_notifier, + &chan->tick_nohz_notifier); + /* + * ring_buffer_nohz_lock will not be needed below, because + * we just removed the notifiers, which were the only source of + * concurrency. + */ +#endif /* CONFIG_NO_HZ */ +#ifdef CONFIG_HOTPLUG_CPU + get_online_cpus(); + chan->cpu_hp_enable = 0; + for_each_online_cpu(cpu) { + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, + cpu); + lib_ring_buffer_stop_switch_timer(buf); + lib_ring_buffer_stop_read_timer(buf); + } + put_online_cpus(); + unregister_cpu_notifier(&chan->cpu_hp_notifier); +#else + for_each_possible_cpu(cpu) { + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, + cpu); + lib_ring_buffer_stop_switch_timer(buf); + lib_ring_buffer_stop_read_timer(buf); + } +#endif + } else { + struct lib_ring_buffer *buf = chan->backend.buf; + + lib_ring_buffer_stop_switch_timer(buf); + lib_ring_buffer_stop_read_timer(buf); + } + channel_backend_unregister_notifiers(&chan->backend); +} + +static void channel_free(struct channel *chan) +{ + channel_iterator_free(chan); + channel_backend_free(&chan->backend); + kfree(chan); +} + +/** + * channel_create - Create channel. + * @config: ring buffer instance configuration + * @name: name of the channel + * @priv: ring buffer client private data + * @buf_addr: pointer the the beginning of the preallocated buffer contiguous + * address mapping. It is used only by RING_BUFFER_STATIC + * configuration. It can be set to NULL for other backends. + * @subbuf_size: subbuffer size + * @num_subbuf: number of subbuffers + * @switch_timer_interval: Time interval (in us) to fill sub-buffers with + * padding to let readers get those sub-buffers. + * Used for live streaming. + * @read_timer_interval: Time interval (in us) to wake up pending readers. + * + * Holds cpu hotplug. + * Returns NULL on failure. + */ +struct channel *channel_create(const struct lib_ring_buffer_config *config, + const char *name, void *priv, void *buf_addr, + size_t subbuf_size, + size_t num_subbuf, unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + int ret, cpu; + struct channel *chan; + + if (lib_ring_buffer_check_config(config, switch_timer_interval, + read_timer_interval)) + return NULL; + + chan = kzalloc(sizeof(struct channel), GFP_KERNEL); + if (!chan) + return NULL; + + ret = channel_backend_init(&chan->backend, name, config, priv, + subbuf_size, num_subbuf); + if (ret) + goto error; + + ret = channel_iterator_init(chan); + if (ret) + goto error_free_backend; + + chan->commit_count_mask = (~0UL >> chan->backend.num_subbuf_order); + chan->switch_timer_interval = usecs_to_jiffies(switch_timer_interval); + chan->read_timer_interval = usecs_to_jiffies(read_timer_interval); + kref_init(&chan->ref); + init_waitqueue_head(&chan->read_wait); + init_waitqueue_head(&chan->hp_wait); + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { +#if defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) + /* Only benefit from NO_HZ idle with per-cpu buffers for now. */ + chan->tick_nohz_notifier.notifier_call = + ring_buffer_tick_nohz_callback; + chan->tick_nohz_notifier.priority = ~0U; + atomic_notifier_chain_register(&tick_nohz_notifier, + &chan->tick_nohz_notifier); +#endif /* defined(CONFIG_NO_HZ) && defined(CONFIG_LIB_RING_BUFFER) */ + + /* + * In case of non-hotplug cpu, if the ring-buffer is allocated + * in early initcall, it will not be notified of secondary cpus. + * In that off case, we need to allocate for all possible cpus. + */ +#ifdef CONFIG_HOTPLUG_CPU + chan->cpu_hp_notifier.notifier_call = + lib_ring_buffer_cpu_hp_callback; + chan->cpu_hp_notifier.priority = 6; + register_cpu_notifier(&chan->cpu_hp_notifier); + + get_online_cpus(); + for_each_online_cpu(cpu) { + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, + cpu); + spin_lock(&per_cpu(ring_buffer_nohz_lock, cpu)); + lib_ring_buffer_start_switch_timer(buf); + lib_ring_buffer_start_read_timer(buf); + spin_unlock(&per_cpu(ring_buffer_nohz_lock, cpu)); + } + chan->cpu_hp_enable = 1; + put_online_cpus(); +#else + for_each_possible_cpu(cpu) { + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, + cpu); + spin_lock(&per_cpu(ring_buffer_nohz_lock, cpu)); + lib_ring_buffer_start_switch_timer(buf); + lib_ring_buffer_start_read_timer(buf); + spin_unlock(&per_cpu(ring_buffer_nohz_lock, cpu)); + } +#endif + } else { + struct lib_ring_buffer *buf = chan->backend.buf; + + lib_ring_buffer_start_switch_timer(buf); + lib_ring_buffer_start_read_timer(buf); + } + + return chan; + +error_free_backend: + channel_backend_free(&chan->backend); +error: + kfree(chan); + return NULL; +} +EXPORT_SYMBOL_GPL(channel_create); + +static +void channel_release(struct kref *kref) +{ + struct channel *chan = container_of(kref, struct channel, ref); + channel_free(chan); +} + +/** + * channel_destroy - Finalize, wait for q.s. and destroy channel. + * @chan: channel to destroy + * + * Holds cpu hotplug. + * Call "destroy" callback, finalize channels, and then decrement the + * channel reference count. Note that when readers have completed data + * consumption of finalized channels, get_subbuf() will return -ENODATA. + * They should release their handle at that point. Returns the private + * data pointer. + */ +void *channel_destroy(struct channel *chan) +{ + int cpu; + const struct lib_ring_buffer_config *config = chan->backend.config; + void *priv; + + channel_unregister_notifiers(chan); + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + /* + * No need to hold cpu hotplug, because all notifiers have been + * unregistered. + */ + for_each_channel_cpu(cpu, chan) { + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, + cpu); + + if (config->cb.buffer_finalize) + config->cb.buffer_finalize(buf, + chan->backend.priv, + cpu); + if (buf->backend.allocated) + lib_ring_buffer_switch_slow(buf, SWITCH_FLUSH); + /* + * Perform flush before writing to finalized. + */ + smp_wmb(); + ACCESS_ONCE(buf->finalized) = 1; + wake_up_interruptible(&buf->read_wait); + } + } else { + struct lib_ring_buffer *buf = chan->backend.buf; + + if (config->cb.buffer_finalize) + config->cb.buffer_finalize(buf, chan->backend.priv, -1); + if (buf->backend.allocated) + lib_ring_buffer_switch_slow(buf, SWITCH_FLUSH); + /* + * Perform flush before writing to finalized. + */ + smp_wmb(); + ACCESS_ONCE(buf->finalized) = 1; + wake_up_interruptible(&buf->read_wait); + } + ACCESS_ONCE(chan->finalized) = 1; + wake_up_interruptible(&chan->hp_wait); + wake_up_interruptible(&chan->read_wait); + priv = chan->backend.priv; + kref_put(&chan->ref, channel_release); + return priv; +} +EXPORT_SYMBOL_GPL(channel_destroy); + +struct lib_ring_buffer *channel_get_ring_buffer( + const struct lib_ring_buffer_config *config, + struct channel *chan, int cpu) +{ + if (config->alloc == RING_BUFFER_ALLOC_GLOBAL) + return chan->backend.buf; + else + return per_cpu_ptr(chan->backend.buf, cpu); +} +EXPORT_SYMBOL_GPL(channel_get_ring_buffer); + +int lib_ring_buffer_open_read(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + + if (!atomic_long_add_unless(&buf->active_readers, 1, 1)) + return -EBUSY; + kref_get(&chan->ref); + smp_mb__after_atomic_inc(); + return 0; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_open_read); + +void lib_ring_buffer_release_read(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + + CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1); + smp_mb__before_atomic_dec(); + atomic_long_dec(&buf->active_readers); + kref_put(&chan->ref, channel_release); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_release_read); + +/* + * Promote compiler barrier to a smp_mb(). + * For the specific ring buffer case, this IPI call should be removed if the + * architecture does not reorder writes. This should eventually be provided by + * a separate architecture-specific infrastructure. + */ +static void remote_mb(void *info) +{ + smp_mb(); +} + +/** + * lib_ring_buffer_snapshot - save subbuffer position snapshot (for read) + * @buf: ring buffer + * @consumed: consumed count indicating the position where to read + * @produced: produced count, indicates position when to stop reading + * + * Returns -ENODATA if buffer is finalized, -EAGAIN if there is currently no + * data to read at consumed position, or 0 if the get operation succeeds. + * Busy-loop trying to get data if the tick_nohz sequence lock is held. + */ + +int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf, + unsigned long *consumed, unsigned long *produced) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long consumed_cur, write_offset; + int finalized; + +retry: + finalized = ACCESS_ONCE(buf->finalized); + /* + * Read finalized before counters. + */ + smp_rmb(); + consumed_cur = atomic_long_read(&buf->consumed); + /* + * No need to issue a memory barrier between consumed count read and + * write offset read, because consumed count can only change + * concurrently in overwrite mode, and we keep a sequence counter + * identifier derived from the write offset to check we are getting + * the same sub-buffer we are expecting (the sub-buffers are atomically + * "tagged" upon writes, tags are checked upon read). + */ + write_offset = v_read(config, &buf->offset); + + /* + * Check that we are not about to read the same subbuffer in + * which the writer head is. + */ + if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_cur, chan) + == 0) + goto nodata; + + *consumed = consumed_cur; + *produced = subbuf_trunc(write_offset, chan); + + return 0; + +nodata: + /* + * The memory barriers __wait_event()/wake_up_interruptible() take care + * of "raw_spin_is_locked" memory ordering. + */ + if (finalized) + return -ENODATA; + else if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock)) + goto retry; + else + return -EAGAIN; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_snapshot); + +/** + * lib_ring_buffer_put_snapshot - move consumed counter forward + * + * Should only be called from consumer context. + * @buf: ring buffer + * @consumed_new: new consumed count value + */ +void lib_ring_buffer_move_consumer(struct lib_ring_buffer *buf, + unsigned long consumed_new) +{ + struct lib_ring_buffer_backend *bufb = &buf->backend; + struct channel *chan = bufb->chan; + unsigned long consumed; + + CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1); + + /* + * Only push the consumed value forward. + * If the consumed cmpxchg fails, this is because we have been pushed by + * the writer in flight recorder mode. + */ + consumed = atomic_long_read(&buf->consumed); + while ((long) consumed - (long) consumed_new < 0) + consumed = atomic_long_cmpxchg(&buf->consumed, consumed, + consumed_new); + /* Wake-up the metadata producer */ + wake_up_interruptible(&buf->write_wait); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_move_consumer); + +/** + * lib_ring_buffer_get_subbuf - get exclusive access to subbuffer for reading + * @buf: ring buffer + * @consumed: consumed count indicating the position where to read + * + * Returns -ENODATA if buffer is finalized, -EAGAIN if there is currently no + * data to read at consumed position, or 0 if the get operation succeeds. + * Busy-loop trying to get data if the tick_nohz sequence lock is held. + */ +int lib_ring_buffer_get_subbuf(struct lib_ring_buffer *buf, + unsigned long consumed) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long consumed_cur, consumed_idx, commit_count, write_offset; + int ret; + int finalized; + +retry: + finalized = ACCESS_ONCE(buf->finalized); + /* + * Read finalized before counters. + */ + smp_rmb(); + consumed_cur = atomic_long_read(&buf->consumed); + consumed_idx = subbuf_index(consumed, chan); + commit_count = v_read(config, &buf->commit_cold[consumed_idx].cc_sb); + /* + * Make sure we read the commit count before reading the buffer + * data and the write offset. Correct consumed offset ordering + * wrt commit count is insured by the use of cmpxchg to update + * the consumed offset. + * smp_call_function_single can fail if the remote CPU is offline, + * this is OK because then there is no wmb to execute there. + * If our thread is executing on the same CPU as the on the buffers + * belongs to, we don't have to synchronize it at all. If we are + * migrated, the scheduler will take care of the memory barriers. + * Normally, smp_call_function_single() should ensure program order when + * executing the remote function, which implies that it surrounds the + * function execution with : + * smp_mb() + * send IPI + * csd_lock_wait + * recv IPI + * smp_mb() + * exec. function + * smp_mb() + * csd unlock + * smp_mb() + * + * However, smp_call_function_single() does not seem to clearly execute + * such barriers. It depends on spinlock semantic to provide the barrier + * before executing the IPI and, when busy-looping, csd_lock_wait only + * executes smp_mb() when it has to wait for the other CPU. + * + * I don't trust this code. Therefore, let's add the smp_mb() sequence + * required ourself, even if duplicated. It has no performance impact + * anyway. + * + * smp_mb() is needed because smp_rmb() and smp_wmb() only order read vs + * read and write vs write. They do not ensure core synchronization. We + * really have to ensure total order between the 3 barriers running on + * the 2 CPUs. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + if (config->sync == RING_BUFFER_SYNC_PER_CPU + && config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + if (raw_smp_processor_id() != buf->backend.cpu) { + /* Total order with IPI handler smp_mb() */ + smp_mb(); + smp_call_function_single(buf->backend.cpu, + remote_mb, NULL, 1); + /* Total order with IPI handler smp_mb() */ + smp_mb(); + } + } else { + /* Total order with IPI handler smp_mb() */ + smp_mb(); + smp_call_function(remote_mb, NULL, 1); + /* Total order with IPI handler smp_mb() */ + smp_mb(); + } + } else { + /* + * Local rmb to match the remote wmb to read the commit count + * before the buffer data and the write offset. + */ + smp_rmb(); + } + + write_offset = v_read(config, &buf->offset); + + /* + * Check that the buffer we are getting is after or at consumed_cur + * position. + */ + if ((long) subbuf_trunc(consumed, chan) + - (long) subbuf_trunc(consumed_cur, chan) < 0) + goto nodata; + + /* + * Check that the subbuffer we are trying to consume has been + * already fully committed. + */ + if (((commit_count - chan->backend.subbuf_size) + & chan->commit_count_mask) + - (buf_trunc(consumed_cur, chan) + >> chan->backend.num_subbuf_order) + != 0) + goto nodata; + + /* + * Check that we are not about to read the same subbuffer in + * which the writer head is. + */ + if (subbuf_trunc(write_offset, chan) - subbuf_trunc(consumed_cur, chan) + == 0) + goto nodata; + + /* + * Failure to get the subbuffer causes a busy-loop retry without going + * to a wait queue. These are caused by short-lived race windows where + * the writer is getting access to a subbuffer we were trying to get + * access to. Also checks that the "consumed" buffer count we are + * looking for matches the one contained in the subbuffer id. + */ + ret = update_read_sb_index(config, &buf->backend, &chan->backend, + consumed_idx, buf_trunc_val(consumed, chan)); + if (ret) + goto retry; + subbuffer_id_clear_noref(config, &buf->backend.buf_rsb.id); + + buf->get_subbuf_consumed = consumed; + buf->get_subbuf = 1; + + return 0; + +nodata: + /* + * The memory barriers __wait_event()/wake_up_interruptible() take care + * of "raw_spin_is_locked" memory ordering. + */ + if (finalized) + return -ENODATA; + else if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock)) + goto retry; + else + return -EAGAIN; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_get_subbuf); + +/** + * lib_ring_buffer_put_subbuf - release exclusive subbuffer access + * @buf: ring buffer + */ +void lib_ring_buffer_put_subbuf(struct lib_ring_buffer *buf) +{ + struct lib_ring_buffer_backend *bufb = &buf->backend; + struct channel *chan = bufb->chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long read_sb_bindex, consumed_idx, consumed; + + CHAN_WARN_ON(chan, atomic_long_read(&buf->active_readers) != 1); + + if (!buf->get_subbuf) { + /* + * Reader puts a subbuffer it did not get. + */ + CHAN_WARN_ON(chan, 1); + return; + } + consumed = buf->get_subbuf_consumed; + buf->get_subbuf = 0; + + /* + * Clear the records_unread counter. (overruns counter) + * Can still be non-zero if a file reader simply grabbed the data + * without using iterators. + * Can be below zero if an iterator is used on a snapshot more than + * once. + */ + read_sb_bindex = subbuffer_id_get_index(config, bufb->buf_rsb.id); + v_add(config, v_read(config, + &bufb->array[read_sb_bindex]->records_unread), + &bufb->records_read); + v_set(config, &bufb->array[read_sb_bindex]->records_unread, 0); + CHAN_WARN_ON(chan, config->mode == RING_BUFFER_OVERWRITE + && subbuffer_id_is_noref(config, bufb->buf_rsb.id)); + subbuffer_id_set_noref(config, &bufb->buf_rsb.id); + + /* + * Exchange the reader subbuffer with the one we put in its place in the + * writer subbuffer table. Expect the original consumed count. If + * update_read_sb_index fails, this is because the writer updated the + * subbuffer concurrently. We should therefore keep the subbuffer we + * currently have: it has become invalid to try reading this sub-buffer + * consumed count value anyway. + */ + consumed_idx = subbuf_index(consumed, chan); + update_read_sb_index(config, &buf->backend, &chan->backend, + consumed_idx, buf_trunc_val(consumed, chan)); + /* + * update_read_sb_index return value ignored. Don't exchange sub-buffer + * if the writer concurrently updated it. + */ +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_put_subbuf); + +/* + * cons_offset is an iterator on all subbuffer offsets between the reader + * position and the writer position. (inclusive) + */ +static +void lib_ring_buffer_print_subbuffer_errors(struct lib_ring_buffer *buf, + struct channel *chan, + unsigned long cons_offset, + int cpu) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long cons_idx, commit_count, commit_count_sb; + + cons_idx = subbuf_index(cons_offset, chan); + commit_count = v_read(config, &buf->commit_hot[cons_idx].cc); + commit_count_sb = v_read(config, &buf->commit_cold[cons_idx].cc_sb); + + if (subbuf_offset(commit_count, chan) != 0) + printk(KERN_WARNING + "ring buffer %s, cpu %d: " + "commit count in subbuffer %lu,\n" + "expecting multiples of %lu bytes\n" + " [ %lu bytes committed, %lu bytes reader-visible ]\n", + chan->backend.name, cpu, cons_idx, + chan->backend.subbuf_size, + commit_count, commit_count_sb); + + printk(KERN_DEBUG "ring buffer: %s, cpu %d: %lu bytes committed\n", + chan->backend.name, cpu, commit_count); +} + +static +void lib_ring_buffer_print_buffer_errors(struct lib_ring_buffer *buf, + struct channel *chan, + void *priv, int cpu) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long write_offset, cons_offset; + + /* + * Can be called in the error path of allocation when + * trans_channel_data is not yet set. + */ + if (!chan) + return; + /* + * No need to order commit_count, write_offset and cons_offset reads + * because we execute at teardown when no more writer nor reader + * references are left. + */ + write_offset = v_read(config, &buf->offset); + cons_offset = atomic_long_read(&buf->consumed); + if (write_offset != cons_offset) + printk(KERN_DEBUG + "ring buffer %s, cpu %d: " + "non-consumed data\n" + " [ %lu bytes written, %lu bytes read ]\n", + chan->backend.name, cpu, write_offset, cons_offset); + + for (cons_offset = atomic_long_read(&buf->consumed); + (long) (subbuf_trunc((unsigned long) v_read(config, &buf->offset), + chan) + - cons_offset) > 0; + cons_offset = subbuf_align(cons_offset, chan)) + lib_ring_buffer_print_subbuffer_errors(buf, chan, cons_offset, + cpu); +} + +static +void lib_ring_buffer_print_errors(struct channel *chan, + struct lib_ring_buffer *buf, int cpu) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + void *priv = chan->backend.priv; + + printk(KERN_DEBUG "ring buffer %s, cpu %d: %lu records written, " + "%lu records overrun\n", + chan->backend.name, cpu, + v_read(config, &buf->records_count), + v_read(config, &buf->records_overrun)); + + if (v_read(config, &buf->records_lost_full) + || v_read(config, &buf->records_lost_wrap) + || v_read(config, &buf->records_lost_big)) + printk(KERN_WARNING + "ring buffer %s, cpu %d: records were lost. Caused by:\n" + " [ %lu buffer full, %lu nest buffer wrap-around, " + "%lu event too big ]\n", + chan->backend.name, cpu, + v_read(config, &buf->records_lost_full), + v_read(config, &buf->records_lost_wrap), + v_read(config, &buf->records_lost_big)); + + lib_ring_buffer_print_buffer_errors(buf, chan, priv, cpu); +} + +/* + * lib_ring_buffer_switch_old_start: Populate old subbuffer header. + * + * Only executed when the buffer is finalized, in SWITCH_FLUSH. + */ +static +void lib_ring_buffer_switch_old_start(struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + u64 tsc) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long oldidx = subbuf_index(offsets->old, chan); + unsigned long commit_count; + + config->cb.buffer_begin(buf, tsc, oldidx); + + /* + * Order all writes to buffer before the commit count update that will + * determine that the subbuffer is full. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + /* + * Must write slot data before incrementing commit count. This + * compiler barrier is upgraded into a smp_mb() by the IPI sent + * by get_subbuf(). + */ + barrier(); + } else + smp_wmb(); + v_add(config, config->cb.subbuffer_header_size(), + &buf->commit_hot[oldidx].cc); + commit_count = v_read(config, &buf->commit_hot[oldidx].cc); + /* Check if the written buffer has to be delivered */ + lib_ring_buffer_check_deliver(config, buf, chan, offsets->old, + commit_count, oldidx); + lib_ring_buffer_write_commit_counter(config, buf, chan, oldidx, + offsets->old, commit_count, + config->cb.subbuffer_header_size()); +} + +/* + * lib_ring_buffer_switch_old_end: switch old subbuffer + * + * Note : offset_old should never be 0 here. It is ok, because we never perform + * buffer switch on an empty subbuffer in SWITCH_ACTIVE mode. The caller + * increments the offset_old value when doing a SWITCH_FLUSH on an empty + * subbuffer. + */ +static +void lib_ring_buffer_switch_old_end(struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + u64 tsc) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long oldidx = subbuf_index(offsets->old - 1, chan); + unsigned long commit_count, padding_size, data_size; + + data_size = subbuf_offset(offsets->old - 1, chan) + 1; + padding_size = chan->backend.subbuf_size - data_size; + subbuffer_set_data_size(config, &buf->backend, oldidx, data_size); + + /* + * Order all writes to buffer before the commit count update that will + * determine that the subbuffer is full. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + /* + * Must write slot data before incrementing commit count. This + * compiler barrier is upgraded into a smp_mb() by the IPI sent + * by get_subbuf(). + */ + barrier(); + } else + smp_wmb(); + v_add(config, padding_size, &buf->commit_hot[oldidx].cc); + commit_count = v_read(config, &buf->commit_hot[oldidx].cc); + lib_ring_buffer_check_deliver(config, buf, chan, offsets->old - 1, + commit_count, oldidx); + lib_ring_buffer_write_commit_counter(config, buf, chan, oldidx, + offsets->old, commit_count, + padding_size); +} + +/* + * lib_ring_buffer_switch_new_start: Populate new subbuffer. + * + * This code can be executed unordered : writers may already have written to the + * sub-buffer before this code gets executed, caution. The commit makes sure + * that this code is executed before the deliver of this sub-buffer. + */ +static +void lib_ring_buffer_switch_new_start(struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + u64 tsc) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long beginidx = subbuf_index(offsets->begin, chan); + unsigned long commit_count; + + config->cb.buffer_begin(buf, tsc, beginidx); + + /* + * Order all writes to buffer before the commit count update that will + * determine that the subbuffer is full. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + /* + * Must write slot data before incrementing commit count. This + * compiler barrier is upgraded into a smp_mb() by the IPI sent + * by get_subbuf(). + */ + barrier(); + } else + smp_wmb(); + v_add(config, config->cb.subbuffer_header_size(), + &buf->commit_hot[beginidx].cc); + commit_count = v_read(config, &buf->commit_hot[beginidx].cc); + /* Check if the written buffer has to be delivered */ + lib_ring_buffer_check_deliver(config, buf, chan, offsets->begin, + commit_count, beginidx); + lib_ring_buffer_write_commit_counter(config, buf, chan, beginidx, + offsets->begin, commit_count, + config->cb.subbuffer_header_size()); +} + +/* + * lib_ring_buffer_switch_new_end: finish switching current subbuffer + * + * The only remaining threads could be the ones with pending commits. They will + * have to do the deliver themselves. + */ +static +void lib_ring_buffer_switch_new_end(struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + u64 tsc) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long endidx = subbuf_index(offsets->end - 1, chan); + unsigned long commit_count, padding_size, data_size; + + data_size = subbuf_offset(offsets->end - 1, chan) + 1; + padding_size = chan->backend.subbuf_size - data_size; + subbuffer_set_data_size(config, &buf->backend, endidx, data_size); + + /* + * Order all writes to buffer before the commit count update that will + * determine that the subbuffer is full. + */ + if (config->ipi == RING_BUFFER_IPI_BARRIER) { + /* + * Must write slot data before incrementing commit count. This + * compiler barrier is upgraded into a smp_mb() by the IPI sent + * by get_subbuf(). + */ + barrier(); + } else + smp_wmb(); + v_add(config, padding_size, &buf->commit_hot[endidx].cc); + commit_count = v_read(config, &buf->commit_hot[endidx].cc); + lib_ring_buffer_check_deliver(config, buf, chan, offsets->end - 1, + commit_count, endidx); + lib_ring_buffer_write_commit_counter(config, buf, chan, endidx, + offsets->end, commit_count, + padding_size); +} + +/* + * Returns : + * 0 if ok + * !0 if execution must be aborted. + */ +static +int lib_ring_buffer_try_switch_slow(enum switch_mode mode, + struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + u64 *tsc) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long off; + + offsets->begin = v_read(config, &buf->offset); + offsets->old = offsets->begin; + offsets->switch_old_start = 0; + off = subbuf_offset(offsets->begin, chan); + + *tsc = config->cb.ring_buffer_clock_read(chan); + + /* + * Ensure we flush the header of an empty subbuffer when doing the + * finalize (SWITCH_FLUSH). This ensures that we end up knowing the + * total data gathering duration even if there were no records saved + * after the last buffer switch. + * In SWITCH_ACTIVE mode, switch the buffer when it contains events. + * SWITCH_ACTIVE only flushes the current subbuffer, dealing with end of + * subbuffer header as appropriate. + * The next record that reserves space will be responsible for + * populating the following subbuffer header. We choose not to populate + * the next subbuffer header here because we want to be able to use + * SWITCH_ACTIVE for periodical buffer flush and CPU tick_nohz stop + * buffer flush, which must guarantee that all the buffer content + * (records and header timestamps) are visible to the reader. This is + * required for quiescence guarantees for the fusion merge. + */ + if (mode == SWITCH_FLUSH || off > 0) { + if (unlikely(off == 0)) { + /* + * The client does not save any header information. + * Don't switch empty subbuffer on finalize, because it + * is invalid to deliver a completely empty subbuffer. + */ + if (!config->cb.subbuffer_header_size()) + return -1; + /* + * Need to write the subbuffer start header on finalize. + */ + offsets->switch_old_start = 1; + } + offsets->begin = subbuf_align(offsets->begin, chan); + } else + return -1; /* we do not have to switch : buffer is empty */ + /* Note: old points to the next subbuf at offset 0 */ + offsets->end = offsets->begin; + return 0; +} + +/* + * Force a sub-buffer switch. This operation is completely reentrant : can be + * called while tracing is active with absolutely no lock held. + * + * Note, however, that as a v_cmpxchg is used for some atomic + * operations, this function must be called from the CPU which owns the buffer + * for a ACTIVE flush. + */ +void lib_ring_buffer_switch_slow(struct lib_ring_buffer *buf, enum switch_mode mode) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + struct switch_offsets offsets; + unsigned long oldidx; + u64 tsc; + + offsets.size = 0; + + /* + * Perform retryable operations. + */ + do { + if (lib_ring_buffer_try_switch_slow(mode, buf, chan, &offsets, + &tsc)) + return; /* Switch not needed */ + } while (v_cmpxchg(config, &buf->offset, offsets.old, offsets.end) + != offsets.old); + + /* + * Atomically update last_tsc. This update races against concurrent + * atomic updates, but the race will always cause supplementary full TSC + * records, never the opposite (missing a full TSC record when it would + * be needed). + */ + save_last_tsc(config, buf, tsc); + + /* + * Push the reader if necessary + */ + lib_ring_buffer_reserve_push_reader(buf, chan, offsets.old); + + oldidx = subbuf_index(offsets.old, chan); + lib_ring_buffer_clear_noref(config, &buf->backend, oldidx); + + /* + * May need to populate header start on SWITCH_FLUSH. + */ + if (offsets.switch_old_start) { + lib_ring_buffer_switch_old_start(buf, chan, &offsets, tsc); + offsets.old += config->cb.subbuffer_header_size(); + } + + /* + * Switch old subbuffer. + */ + lib_ring_buffer_switch_old_end(buf, chan, &offsets, tsc); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_switch_slow); + +/* + * Returns : + * 0 if ok + * -ENOSPC if event size is too large for packet. + * -ENOBUFS if there is currently not enough space in buffer for the event. + * -EIO if data cannot be written into the buffer for any other reason. + */ +static +int lib_ring_buffer_try_reserve_slow(struct lib_ring_buffer *buf, + struct channel *chan, + struct switch_offsets *offsets, + struct lib_ring_buffer_ctx *ctx) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long reserve_commit_diff; + + offsets->begin = v_read(config, &buf->offset); + offsets->old = offsets->begin; + offsets->switch_new_start = 0; + offsets->switch_new_end = 0; + offsets->switch_old_end = 0; + offsets->pre_header_padding = 0; + + ctx->tsc = config->cb.ring_buffer_clock_read(chan); + if ((int64_t) ctx->tsc == -EIO) + return -EIO; + + if (last_tsc_overflow(config, buf, ctx->tsc)) + ctx->rflags |= RING_BUFFER_RFLAG_FULL_TSC; + + if (unlikely(subbuf_offset(offsets->begin, ctx->chan) == 0)) { + offsets->switch_new_start = 1; /* For offsets->begin */ + } else { + offsets->size = config->cb.record_header_size(config, chan, + offsets->begin, + &offsets->pre_header_padding, + ctx); + offsets->size += + lib_ring_buffer_align(offsets->begin + offsets->size, + ctx->largest_align) + + ctx->data_size; + if (unlikely(subbuf_offset(offsets->begin, chan) + + offsets->size > chan->backend.subbuf_size)) { + offsets->switch_old_end = 1; /* For offsets->old */ + offsets->switch_new_start = 1; /* For offsets->begin */ + } + } + if (unlikely(offsets->switch_new_start)) { + unsigned long sb_index; + + /* + * We are typically not filling the previous buffer completely. + */ + if (likely(offsets->switch_old_end)) + offsets->begin = subbuf_align(offsets->begin, chan); + offsets->begin = offsets->begin + + config->cb.subbuffer_header_size(); + /* Test new buffer integrity */ + sb_index = subbuf_index(offsets->begin, chan); + reserve_commit_diff = + (buf_trunc(offsets->begin, chan) + >> chan->backend.num_subbuf_order) + - ((unsigned long) v_read(config, + &buf->commit_cold[sb_index].cc_sb) + & chan->commit_count_mask); + if (likely(reserve_commit_diff == 0)) { + /* Next subbuffer not being written to. */ + if (unlikely(config->mode != RING_BUFFER_OVERWRITE && + subbuf_trunc(offsets->begin, chan) + - subbuf_trunc((unsigned long) + atomic_long_read(&buf->consumed), chan) + >= chan->backend.buf_size)) { + /* + * We do not overwrite non consumed buffers + * and we are full : record is lost. + */ + v_inc(config, &buf->records_lost_full); + return -ENOBUFS; + } else { + /* + * Next subbuffer not being written to, and we + * are either in overwrite mode or the buffer is + * not full. It's safe to write in this new + * subbuffer. + */ + } + } else { + /* + * Next subbuffer reserve offset does not match the + * commit offset. Drop record in producer-consumer and + * overwrite mode. Caused by either a writer OOPS or too + * many nested writes over a reserve/commit pair. + */ + v_inc(config, &buf->records_lost_wrap); + return -EIO; + } + offsets->size = + config->cb.record_header_size(config, chan, + offsets->begin, + &offsets->pre_header_padding, + ctx); + offsets->size += + lib_ring_buffer_align(offsets->begin + offsets->size, + ctx->largest_align) + + ctx->data_size; + if (unlikely(subbuf_offset(offsets->begin, chan) + + offsets->size > chan->backend.subbuf_size)) { + /* + * Record too big for subbuffers, report error, don't + * complete the sub-buffer switch. + */ + v_inc(config, &buf->records_lost_big); + return -ENOSPC; + } else { + /* + * We just made a successful buffer switch and the + * record fits in the new subbuffer. Let's write. + */ + } + } else { + /* + * Record fits in the current buffer and we are not on a switch + * boundary. It's safe to write. + */ + } + offsets->end = offsets->begin + offsets->size; + + if (unlikely(subbuf_offset(offsets->end, chan) == 0)) { + /* + * The offset_end will fall at the very beginning of the next + * subbuffer. + */ + offsets->switch_new_end = 1; /* For offsets->begin */ + } + return 0; +} + +/** + * lib_ring_buffer_reserve_slow - Atomic slot reservation in a buffer. + * @ctx: ring buffer context. + * + * Return : -NOBUFS if not enough space, -ENOSPC if event size too large, + * -EIO for other errors, else returns 0. + * It will take care of sub-buffer switching. + */ +int lib_ring_buffer_reserve_slow(struct lib_ring_buffer_ctx *ctx) +{ + struct channel *chan = ctx->chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + struct switch_offsets offsets; + int ret; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + buf = per_cpu_ptr(chan->backend.buf, ctx->cpu); + else + buf = chan->backend.buf; + ctx->buf = buf; + + offsets.size = 0; + + do { + ret = lib_ring_buffer_try_reserve_slow(buf, chan, &offsets, + ctx); + if (unlikely(ret)) + return ret; + } while (unlikely(v_cmpxchg(config, &buf->offset, offsets.old, + offsets.end) + != offsets.old)); + + /* + * Atomically update last_tsc. This update races against concurrent + * atomic updates, but the race will always cause supplementary full TSC + * records, never the opposite (missing a full TSC record when it would + * be needed). + */ + save_last_tsc(config, buf, ctx->tsc); + + /* + * Push the reader if necessary + */ + lib_ring_buffer_reserve_push_reader(buf, chan, offsets.end - 1); + + /* + * Clear noref flag for this subbuffer. + */ + lib_ring_buffer_clear_noref(config, &buf->backend, + subbuf_index(offsets.end - 1, chan)); + + /* + * Switch old subbuffer if needed. + */ + if (unlikely(offsets.switch_old_end)) { + lib_ring_buffer_clear_noref(config, &buf->backend, + subbuf_index(offsets.old - 1, chan)); + lib_ring_buffer_switch_old_end(buf, chan, &offsets, ctx->tsc); + } + + /* + * Populate new subbuffer. + */ + if (unlikely(offsets.switch_new_start)) + lib_ring_buffer_switch_new_start(buf, chan, &offsets, ctx->tsc); + + if (unlikely(offsets.switch_new_end)) + lib_ring_buffer_switch_new_end(buf, chan, &offsets, ctx->tsc); + + ctx->slot_size = offsets.size; + ctx->pre_offset = offsets.begin; + ctx->buf_offset = offsets.begin + offsets.pre_header_padding; + return 0; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_reserve_slow); + +int __init init_lib_ring_buffer_frontend(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + spin_lock_init(&per_cpu(ring_buffer_nohz_lock, cpu)); + return 0; +} + +module_init(init_lib_ring_buffer_frontend); + +void __exit exit_lib_ring_buffer_frontend(void) +{ +} + +module_exit(exit_lib_ring_buffer_frontend); diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c new file mode 100644 index 0000000..1321b5f --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_iterator.c @@ -0,0 +1,798 @@ +/* + * ring_buffer_iterator.c + * + * (C) Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring buffer and channel iterators. Get each event of a channel in order. Uses + * a prio heap for per-cpu buffers, giving a O(log(NR_CPUS)) algorithmic + * complexity for the "get next event" operation. + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "../../wrapper/ringbuffer/iterator.h" +#include <linux/jiffies.h> +#include <linux/delay.h> +#include <linux/module.h> + +/* + * Safety factor taking into account internal kernel interrupt latency. + * Assuming 250ms worse-case latency. + */ +#define MAX_SYSTEM_LATENCY 250 + +/* + * Maximum delta expected between trace clocks. At most 1 jiffy delta. + */ +#define MAX_CLOCK_DELTA (jiffies_to_usecs(1) * 1000) + +/** + * lib_ring_buffer_get_next_record - Get the next record in a buffer. + * @chan: channel + * @buf: buffer + * + * Returns the size of the event read, -EAGAIN if buffer is empty, -ENODATA if + * buffer is empty and finalized. The buffer must already be opened for reading. + */ +ssize_t lib_ring_buffer_get_next_record(struct channel *chan, + struct lib_ring_buffer *buf) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer_iter *iter = &buf->iter; + int ret; + +restart: + switch (iter->state) { + case ITER_GET_SUBBUF: + ret = lib_ring_buffer_get_next_subbuf(buf); + if (ret && !ACCESS_ONCE(buf->finalized) + && config->alloc == RING_BUFFER_ALLOC_GLOBAL) { + /* + * Use "pull" scheme for global buffers. The reader + * itself flushes the buffer to "pull" data not visible + * to readers yet. Flush current subbuffer and re-try. + * + * Per-CPU buffers rather use a "push" scheme because + * the IPI needed to flush all CPU's buffers is too + * costly. In the "push" scheme, the reader waits for + * the writer periodic deferrable timer to flush the + * buffers (keeping track of a quiescent state + * timestamp). Therefore, the writer "pushes" data out + * of the buffers rather than letting the reader "pull" + * data from the buffer. + */ + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + ret = lib_ring_buffer_get_next_subbuf(buf); + } + if (ret) + return ret; + iter->consumed = buf->cons_snapshot; + iter->data_size = lib_ring_buffer_get_read_data_size(config, buf); + iter->read_offset = iter->consumed; + /* skip header */ + iter->read_offset += config->cb.subbuffer_header_size(); + iter->state = ITER_TEST_RECORD; + goto restart; + case ITER_TEST_RECORD: + if (iter->read_offset - iter->consumed >= iter->data_size) { + iter->state = ITER_PUT_SUBBUF; + } else { + CHAN_WARN_ON(chan, !config->cb.record_get); + config->cb.record_get(config, chan, buf, + iter->read_offset, + &iter->header_len, + &iter->payload_len, + &iter->timestamp); + iter->read_offset += iter->header_len; + subbuffer_consume_record(config, &buf->backend); + iter->state = ITER_NEXT_RECORD; + return iter->payload_len; + } + goto restart; + case ITER_NEXT_RECORD: + iter->read_offset += iter->payload_len; + iter->state = ITER_TEST_RECORD; + goto restart; + case ITER_PUT_SUBBUF: + lib_ring_buffer_put_next_subbuf(buf); + iter->state = ITER_GET_SUBBUF; + goto restart; + default: + CHAN_WARN_ON(chan, 1); /* Should not happen */ + return -EPERM; + } +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_get_next_record); + +static int buf_is_higher(void *a, void *b) +{ + struct lib_ring_buffer *bufa = a; + struct lib_ring_buffer *bufb = b; + + /* Consider lowest timestamps to be at the top of the heap */ + return (bufa->iter.timestamp < bufb->iter.timestamp); +} + +static +void lib_ring_buffer_get_empty_buf_records(const struct lib_ring_buffer_config *config, + struct channel *chan) +{ + struct lttng_ptr_heap *heap = &chan->iter.heap; + struct lib_ring_buffer *buf, *tmp; + ssize_t len; + + list_for_each_entry_safe(buf, tmp, &chan->iter.empty_head, + iter.empty_node) { + len = lib_ring_buffer_get_next_record(chan, buf); + + /* + * Deal with -EAGAIN and -ENODATA. + * len >= 0 means record contains data. + * -EBUSY should never happen, because we support only one + * reader. + */ + switch (len) { + case -EAGAIN: + /* Keep node in empty list */ + break; + case -ENODATA: + /* + * Buffer is finalized. Don't add to list of empty + * buffer, because it has no more data to provide, ever. + */ + list_del(&buf->iter.empty_node); + break; + case -EBUSY: + CHAN_WARN_ON(chan, 1); + break; + default: + /* + * Insert buffer into the heap, remove from empty buffer + * list. + */ + CHAN_WARN_ON(chan, len < 0); + list_del(&buf->iter.empty_node); + CHAN_WARN_ON(chan, lttng_heap_insert(heap, buf)); + } + } +} + +static +void lib_ring_buffer_wait_for_qs(const struct lib_ring_buffer_config *config, + struct channel *chan) +{ + u64 timestamp_qs; + unsigned long wait_msecs; + + /* + * No need to wait if no empty buffers are present. + */ + if (list_empty(&chan->iter.empty_head)) + return; + + timestamp_qs = config->cb.ring_buffer_clock_read(chan); + /* + * We need to consider previously empty buffers. + * Do a get next buf record on each of them. Add them to + * the heap if they have data. If at least one of them + * don't have data, we need to wait for + * switch_timer_interval + MAX_SYSTEM_LATENCY (so we are sure the + * buffers have been switched either by the timer or idle entry) and + * check them again, adding them if they have data. + */ + lib_ring_buffer_get_empty_buf_records(config, chan); + + /* + * No need to wait if no empty buffers are present. + */ + if (list_empty(&chan->iter.empty_head)) + return; + + /* + * We need to wait for the buffer switch timer to run. If the + * CPU is idle, idle entry performed the switch. + * TODO: we could optimize further by skipping the sleep if all + * empty buffers belong to idle or offline cpus. + */ + wait_msecs = jiffies_to_msecs(chan->switch_timer_interval); + wait_msecs += MAX_SYSTEM_LATENCY; + msleep(wait_msecs); + lib_ring_buffer_get_empty_buf_records(config, chan); + /* + * Any buffer still in the empty list here cannot possibly + * contain an event with a timestamp prior to "timestamp_qs". + * The new quiescent state timestamp is the one we grabbed + * before waiting for buffer data. It is therefore safe to + * ignore empty buffers up to last_qs timestamp for fusion + * merge. + */ + chan->iter.last_qs = timestamp_qs; +} + +/** + * channel_get_next_record - Get the next record in a channel. + * @chan: channel + * @ret_buf: the buffer in which the event is located (output) + * + * Returns the size of new current event, -EAGAIN if all buffers are empty, + * -ENODATA if all buffers are empty and finalized. The channel must already be + * opened for reading. + */ + +ssize_t channel_get_next_record(struct channel *chan, + struct lib_ring_buffer **ret_buf) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + struct lttng_ptr_heap *heap; + ssize_t len; + + if (config->alloc == RING_BUFFER_ALLOC_GLOBAL) { + *ret_buf = channel_get_ring_buffer(config, chan, 0); + return lib_ring_buffer_get_next_record(chan, *ret_buf); + } + + heap = &chan->iter.heap; + + /* + * get next record for topmost buffer. + */ + buf = lttng_heap_maximum(heap); + if (buf) { + len = lib_ring_buffer_get_next_record(chan, buf); + /* + * Deal with -EAGAIN and -ENODATA. + * len >= 0 means record contains data. + */ + switch (len) { + case -EAGAIN: + buf->iter.timestamp = 0; + list_add(&buf->iter.empty_node, &chan->iter.empty_head); + /* Remove topmost buffer from the heap */ + CHAN_WARN_ON(chan, lttng_heap_remove(heap) != buf); + break; + case -ENODATA: + /* + * Buffer is finalized. Remove buffer from heap and + * don't add to list of empty buffer, because it has no + * more data to provide, ever. + */ + CHAN_WARN_ON(chan, lttng_heap_remove(heap) != buf); + break; + case -EBUSY: + CHAN_WARN_ON(chan, 1); + break; + default: + /* + * Reinsert buffer into the heap. Note that heap can be + * partially empty, so we need to use + * lttng_heap_replace_max(). + */ + CHAN_WARN_ON(chan, len < 0); + CHAN_WARN_ON(chan, lttng_heap_replace_max(heap, buf) != buf); + break; + } + } + + buf = lttng_heap_maximum(heap); + if (!buf || buf->iter.timestamp > chan->iter.last_qs) { + /* + * Deal with buffers previously showing no data. + * Add buffers containing data to the heap, update + * last_qs. + */ + lib_ring_buffer_wait_for_qs(config, chan); + } + + *ret_buf = buf = lttng_heap_maximum(heap); + if (buf) { + /* + * If this warning triggers, you probably need to check your + * system interrupt latency. Typical causes: too many printk() + * output going to a serial console with interrupts off. + * Allow for MAX_CLOCK_DELTA ns timestamp delta going backward. + * Observed on SMP KVM setups with trace_clock(). + */ + if (chan->iter.last_timestamp + > (buf->iter.timestamp + MAX_CLOCK_DELTA)) { + printk(KERN_WARNING "ring_buffer: timestamps going " + "backward. Last time %llu ns, cpu %d, " + "current time %llu ns, cpu %d, " + "delta %llu ns.\n", + chan->iter.last_timestamp, chan->iter.last_cpu, + buf->iter.timestamp, buf->backend.cpu, + chan->iter.last_timestamp - buf->iter.timestamp); + CHAN_WARN_ON(chan, 1); + } + chan->iter.last_timestamp = buf->iter.timestamp; + chan->iter.last_cpu = buf->backend.cpu; + return buf->iter.payload_len; + } else { + /* Heap is empty */ + if (list_empty(&chan->iter.empty_head)) + return -ENODATA; /* All buffers finalized */ + else + return -EAGAIN; /* Temporarily empty */ + } +} +EXPORT_SYMBOL_GPL(channel_get_next_record); + +static +void lib_ring_buffer_iterator_init(struct channel *chan, struct lib_ring_buffer *buf) +{ + if (buf->iter.allocated) + return; + + buf->iter.allocated = 1; + if (chan->iter.read_open && !buf->iter.read_open) { + CHAN_WARN_ON(chan, lib_ring_buffer_open_read(buf) != 0); + buf->iter.read_open = 1; + } + + /* Add to list of buffers without any current record */ + if (chan->backend.config->alloc == RING_BUFFER_ALLOC_PER_CPU) + list_add(&buf->iter.empty_node, &chan->iter.empty_head); +} + +#ifdef CONFIG_HOTPLUG_CPU +static +int __cpuinit channel_iterator_cpu_hotplug(struct notifier_block *nb, + unsigned long action, + void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct channel *chan = container_of(nb, struct channel, + hp_iter_notifier); + struct lib_ring_buffer *buf = per_cpu_ptr(chan->backend.buf, cpu); + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (!chan->hp_iter_enable) + return NOTIFY_DONE; + + CHAN_WARN_ON(chan, config->alloc == RING_BUFFER_ALLOC_GLOBAL); + + switch (action) { + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + lib_ring_buffer_iterator_init(chan, buf); + return NOTIFY_OK; + default: + return NOTIFY_DONE; + } +} +#endif + +int channel_iterator_init(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + int cpu, ret; + + INIT_LIST_HEAD(&chan->iter.empty_head); + ret = lttng_heap_init(&chan->iter.heap, + num_possible_cpus(), + GFP_KERNEL, buf_is_higher); + if (ret) + return ret; + /* + * In case of non-hotplug cpu, if the ring-buffer is allocated + * in early initcall, it will not be notified of secondary cpus. + * In that off case, we need to allocate for all possible cpus. + */ +#ifdef CONFIG_HOTPLUG_CPU + chan->hp_iter_notifier.notifier_call = + channel_iterator_cpu_hotplug; + chan->hp_iter_notifier.priority = 10; + register_cpu_notifier(&chan->hp_iter_notifier); + get_online_cpus(); + for_each_online_cpu(cpu) { + buf = per_cpu_ptr(chan->backend.buf, cpu); + lib_ring_buffer_iterator_init(chan, buf); + } + chan->hp_iter_enable = 1; + put_online_cpus(); +#else + for_each_possible_cpu(cpu) { + buf = per_cpu_ptr(chan->backend.buf, cpu); + lib_ring_buffer_iterator_init(chan, buf); + } +#endif + } else { + buf = channel_get_ring_buffer(config, chan, 0); + lib_ring_buffer_iterator_init(chan, buf); + } + return 0; +} + +void channel_iterator_unregister_notifiers(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + chan->hp_iter_enable = 0; + unregister_cpu_notifier(&chan->hp_iter_notifier); + } +} + +void channel_iterator_free(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + lttng_heap_free(&chan->iter.heap); +} + +int lib_ring_buffer_iterator_open(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + CHAN_WARN_ON(chan, config->output != RING_BUFFER_ITERATOR); + return lib_ring_buffer_open_read(buf); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_iterator_open); + +/* + * Note: Iterators must not be mixed with other types of outputs, because an + * iterator can leave the buffer in "GET" state, which is not consistent with + * other types of output (mmap, splice, raw data read). + */ +void lib_ring_buffer_iterator_release(struct lib_ring_buffer *buf) +{ + lib_ring_buffer_release_read(buf); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_iterator_release); + +int channel_iterator_open(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + int ret = 0, cpu; + + CHAN_WARN_ON(chan, config->output != RING_BUFFER_ITERATOR); + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + get_online_cpus(); + /* Allow CPU hotplug to keep track of opened reader */ + chan->iter.read_open = 1; + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(config, chan, cpu); + ret = lib_ring_buffer_iterator_open(buf); + if (ret) + goto error; + buf->iter.read_open = 1; + } + put_online_cpus(); + } else { + buf = channel_get_ring_buffer(config, chan, 0); + ret = lib_ring_buffer_iterator_open(buf); + } + return ret; +error: + /* Error should always happen on CPU 0, hence no close is required. */ + CHAN_WARN_ON(chan, cpu != 0); + put_online_cpus(); + return ret; +} +EXPORT_SYMBOL_GPL(channel_iterator_open); + +void channel_iterator_release(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + int cpu; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) { + get_online_cpus(); + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(config, chan, cpu); + if (buf->iter.read_open) { + lib_ring_buffer_iterator_release(buf); + buf->iter.read_open = 0; + } + } + chan->iter.read_open = 0; + put_online_cpus(); + } else { + buf = channel_get_ring_buffer(config, chan, 0); + lib_ring_buffer_iterator_release(buf); + } +} +EXPORT_SYMBOL_GPL(channel_iterator_release); + +void lib_ring_buffer_iterator_reset(struct lib_ring_buffer *buf) +{ + struct channel *chan = buf->backend.chan; + + if (buf->iter.state != ITER_GET_SUBBUF) + lib_ring_buffer_put_next_subbuf(buf); + buf->iter.state = ITER_GET_SUBBUF; + /* Remove from heap (if present). */ + if (lttng_heap_cherrypick(&chan->iter.heap, buf)) + list_add(&buf->iter.empty_node, &chan->iter.empty_head); + buf->iter.timestamp = 0; + buf->iter.header_len = 0; + buf->iter.payload_len = 0; + buf->iter.consumed = 0; + buf->iter.read_offset = 0; + buf->iter.data_size = 0; + /* Don't reset allocated and read_open */ +} + +void channel_iterator_reset(struct channel *chan) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + struct lib_ring_buffer *buf; + int cpu; + + /* Empty heap, put into empty_head */ + while ((buf = lttng_heap_remove(&chan->iter.heap)) != NULL) + list_add(&buf->iter.empty_node, &chan->iter.empty_head); + + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(config, chan, cpu); + lib_ring_buffer_iterator_reset(buf); + } + /* Don't reset read_open */ + chan->iter.last_qs = 0; + chan->iter.last_timestamp = 0; + chan->iter.last_cpu = 0; + chan->iter.len_left = 0; +} + +/* + * Ring buffer payload extraction read() implementation. + */ +static +ssize_t channel_ring_buffer_file_read(struct file *filp, + char __user *user_buf, + size_t count, + loff_t *ppos, + struct channel *chan, + struct lib_ring_buffer *buf, + int fusionmerge) +{ + const struct lib_ring_buffer_config *config = chan->backend.config; + size_t read_count = 0, read_offset; + ssize_t len; + + might_sleep(); + if (!access_ok(VERIFY_WRITE, user_buf, count)) + return -EFAULT; + + /* Finish copy of previous record */ + if (*ppos != 0) { + if (read_count < count) { + len = chan->iter.len_left; + read_offset = *ppos; + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU + && fusionmerge) + buf = lttng_heap_maximum(&chan->iter.heap); + CHAN_WARN_ON(chan, !buf); + goto skip_get_next; + } + } + + while (read_count < count) { + size_t copy_len, space_left; + + if (fusionmerge) + len = channel_get_next_record(chan, &buf); + else + len = lib_ring_buffer_get_next_record(chan, buf); +len_test: + if (len < 0) { + /* + * Check if buffer is finalized (end of file). + */ + if (len == -ENODATA) { + /* A 0 read_count will tell about end of file */ + goto nodata; + } + if (filp->f_flags & O_NONBLOCK) { + if (!read_count) + read_count = -EAGAIN; + goto nodata; + } else { + int error; + + /* + * No data available at the moment, return what + * we got. + */ + if (read_count) + goto nodata; + + /* + * Wait for returned len to be >= 0 or -ENODATA. + */ + if (fusionmerge) + error = wait_event_interruptible( + chan->read_wait, + ((len = channel_get_next_record(chan, + &buf)), len != -EAGAIN)); + else + error = wait_event_interruptible( + buf->read_wait, + ((len = lib_ring_buffer_get_next_record( + chan, buf)), len != -EAGAIN)); + CHAN_WARN_ON(chan, len == -EBUSY); + if (error) { + read_count = error; + goto nodata; + } + CHAN_WARN_ON(chan, len < 0 && len != -ENODATA); + goto len_test; + } + } + read_offset = buf->iter.read_offset; +skip_get_next: + space_left = count - read_count; + if (len <= space_left) { + copy_len = len; + chan->iter.len_left = 0; + *ppos = 0; + } else { + copy_len = space_left; + chan->iter.len_left = len - copy_len; + *ppos = read_offset + copy_len; + } + if (__lib_ring_buffer_copy_to_user(&buf->backend, read_offset, + &user_buf[read_count], + copy_len)) { + /* + * Leave the len_left and ppos values at their current + * state, as we currently have a valid event to read. + */ + return -EFAULT; + } + read_count += copy_len; + }; + return read_count; + +nodata: + *ppos = 0; + chan->iter.len_left = 0; + return read_count; +} + +/** + * lib_ring_buffer_file_read - Read buffer record payload. + * @filp: file structure pointer. + * @buffer: user buffer to read data into. + * @count: number of bytes to read. + * @ppos: file read position. + * + * Returns a negative value on error, or the number of bytes read on success. + * ppos is used to save the position _within the current record_ between calls + * to read(). + */ +static +ssize_t lib_ring_buffer_file_read(struct file *filp, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct inode *inode = filp->f_dentry->d_inode; + struct lib_ring_buffer *buf = inode->i_private; + struct channel *chan = buf->backend.chan; + + return channel_ring_buffer_file_read(filp, user_buf, count, ppos, + chan, buf, 0); +} + +/** + * channel_file_read - Read channel record payload. + * @filp: file structure pointer. + * @buffer: user buffer to read data into. + * @count: number of bytes to read. + * @ppos: file read position. + * + * Returns a negative value on error, or the number of bytes read on success. + * ppos is used to save the position _within the current record_ between calls + * to read(). + */ +static +ssize_t channel_file_read(struct file *filp, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct inode *inode = filp->f_dentry->d_inode; + struct channel *chan = inode->i_private; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (config->alloc == RING_BUFFER_ALLOC_PER_CPU) + return channel_ring_buffer_file_read(filp, user_buf, count, + ppos, chan, NULL, 1); + else { + struct lib_ring_buffer *buf = + channel_get_ring_buffer(config, chan, 0); + return channel_ring_buffer_file_read(filp, user_buf, count, + ppos, chan, buf, 0); + } +} + +static +int lib_ring_buffer_file_open(struct inode *inode, struct file *file) +{ + struct lib_ring_buffer *buf = inode->i_private; + int ret; + + ret = lib_ring_buffer_iterator_open(buf); + if (ret) + return ret; + + file->private_data = buf; + ret = nonseekable_open(inode, file); + if (ret) + goto release_iter; + return 0; + +release_iter: + lib_ring_buffer_iterator_release(buf); + return ret; +} + +static +int lib_ring_buffer_file_release(struct inode *inode, struct file *file) +{ + struct lib_ring_buffer *buf = inode->i_private; + + lib_ring_buffer_iterator_release(buf); + return 0; +} + +static +int channel_file_open(struct inode *inode, struct file *file) +{ + struct channel *chan = inode->i_private; + int ret; + + ret = channel_iterator_open(chan); + if (ret) + return ret; + + file->private_data = chan; + ret = nonseekable_open(inode, file); + if (ret) + goto release_iter; + return 0; + +release_iter: + channel_iterator_release(chan); + return ret; +} + +static +int channel_file_release(struct inode *inode, struct file *file) +{ + struct channel *chan = inode->i_private; + + channel_iterator_release(chan); + return 0; +} + +const struct file_operations channel_payload_file_operations = { + .owner = THIS_MODULE, + .open = channel_file_open, + .release = channel_file_release, + .read = channel_file_read, + .llseek = lib_ring_buffer_no_llseek, +}; +EXPORT_SYMBOL_GPL(channel_payload_file_operations); + +const struct file_operations lib_ring_buffer_payload_file_operations = { + .owner = THIS_MODULE, + .open = lib_ring_buffer_file_open, + .release = lib_ring_buffer_file_release, + .read = lib_ring_buffer_file_read, + .llseek = lib_ring_buffer_no_llseek, +}; +EXPORT_SYMBOL_GPL(lib_ring_buffer_payload_file_operations); diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c new file mode 100644 index 0000000..68221ee --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_mmap.c @@ -0,0 +1,115 @@ +/* + * ring_buffer_mmap.c + * + * Copyright (C) 2002-2005 - Tom Zanussi <zanussi at us.ibm.com>, IBM Corp + * Copyright (C) 1999-2005 - Karim Yaghmour <karim at opersys.com> + * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Re-using content from kernel/relay.c. + * + * This file is released under the GPL v2. + */ + +#include <linux/module.h> +#include <linux/mm.h> + +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" +#include "../../wrapper/ringbuffer/vfs.h" + +/* + * fault() vm_op implementation for ring buffer file mapping. + */ +static int lib_ring_buffer_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct lib_ring_buffer *buf = vma->vm_private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + pgoff_t pgoff = vmf->pgoff; + struct page **page; + void **virt; + unsigned long offset, sb_bindex; + + if (!buf) + return VM_FAULT_OOM; + + /* + * Verify that faults are only done on the range of pages owned by the + * reader. + */ + offset = pgoff << PAGE_SHIFT; + sb_bindex = subbuffer_id_get_index(config, buf->backend.buf_rsb.id); + if (!(offset >= buf->backend.array[sb_bindex]->mmap_offset + && offset < buf->backend.array[sb_bindex]->mmap_offset + + buf->backend.chan->backend.subbuf_size)) + return VM_FAULT_SIGBUS; + /* + * ring_buffer_read_get_page() gets the page in the current reader's + * pages. + */ + page = lib_ring_buffer_read_get_page(&buf->backend, offset, &virt); + if (!*page) + return VM_FAULT_SIGBUS; + get_page(*page); + vmf->page = *page; + + return 0; +} + +/* + * vm_ops for ring buffer file mappings. + */ +static const struct vm_operations_struct lib_ring_buffer_mmap_ops = { + .fault = lib_ring_buffer_fault, +}; + +/** + * lib_ring_buffer_mmap_buf: - mmap channel buffer to process address space + * @buf: ring buffer to map + * @vma: vm_area_struct describing memory to be mapped + * + * Returns 0 if ok, negative on error + * + * Caller should already have grabbed mmap_sem. + */ +static int lib_ring_buffer_mmap_buf(struct lib_ring_buffer *buf, + struct vm_area_struct *vma) +{ + unsigned long length = vma->vm_end - vma->vm_start; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned long mmap_buf_len; + + if (config->output != RING_BUFFER_MMAP) + return -EINVAL; + + if (!buf) + return -EBADF; + + mmap_buf_len = chan->backend.buf_size; + if (chan->backend.extra_reader_sb) + mmap_buf_len += chan->backend.subbuf_size; + + if (length != mmap_buf_len) + return -EINVAL; + + vma->vm_ops = &lib_ring_buffer_mmap_ops; + vma->vm_flags |= VM_DONTEXPAND; + vma->vm_private_data = buf; + + return 0; +} + +/** + * lib_ring_buffer_mmap - mmap file op + * @filp: the file + * @vma: the vma describing what to map + * + * Calls upon lib_ring_buffer_mmap_buf() to map the file into user space. + */ +int lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct lib_ring_buffer *buf = filp->private_data; + return lib_ring_buffer_mmap_buf(buf, vma); +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_mmap); diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c new file mode 100644 index 0000000..ded18ba --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_splice.c @@ -0,0 +1,202 @@ +/* + * ring_buffer_splice.c + * + * Copyright (C) 2002-2005 - Tom Zanussi <zanussi at us.ibm.com>, IBM Corp + * Copyright (C) 1999-2005 - Karim Yaghmour <karim at opersys.com> + * Copyright (C) 2008-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Re-using content from kernel/relay.c. + * + * This file is released under the GPL v2. + */ + +#include <linux/module.h> +#include <linux/fs.h> + +#include "../../wrapper/splice.h" +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" +#include "../../wrapper/ringbuffer/vfs.h" + +#if 0 +#define printk_dbg(fmt, args...) printk(fmt, args) +#else +#define printk_dbg(fmt, args...) +#endif + +loff_t lib_ring_buffer_no_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* + * Release pages from the buffer so splice pipe_to_file can move them. + * Called after the pipe has been populated with buffer pages. + */ +static void lib_ring_buffer_pipe_buf_release(struct pipe_inode_info *pipe, + struct pipe_buffer *pbuf) +{ + __free_page(pbuf->page); +} + +static const struct pipe_buf_operations ring_buffer_pipe_buf_ops = { + .can_merge = 0, + .map = generic_pipe_buf_map, + .unmap = generic_pipe_buf_unmap, + .confirm = generic_pipe_buf_confirm, + .release = lib_ring_buffer_pipe_buf_release, + .steal = generic_pipe_buf_steal, + .get = generic_pipe_buf_get, +}; + +/* + * Page release operation after splice pipe_to_file ends. + */ +static void lib_ring_buffer_page_release(struct splice_pipe_desc *spd, + unsigned int i) +{ + __free_page(spd->pages[i]); +} + +/* + * subbuf_splice_actor - splice up to one subbuf's worth of data + */ +static int subbuf_splice_actor(struct file *in, + loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, + unsigned int flags) +{ + struct lib_ring_buffer *buf = in->private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + unsigned int poff, subbuf_pages, nr_pages; + struct page *pages[PIPE_DEF_BUFFERS]; + struct partial_page partial[PIPE_DEF_BUFFERS]; + struct splice_pipe_desc spd = { + .pages = pages, + .nr_pages = 0, + .partial = partial, + .flags = flags, + .ops = &ring_buffer_pipe_buf_ops, + .spd_release = lib_ring_buffer_page_release, + }; + unsigned long consumed_old, roffset; + unsigned long bytes_avail; + + /* + * Check that a GET_SUBBUF ioctl has been done before. + */ + WARN_ON(atomic_long_read(&buf->active_readers) != 1); + consumed_old = lib_ring_buffer_get_consumed(config, buf); + consumed_old += *ppos; + + /* + * Adjust read len, if longer than what is available. + * Max read size is 1 subbuffer due to get_subbuf/put_subbuf for + * protection. + */ + bytes_avail = chan->backend.subbuf_size; + WARN_ON(bytes_avail > chan->backend.buf_size); + len = min_t(size_t, len, bytes_avail); + subbuf_pages = bytes_avail >> PAGE_SHIFT; + nr_pages = min_t(unsigned int, subbuf_pages, PIPE_DEF_BUFFERS); + roffset = consumed_old & PAGE_MASK; + poff = consumed_old & ~PAGE_MASK; + printk_dbg(KERN_DEBUG "SPLICE actor len %zu pos %zd write_pos %ld\n", + len, (ssize_t)*ppos, lib_ring_buffer_get_offset(config, buf)); + + for (; spd.nr_pages < nr_pages; spd.nr_pages++) { + unsigned int this_len; + struct page **page, *new_page; + void **virt; + + if (!len) + break; + printk_dbg(KERN_DEBUG "SPLICE actor loop len %zu roffset %ld\n", + len, roffset); + + /* + * We have to replace the page we are moving into the splice + * pipe. + */ + new_page = alloc_pages_node(cpu_to_node(max(buf->backend.cpu, + 0)), + GFP_KERNEL | __GFP_ZERO, 0); + if (!new_page) + break; + + this_len = PAGE_SIZE - poff; + page = lib_ring_buffer_read_get_page(&buf->backend, roffset, &virt); + spd.pages[spd.nr_pages] = *page; + *page = new_page; + *virt = page_address(new_page); + spd.partial[spd.nr_pages].offset = poff; + spd.partial[spd.nr_pages].len = this_len; + + poff = 0; + roffset += PAGE_SIZE; + len -= this_len; + } + + if (!spd.nr_pages) + return 0; + + return wrapper_splice_to_pipe(pipe, &spd); +} + +ssize_t lib_ring_buffer_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + struct lib_ring_buffer *buf = in->private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + ssize_t spliced; + int ret; + + if (config->output != RING_BUFFER_SPLICE) + return -EINVAL; + + /* + * We require ppos and length to be page-aligned for performance reasons + * (no page copy). Size is known using the ioctl + * RING_BUFFER_GET_PADDED_SUBBUF_SIZE, which is page-size padded. + * We fail when the ppos or len passed is not page-sized, because splice + * is not allowed to copy more than the length passed as parameter (so + * the ABI does not let us silently copy more than requested to include + * padding). + */ + if (*ppos != PAGE_ALIGN(*ppos) || len != PAGE_ALIGN(len)) + return -EINVAL; + + ret = 0; + spliced = 0; + + printk_dbg(KERN_DEBUG "SPLICE read len %zu pos %zd\n", len, + (ssize_t)*ppos); + while (len && !spliced) { + ret = subbuf_splice_actor(in, ppos, pipe, len, flags); + printk_dbg(KERN_DEBUG "SPLICE read loop ret %d\n", ret); + if (ret < 0) + break; + else if (!ret) { + if (flags & SPLICE_F_NONBLOCK) + ret = -EAGAIN; + break; + } + + *ppos += ret; + if (ret > len) + len = 0; + else + len -= ret; + spliced += ret; + } + + if (spliced) + return spliced; + + return ret; +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_splice_read); diff --git a/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c new file mode 100644 index 0000000..1708ffd --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/ring_buffer_vfs.c @@ -0,0 +1,387 @@ +/* + * ring_buffer_vfs.c + * + * Copyright (C) 2009-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Ring Buffer VFS file operations. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/compat.h> + +#include "../../wrapper/ringbuffer/backend.h" +#include "../../wrapper/ringbuffer/frontend.h" +#include "../../wrapper/ringbuffer/vfs.h" +#include "../../wrapper/poll.h" + +static int put_ulong(unsigned long val, unsigned long arg) +{ + return put_user(val, (unsigned long __user *)arg); +} + +#ifdef CONFIG_COMPAT +static int compat_put_ulong(compat_ulong_t val, unsigned long arg) +{ + return put_user(val, (compat_ulong_t __user *)compat_ptr(arg)); +} +#endif + +/** + * lib_ring_buffer_open - ring buffer open file operation + * @inode: opened inode + * @file: opened file + * + * Open implementation. Makes sure only one open instance of a buffer is + * done at a given moment. + */ +int lib_ring_buffer_open(struct inode *inode, struct file *file) +{ + struct lib_ring_buffer *buf = inode->i_private; + int ret; + + ret = lib_ring_buffer_open_read(buf); + if (ret) + return ret; + + file->private_data = buf; + ret = nonseekable_open(inode, file); + if (ret) + goto release_read; + return 0; + +release_read: + lib_ring_buffer_release_read(buf); + return ret; +} + +/** + * lib_ring_buffer_release - ring buffer release file operation + * @inode: opened inode + * @file: opened file + * + * Release implementation. + */ +int lib_ring_buffer_release(struct inode *inode, struct file *file) +{ + struct lib_ring_buffer *buf = file->private_data; + + lib_ring_buffer_release_read(buf); + + return 0; +} + +/** + * lib_ring_buffer_poll - ring buffer poll file operation + * @filp: the file + * @wait: poll table + * + * Poll implementation. + */ +unsigned int lib_ring_buffer_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + struct lib_ring_buffer *buf = filp->private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + int finalized, disabled; + + if (filp->f_mode & FMODE_READ) { + poll_wait_set_exclusive(wait); + poll_wait(filp, &buf->read_wait, wait); + + finalized = lib_ring_buffer_is_finalized(config, buf); + disabled = lib_ring_buffer_channel_is_disabled(chan); + + /* + * lib_ring_buffer_is_finalized() contains a smp_rmb() ordering + * finalized load before offsets loads. + */ + WARN_ON(atomic_long_read(&buf->active_readers) != 1); +retry: + if (disabled) + return POLLERR; + + if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf), chan) + - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf), chan) + == 0) { + if (finalized) + return POLLHUP; + else { + /* + * The memory barriers + * __wait_event()/wake_up_interruptible() take + * care of "raw_spin_is_locked" memory ordering. + */ + if (raw_spin_is_locked(&buf->raw_tick_nohz_spinlock)) + goto retry; + else + return 0; + } + } else { + if (subbuf_trunc(lib_ring_buffer_get_offset(config, buf), + chan) + - subbuf_trunc(lib_ring_buffer_get_consumed(config, buf), + chan) + >= chan->backend.buf_size) + return POLLPRI | POLLRDBAND; + else + return POLLIN | POLLRDNORM; + } + } + return mask; +} + +/** + * lib_ring_buffer_ioctl - control ring buffer reader synchronization + * + * @filp: the file + * @cmd: the command + * @arg: command arg + * + * This ioctl implements commands necessary for producer/consumer + * and flight recorder reader interaction : + * RING_BUFFER_GET_NEXT_SUBBUF + * Get the next sub-buffer that can be read. It never blocks. + * RING_BUFFER_PUT_NEXT_SUBBUF + * Release the currently read sub-buffer. + * RING_BUFFER_GET_SUBBUF_SIZE + * returns the size of the current sub-buffer. + * RING_BUFFER_GET_MAX_SUBBUF_SIZE + * returns the maximum size for sub-buffers. + * RING_BUFFER_GET_NUM_SUBBUF + * returns the number of reader-visible sub-buffers in the per cpu + * channel (for mmap). + * RING_BUFFER_GET_MMAP_READ_OFFSET + * returns the offset of the subbuffer belonging to the reader. + * Should only be used for mmap clients. + */ +long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct lib_ring_buffer *buf = filp->private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (lib_ring_buffer_channel_is_disabled(chan)) + return -EIO; + + switch (cmd) { + case RING_BUFFER_SNAPSHOT: + return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, + &buf->prod_snapshot); + case RING_BUFFER_SNAPSHOT_GET_CONSUMED: + return put_ulong(buf->cons_snapshot, arg); + case RING_BUFFER_SNAPSHOT_GET_PRODUCED: + return put_ulong(buf->prod_snapshot, arg); + case RING_BUFFER_GET_SUBBUF: + { + unsigned long uconsume; + long ret; + + ret = get_user(uconsume, (unsigned long __user *) arg); + if (ret) + return ret; /* will return -EFAULT */ + ret = lib_ring_buffer_get_subbuf(buf, uconsume); + if (!ret) { + /* Set file position to zero at each successful "get" */ + filp->f_pos = 0; + } + return ret; + } + case RING_BUFFER_PUT_SUBBUF: + lib_ring_buffer_put_subbuf(buf); + return 0; + + case RING_BUFFER_GET_NEXT_SUBBUF: + { + long ret; + + ret = lib_ring_buffer_get_next_subbuf(buf); + if (!ret) { + /* Set file position to zero at each successful "get" */ + filp->f_pos = 0; + } + return ret; + } + case RING_BUFFER_PUT_NEXT_SUBBUF: + lib_ring_buffer_put_next_subbuf(buf); + return 0; + case RING_BUFFER_GET_SUBBUF_SIZE: + return put_ulong(lib_ring_buffer_get_read_data_size(config, buf), + arg); + case RING_BUFFER_GET_PADDED_SUBBUF_SIZE: + { + unsigned long size; + + size = lib_ring_buffer_get_read_data_size(config, buf); + size = PAGE_ALIGN(size); + return put_ulong(size, arg); + } + case RING_BUFFER_GET_MAX_SUBBUF_SIZE: + return put_ulong(chan->backend.subbuf_size, arg); + case RING_BUFFER_GET_MMAP_LEN: + { + unsigned long mmap_buf_len; + + if (config->output != RING_BUFFER_MMAP) + return -EINVAL; + mmap_buf_len = chan->backend.buf_size; + if (chan->backend.extra_reader_sb) + mmap_buf_len += chan->backend.subbuf_size; + if (mmap_buf_len > INT_MAX) + return -EFBIG; + return put_ulong(mmap_buf_len, arg); + } + case RING_BUFFER_GET_MMAP_READ_OFFSET: + { + unsigned long sb_bindex; + + if (config->output != RING_BUFFER_MMAP) + return -EINVAL; + sb_bindex = subbuffer_id_get_index(config, + buf->backend.buf_rsb.id); + return put_ulong(buf->backend.array[sb_bindex]->mmap_offset, + arg); + } + case RING_BUFFER_FLUSH: + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + return 0; + default: + return -ENOIOCTLCMD; + } +} + +#ifdef CONFIG_COMPAT +long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct lib_ring_buffer *buf = filp->private_data; + struct channel *chan = buf->backend.chan; + const struct lib_ring_buffer_config *config = chan->backend.config; + + if (lib_ring_buffer_channel_is_disabled(chan)) + return -EIO; + + switch (cmd) { + case RING_BUFFER_SNAPSHOT: + return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot, + &buf->prod_snapshot); + case RING_BUFFER_SNAPSHOT_GET_CONSUMED: + return compat_put_ulong(buf->cons_snapshot, arg); + case RING_BUFFER_SNAPSHOT_GET_PRODUCED: + return compat_put_ulong(buf->prod_snapshot, arg); + case RING_BUFFER_GET_SUBBUF: + { + __u32 uconsume; + unsigned long consume; + long ret; + + ret = get_user(uconsume, (__u32 __user *) arg); + if (ret) + return ret; /* will return -EFAULT */ + consume = buf->cons_snapshot; + consume &= ~0xFFFFFFFFL; + consume |= uconsume; + ret = lib_ring_buffer_get_subbuf(buf, consume); + if (!ret) { + /* Set file position to zero at each successful "get" */ + filp->f_pos = 0; + } + return ret; + } + case RING_BUFFER_PUT_SUBBUF: + lib_ring_buffer_put_subbuf(buf); + return 0; + + case RING_BUFFER_GET_NEXT_SUBBUF: + { + long ret; + + ret = lib_ring_buffer_get_next_subbuf(buf); + if (!ret) { + /* Set file position to zero at each successful "get" */ + filp->f_pos = 0; + } + return ret; + } + case RING_BUFFER_PUT_NEXT_SUBBUF: + lib_ring_buffer_put_next_subbuf(buf); + return 0; + case RING_BUFFER_GET_SUBBUF_SIZE: + { + unsigned long data_size; + + data_size = lib_ring_buffer_get_read_data_size(config, buf); + if (data_size > UINT_MAX) + return -EFBIG; + return put_ulong(data_size, arg); + } + case RING_BUFFER_GET_PADDED_SUBBUF_SIZE: + { + unsigned long size; + + size = lib_ring_buffer_get_read_data_size(config, buf); + size = PAGE_ALIGN(size); + if (size > UINT_MAX) + return -EFBIG; + return put_ulong(size, arg); + } + case RING_BUFFER_GET_MAX_SUBBUF_SIZE: + if (chan->backend.subbuf_size > UINT_MAX) + return -EFBIG; + return put_ulong(chan->backend.subbuf_size, arg); + case RING_BUFFER_GET_MMAP_LEN: + { + unsigned long mmap_buf_len; + + if (config->output != RING_BUFFER_MMAP) + return -EINVAL; + mmap_buf_len = chan->backend.buf_size; + if (chan->backend.extra_reader_sb) + mmap_buf_len += chan->backend.subbuf_size; + if (mmap_buf_len > UINT_MAX) + return -EFBIG; + return put_ulong(mmap_buf_len, arg); + } + case RING_BUFFER_GET_MMAP_READ_OFFSET: + { + unsigned long sb_bindex, read_offset; + + if (config->output != RING_BUFFER_MMAP) + return -EINVAL; + sb_bindex = subbuffer_id_get_index(config, + buf->backend.buf_rsb.id); + read_offset = buf->backend.array[sb_bindex]->mmap_offset; + if (read_offset > UINT_MAX) + return -EINVAL; + return put_ulong(read_offset, arg); + } + case RING_BUFFER_FLUSH: + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + return 0; + default: + return -ENOIOCTLCMD; + } +} +#endif + +const struct file_operations lib_ring_buffer_file_operations = { + .owner = THIS_MODULE, + .open = lib_ring_buffer_open, + .release = lib_ring_buffer_release, + .poll = lib_ring_buffer_poll, + .splice_read = lib_ring_buffer_splice_read, + .mmap = lib_ring_buffer_mmap, + .unlocked_ioctl = lib_ring_buffer_ioctl, + .llseek = lib_ring_buffer_no_llseek, +#ifdef CONFIG_COMPAT + .compat_ioctl = lib_ring_buffer_compat_ioctl, +#endif +}; +EXPORT_SYMBOL_GPL(lib_ring_buffer_file_operations); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Ring Buffer Library VFS"); diff --git a/drivers/staging/lttng/lib/ringbuffer/vatomic.h b/drivers/staging/lttng/lib/ringbuffer/vatomic.h new file mode 100644 index 0000000..b944dd6 --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/vatomic.h @@ -0,0 +1,85 @@ +#ifndef _LINUX_RING_BUFFER_VATOMIC_H +#define _LINUX_RING_BUFFER_VATOMIC_H + +/* + * linux/ringbuffer/vatomic.h + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <asm/atomic.h> +#include <asm/local.h> + +/* + * Same data type (long) accessed differently depending on configuration. + * v field is for non-atomic access (protected by mutual exclusion). + * In the fast-path, the ring_buffer_config structure is constant, so the + * compiler can statically select the appropriate branch. + * local_t is used for per-cpu and per-thread buffers. + * atomic_long_t is used for globally shared buffers. + */ +union v_atomic { + local_t l; + atomic_long_t a; + long v; +}; + +static inline +long v_read(const struct lib_ring_buffer_config *config, union v_atomic *v_a) +{ + if (config->sync == RING_BUFFER_SYNC_PER_CPU) + return local_read(&v_a->l); + else + return atomic_long_read(&v_a->a); +} + +static inline +void v_set(const struct lib_ring_buffer_config *config, union v_atomic *v_a, + long v) +{ + if (config->sync == RING_BUFFER_SYNC_PER_CPU) + local_set(&v_a->l, v); + else + atomic_long_set(&v_a->a, v); +} + +static inline +void v_add(const struct lib_ring_buffer_config *config, long v, union v_atomic *v_a) +{ + if (config->sync == RING_BUFFER_SYNC_PER_CPU) + local_add(v, &v_a->l); + else + atomic_long_add(v, &v_a->a); +} + +static inline +void v_inc(const struct lib_ring_buffer_config *config, union v_atomic *v_a) +{ + if (config->sync == RING_BUFFER_SYNC_PER_CPU) + local_inc(&v_a->l); + else + atomic_long_inc(&v_a->a); +} + +/* + * Non-atomic decrement. Only used by reader, apply to reader-owned subbuffer. + */ +static inline +void _v_dec(const struct lib_ring_buffer_config *config, union v_atomic *v_a) +{ + --v_a->v; +} + +static inline +long v_cmpxchg(const struct lib_ring_buffer_config *config, union v_atomic *v_a, + long old, long _new) +{ + if (config->sync == RING_BUFFER_SYNC_PER_CPU) + return local_cmpxchg(&v_a->l, old, _new); + else + return atomic_long_cmpxchg(&v_a->a, old, _new); +} + +#endif /* _LINUX_RING_BUFFER_VATOMIC_H */ diff --git a/drivers/staging/lttng/lib/ringbuffer/vfs.h b/drivers/staging/lttng/lib/ringbuffer/vfs.h new file mode 100644 index 0000000..d073e4c --- /dev/null +++ b/drivers/staging/lttng/lib/ringbuffer/vfs.h @@ -0,0 +1,89 @@ +#ifndef _LINUX_RING_BUFFER_VFS_H +#define _LINUX_RING_BUFFER_VFS_H + +/* + * linux/ringbuffer/vfs.h + * + * (C) Copyright 2005-2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Wait-free ring buffer VFS file operations. + * + * Author: + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/fs.h> +#include <linux/poll.h> + +/* VFS API */ + +extern const struct file_operations lib_ring_buffer_file_operations; + +/* + * Internal file operations. + */ + +int lib_ring_buffer_open(struct inode *inode, struct file *file); +int lib_ring_buffer_release(struct inode *inode, struct file *file); +unsigned int lib_ring_buffer_poll(struct file *filp, poll_table *wait); +ssize_t lib_ring_buffer_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); +int lib_ring_buffer_mmap(struct file *filp, struct vm_area_struct *vma); + +/* Ring Buffer ioctl() and ioctl numbers */ +long lib_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long lib_ring_buffer_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); +#endif + +/* + * Use RING_BUFFER_GET_NEXT_SUBBUF / RING_BUFFER_PUT_NEXT_SUBBUF to read and + * consume sub-buffers sequentially. + * + * Reading sub-buffers without consuming them can be performed with: + * + * RING_BUFFER_SNAPSHOT + * RING_BUFFER_SNAPSHOT_GET_CONSUMED + * RING_BUFFER_SNAPSHOT_GET_PRODUCED + * + * to get the offset range to consume, and then by passing each sub-buffer + * offset to RING_BUFFER_GET_SUBBUF, read the sub-buffer, and then release it + * with RING_BUFFER_PUT_SUBBUF. + * + * Note that the "snapshot" API can be used to read the sub-buffer in reverse + * order, which is useful for flight recorder snapshots. + */ + +/* Get a snapshot of the current ring buffer producer and consumer positions */ +#define RING_BUFFER_SNAPSHOT _IO(0xF6, 0x00) +/* Get the consumer position (iteration start) */ +#define RING_BUFFER_SNAPSHOT_GET_CONSUMED _IOR(0xF6, 0x01, unsigned long) +/* Get the producer position (iteration end) */ +#define RING_BUFFER_SNAPSHOT_GET_PRODUCED _IOR(0xF6, 0x02, unsigned long) +/* Get exclusive read access to the specified sub-buffer position */ +#define RING_BUFFER_GET_SUBBUF _IOW(0xF6, 0x03, unsigned long) +/* Release exclusive sub-buffer access */ +#define RING_BUFFER_PUT_SUBBUF _IO(0xF6, 0x04) + +/* Get exclusive read access to the next sub-buffer that can be read. */ +#define RING_BUFFER_GET_NEXT_SUBBUF _IO(0xF6, 0x05) +/* Release exclusive sub-buffer access, move consumer forward. */ +#define RING_BUFFER_PUT_NEXT_SUBBUF _IO(0xF6, 0x06) +/* returns the size of the current sub-buffer, without padding (for mmap). */ +#define RING_BUFFER_GET_SUBBUF_SIZE _IOR(0xF6, 0x07, unsigned long) +/* returns the size of the current sub-buffer, with padding (for splice). */ +#define RING_BUFFER_GET_PADDED_SUBBUF_SIZE _IOR(0xF6, 0x08, unsigned long) +/* returns the maximum size for sub-buffers. */ +#define RING_BUFFER_GET_MAX_SUBBUF_SIZE _IOR(0xF6, 0x09, unsigned long) +/* returns the length to mmap. */ +#define RING_BUFFER_GET_MMAP_LEN _IOR(0xF6, 0x0A, unsigned long) +/* returns the offset of the subbuffer belonging to the mmap reader. */ +#define RING_BUFFER_GET_MMAP_READ_OFFSET _IOR(0xF6, 0x0B, unsigned long) +/* flush the current sub-buffer */ +#define RING_BUFFER_FLUSH _IO(0xF6, 0x0C) + +#endif /* _LINUX_RING_BUFFER_VFS_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 03/20] lttng lib: portable bitfield read/write header 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 01/20] lttng lib: lttng priority heap Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 02/20] lttng lib: ring buffer Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 04/20] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers ` (17 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lib/bitfield.h | 400 ++++++++++++++++++++++++++++++++++ 1 files changed, 400 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/bitfield.h diff --git a/drivers/staging/lttng/lib/bitfield.h b/drivers/staging/lttng/lib/bitfield.h new file mode 100644 index 0000000..861e6dc --- /dev/null +++ b/drivers/staging/lttng/lib/bitfield.h @@ -0,0 +1,400 @@ +#ifndef _BABELTRACE_BITFIELD_H +#define _BABELTRACE_BITFIELD_H + +/* + * BabelTrace + * + * Bitfields read/write functions. + * + * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ + +#include "../ltt-endian.h" + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */ +#define _bt_piecewise_rshift(_v, _shift) \ +({ \ + typeof(_v) ___v = (_v); \ + typeof(_shift) ___shift = (_shift); \ + unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1); \ + unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \ + \ + for (; sb; sb--) \ + ___v >>= sizeof(___v) * CHAR_BIT - 1; \ + ___v >>= final; \ +}) + +#define _bt_piecewise_lshift(_v, _shift) \ +({ \ + typeof(_v) ___v = (_v); \ + typeof(_shift) ___shift = (_shift); \ + unsigned long sb = (___shift) / (sizeof(___v) * CHAR_BIT - 1); \ + unsigned long final = (___shift) % (sizeof(___v) * CHAR_BIT - 1); \ + \ + for (; sb; sb--) \ + ___v <<= sizeof(___v) * CHAR_BIT - 1; \ + ___v <<= final; \ +}) + +#define _bt_is_signed_type(type) (((type)(-1)) < 0) + +#define _bt_unsigned_cast(type, v) \ +({ \ + (sizeof(v) < sizeof(type)) ? \ + ((type) (v)) & (~(~(type) 0 << (sizeof(v) * CHAR_BIT))) : \ + (type) (v); \ +}) + +/* + * bt_bitfield_write - write integer to a bitfield in native endianness + * + * Save integer to the bitfield, which starts at the "start" bit, has "len" + * bits. + * The inside of a bitfield is from high bits to low bits. + * Uses native endianness. + * For unsigned "v", pad MSB with 0 if bitfield is larger than v. + * For signed "v", sign-extend v if bitfield is larger than v. + * + * On little endian, bytes are placed from the less significant to the most + * significant. Also, consecutive bitfields are placed from lower bits to higher + * bits. + * + * On big endian, bytes are places from most significant to less significant. + * Also, consecutive bitfields are placed from higher to lower bits. + */ + +#define _bt_bitfield_write_le(_ptr, type, _start, _length, _v) \ +do { \ + typeof(_v) __v = (_v); \ + type *__ptr = (void *) (_ptr); \ + unsigned long __start = (_start), __length = (_length); \ + type mask, cmask; \ + unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \ + unsigned long start_unit, end_unit, this_unit; \ + unsigned long end, cshift; /* cshift is "complement shift" */ \ + \ + if (!__length) \ + break; \ + \ + end = __start + __length; \ + start_unit = __start / ts; \ + end_unit = (end + (ts - 1)) / ts; \ + \ + /* Trim v high bits */ \ + if (__length < sizeof(__v) * CHAR_BIT) \ + __v &= ~((~(typeof(__v)) 0) << __length); \ + \ + /* We can now append v with a simple "or", shift it piece-wise */ \ + this_unit = start_unit; \ + if (start_unit == end_unit - 1) { \ + mask = ~((~(type) 0) << (__start % ts)); \ + if (end % ts) \ + mask |= (~(type) 0) << (end % ts); \ + cmask = (type) __v << (__start % ts); \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + break; \ + } \ + if (__start % ts) { \ + cshift = __start % ts; \ + mask = ~((~(type) 0) << cshift); \ + cmask = (type) __v << cshift; \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + __v = _bt_piecewise_rshift(__v, ts - cshift); \ + __start += ts - cshift; \ + this_unit++; \ + } \ + for (; this_unit < end_unit - 1; this_unit++) { \ + __ptr[this_unit] = (type) __v; \ + __v = _bt_piecewise_rshift(__v, ts); \ + __start += ts; \ + } \ + if (end % ts) { \ + mask = (~(type) 0) << (end % ts); \ + cmask = (type) __v; \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + } else \ + __ptr[this_unit] = (type) __v; \ +} while (0) + +#define _bt_bitfield_write_be(_ptr, type, _start, _length, _v) \ +do { \ + typeof(_v) __v = (_v); \ + type *__ptr = (void *) (_ptr); \ + unsigned long __start = (_start), __length = (_length); \ + type mask, cmask; \ + unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \ + unsigned long start_unit, end_unit, this_unit; \ + unsigned long end, cshift; /* cshift is "complement shift" */ \ + \ + if (!__length) \ + break; \ + \ + end = __start + __length; \ + start_unit = __start / ts; \ + end_unit = (end + (ts - 1)) / ts; \ + \ + /* Trim v high bits */ \ + if (__length < sizeof(__v) * CHAR_BIT) \ + __v &= ~((~(typeof(__v)) 0) << __length); \ + \ + /* We can now append v with a simple "or", shift it piece-wise */ \ + this_unit = end_unit - 1; \ + if (start_unit == end_unit - 1) { \ + mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \ + if (__start % ts) \ + mask |= (~((type) 0)) << (ts - (__start % ts)); \ + cmask = (type) __v << ((ts - (end % ts)) % ts); \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + break; \ + } \ + if (end % ts) { \ + cshift = end % ts; \ + mask = ~((~(type) 0) << (ts - cshift)); \ + cmask = (type) __v << (ts - cshift); \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + __v = _bt_piecewise_rshift(__v, cshift); \ + end -= cshift; \ + this_unit--; \ + } \ + for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \ + __ptr[this_unit] = (type) __v; \ + __v = _bt_piecewise_rshift(__v, ts); \ + end -= ts; \ + } \ + if (__start % ts) { \ + mask = (~(type) 0) << (ts - (__start % ts)); \ + cmask = (type) __v; \ + cmask &= ~mask; \ + __ptr[this_unit] &= mask; \ + __ptr[this_unit] |= cmask; \ + } else \ + __ptr[this_unit] = (type) __v; \ +} while (0) + +/* + * bt_bitfield_write - write integer to a bitfield in native endianness + * bt_bitfield_write_le - write integer to a bitfield in little endian + * bt_bitfield_write_be - write integer to a bitfield in big endian + */ + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) + +#define bt_bitfield_write(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_le(ptr, type, _start, _length, _v) + +#define bt_bitfield_write_le(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_le(ptr, type, _start, _length, _v) + +#define bt_bitfield_write_be(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v) + +#elif (__BYTE_ORDER == __BIG_ENDIAN) + +#define bt_bitfield_write(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_be(ptr, type, _start, _length, _v) + +#define bt_bitfield_write_le(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v) + +#define bt_bitfield_write_be(ptr, type, _start, _length, _v) \ + _bt_bitfield_write_be(ptr, type, _start, _length, _v) + +#else /* (BYTE_ORDER == PDP_ENDIAN) */ + +#error "Byte order not supported" + +#endif + +#define _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \ +do { \ + typeof(*(_vptr)) *__vptr = (_vptr); \ + typeof(*__vptr) __v; \ + type *__ptr = (void *) (_ptr); \ + unsigned long __start = (_start), __length = (_length); \ + type mask, cmask; \ + unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \ + unsigned long start_unit, end_unit, this_unit; \ + unsigned long end, cshift; /* cshift is "complement shift" */ \ + \ + if (!__length) { \ + *__vptr = 0; \ + break; \ + } \ + \ + end = __start + __length; \ + start_unit = __start / ts; \ + end_unit = (end + (ts - 1)) / ts; \ + \ + this_unit = end_unit - 1; \ + if (_bt_is_signed_type(typeof(__v)) \ + && (__ptr[this_unit] & ((type) 1 << ((end % ts ? : ts) - 1)))) \ + __v = ~(typeof(__v)) 0; \ + else \ + __v = 0; \ + if (start_unit == end_unit - 1) { \ + cmask = __ptr[this_unit]; \ + cmask >>= (__start % ts); \ + if ((end - __start) % ts) { \ + mask = ~((~(type) 0) << (end - __start)); \ + cmask &= mask; \ + } \ + __v = _bt_piecewise_lshift(__v, end - __start); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + *__vptr = __v; \ + break; \ + } \ + if (end % ts) { \ + cshift = end % ts; \ + mask = ~((~(type) 0) << cshift); \ + cmask = __ptr[this_unit]; \ + cmask &= mask; \ + __v = _bt_piecewise_lshift(__v, cshift); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + end -= cshift; \ + this_unit--; \ + } \ + for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \ + __v = _bt_piecewise_lshift(__v, ts); \ + __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\ + end -= ts; \ + } \ + if (__start % ts) { \ + mask = ~((~(type) 0) << (ts - (__start % ts))); \ + cmask = __ptr[this_unit]; \ + cmask >>= (__start % ts); \ + cmask &= mask; \ + __v = _bt_piecewise_lshift(__v, ts - (__start % ts)); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + } else { \ + __v = _bt_piecewise_lshift(__v, ts); \ + __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\ + } \ + *__vptr = __v; \ +} while (0) + +#define _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \ +do { \ + typeof(*(_vptr)) *__vptr = (_vptr); \ + typeof(*__vptr) __v; \ + type *__ptr = (void *) (_ptr); \ + unsigned long __start = (_start), __length = (_length); \ + type mask, cmask; \ + unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \ + unsigned long start_unit, end_unit, this_unit; \ + unsigned long end, cshift; /* cshift is "complement shift" */ \ + \ + if (!__length) { \ + *__vptr = 0; \ + break; \ + } \ + \ + end = __start + __length; \ + start_unit = __start / ts; \ + end_unit = (end + (ts - 1)) / ts; \ + \ + this_unit = start_unit; \ + if (_bt_is_signed_type(typeof(__v)) \ + && (__ptr[this_unit] & ((type) 1 << (ts - (__start % ts) - 1)))) \ + __v = ~(typeof(__v)) 0; \ + else \ + __v = 0; \ + if (start_unit == end_unit - 1) { \ + cmask = __ptr[this_unit]; \ + cmask >>= (ts - (end % ts)) % ts; \ + if ((end - __start) % ts) { \ + mask = ~((~(type) 0) << (end - __start)); \ + cmask &= mask; \ + } \ + __v = _bt_piecewise_lshift(__v, end - __start); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + *__vptr = __v; \ + break; \ + } \ + if (__start % ts) { \ + cshift = __start % ts; \ + mask = ~((~(type) 0) << (ts - cshift)); \ + cmask = __ptr[this_unit]; \ + cmask &= mask; \ + __v = _bt_piecewise_lshift(__v, ts - cshift); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + __start += ts - cshift; \ + this_unit++; \ + } \ + for (; this_unit < end_unit - 1; this_unit++) { \ + __v = _bt_piecewise_lshift(__v, ts); \ + __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\ + __start += ts; \ + } \ + if (end % ts) { \ + mask = ~((~(type) 0) << (end % ts)); \ + cmask = __ptr[this_unit]; \ + cmask >>= ts - (end % ts); \ + cmask &= mask; \ + __v = _bt_piecewise_lshift(__v, end % ts); \ + __v |= _bt_unsigned_cast(typeof(__v), cmask); \ + } else { \ + __v = _bt_piecewise_lshift(__v, ts); \ + __v |= _bt_unsigned_cast(typeof(__v), __ptr[this_unit]);\ + } \ + *__vptr = __v; \ +} while (0) + +/* + * bt_bitfield_read - read integer from a bitfield in native endianness + * bt_bitfield_read_le - read integer from a bitfield in little endian + * bt_bitfield_read_be - read integer from a bitfield in big endian + */ + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) + +#define bt_bitfield_read(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) + +#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) + +#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_be(_ptr, unsigned char, _start, _length, _vptr) + +#elif (__BYTE_ORDER == __BIG_ENDIAN) + +#define bt_bitfield_read(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) + +#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_le(_ptr, unsigned char, _start, _length, _vptr) + +#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \ + _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) + +#else /* (__BYTE_ORDER == __PDP_ENDIAN) */ + +#error "Byte order not supported" + +#endif + +#endif /* _BABELTRACE_BITFIELD_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 04/20] lttng: BUILD_RUNTIME_BUG_ON 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (2 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 03/20] lttng lib: portable bitfield read/write header Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 05/20] lttng: offset alignment header Mathieu Desnoyers ` (16 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lib/bug.h | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/bug.h diff --git a/drivers/staging/lttng/lib/bug.h b/drivers/staging/lttng/lib/bug.h new file mode 100644 index 0000000..8243cc9 --- /dev/null +++ b/drivers/staging/lttng/lib/bug.h @@ -0,0 +1,29 @@ +#ifndef _LTTNG_BUG_H +#define _LTTNG_BUG_H + +/* + * lib/bug.h + * + * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +/** + * BUILD_RUNTIME_BUG_ON - check condition at build (if constant) or runtime + * @condition: the condition which should be false. + * + * If the condition is a constant and true, the compiler will generate a build + * error. If the condition is not constant, a BUG will be triggered at runtime + * if the condition is ever true. If the condition is constant and false, no + * code is emitted. + */ +#define BUILD_RUNTIME_BUG_ON(condition) \ + do { \ + if (__builtin_constant_p(condition)) \ + BUILD_BUG_ON(condition); \ + else \ + BUG_ON(condition); \ + } while (0) + +#endif -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 05/20] lttng: offset alignment header 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (3 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 04/20] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 06/20] lttng libs: add Makefile Mathieu Desnoyers ` (15 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lib/align.h | 61 +++++++++++++++++++++++++++++++++++++ 1 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/align.h diff --git a/drivers/staging/lttng/lib/align.h b/drivers/staging/lttng/lib/align.h new file mode 100644 index 0000000..0b86100 --- /dev/null +++ b/drivers/staging/lttng/lib/align.h @@ -0,0 +1,61 @@ +#ifndef _LTTNG_ALIGN_H +#define _LTTNG_ALIGN_H + +/* + * lib/align.h + * + * (C) Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include "bug.h" + +#define ALIGN_FLOOR(x, a) __ALIGN_FLOOR_MASK(x, (typeof(x)) (a) - 1) +#define __ALIGN_FLOOR_MASK(x, mask) ((x) & ~(mask)) +#define PTR_ALIGN_FLOOR(p, a) \ + ((typeof(p)) ALIGN_FLOOR((unsigned long) (p), a)) + +/* + * Align pointer on natural object alignment. + */ +#define object_align(obj) PTR_ALIGN(obj, __alignof__(*(obj))) +#define object_align_floor(obj) PTR_ALIGN_FLOOR(obj, __alignof__(*(obj))) + +/** + * offset_align - Calculate the offset needed to align an object on its natural + * alignment towards higher addresses. + * @align_drift: object offset from an "alignment"-aligned address. + * @alignment: natural object alignment. Must be non-zero, power of 2. + * + * Returns the offset that must be added to align towards higher + * addresses. + */ +#define offset_align(align_drift, alignment) \ + ({ \ + BUILD_RUNTIME_BUG_ON((alignment) == 0 \ + || ((alignment) & ((alignment) - 1))); \ + (((alignment) - (align_drift)) & ((alignment) - 1)); \ + }) + +/** + * offset_align_floor - Calculate the offset needed to align an object + * on its natural alignment towards lower addresses. + * @align_drift: object offset from an "alignment"-aligned address. + * @alignment: natural object alignment. Must be non-zero, power of 2. + * + * Returns the offset that must be substracted to align towards lower addresses. + */ +#define offset_align_floor(align_drift, alignment) \ + ({ \ + BUILD_RUNTIME_BUG_ON((alignment) == 0 \ + || ((alignment) & ((alignment) - 1))); \ + (((align_drift) - (alignment)) & ((alignment) - 1); \ + }) + +#endif /* __KERNEL__ */ + +#endif -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 06/20] lttng libs: add Makefile 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (4 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 05/20] lttng: offset alignment header Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 07/20] lttng wrappers Mathieu Desnoyers ` (14 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lib/Makefile | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lib/Makefile diff --git a/drivers/staging/lttng/lib/Makefile b/drivers/staging/lttng/lib/Makefile new file mode 100644 index 0000000..e5735ec --- /dev/null +++ b/drivers/staging/lttng/lib/Makefile @@ -0,0 +1,11 @@ +obj-m += lib-ring-buffer.o + +lib-ring-buffer-objs := \ + ringbuffer/ring_buffer_backend.o \ + ringbuffer/ring_buffer_frontend.o \ + ringbuffer/ring_buffer_iterator.o \ + ringbuffer/ring_buffer_vfs.o \ + ringbuffer/ring_buffer_splice.o \ + ringbuffer/ring_buffer_mmap.o \ + prio_heap/lttng_prio_heap.o \ + ../wrapper/splice.o -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 07/20] lttng wrappers 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (5 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 06/20] lttng libs: add Makefile Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-29 1:04 ` Greg KH 2011-11-28 12:42 ` [lttng-dev] [PATCH 08/20] lttng instrumentation: tracepoint events Mathieu Desnoyers ` (13 subsequent siblings) 20 siblings, 1 reply; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Implement wrappers for compatibility with older kernel versions and kernels with had the libringbuffer (old) patchset applied. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/wrapper/ftrace.h | 70 ++++++++++++++++++ drivers/staging/lttng/wrapper/inline_memcpy.h | 11 +++ drivers/staging/lttng/wrapper/kallsyms.h | 28 +++++++ drivers/staging/lttng/wrapper/perf.h | 32 ++++++++ drivers/staging/lttng/wrapper/poll.h | 14 ++++ drivers/staging/lttng/wrapper/ringbuffer/api.h | 1 + drivers/staging/lttng/wrapper/ringbuffer/backend.h | 1 + .../lttng/wrapper/ringbuffer/backend_internal.h | 2 + .../lttng/wrapper/ringbuffer/backend_types.h | 1 + drivers/staging/lttng/wrapper/ringbuffer/config.h | 1 + .../staging/lttng/wrapper/ringbuffer/frontend.h | 1 + .../lttng/wrapper/ringbuffer/frontend_api.h | 1 + .../lttng/wrapper/ringbuffer/frontend_internal.h | 1 + .../lttng/wrapper/ringbuffer/frontend_types.h | 1 + .../staging/lttng/wrapper/ringbuffer/iterator.h | 1 + drivers/staging/lttng/wrapper/ringbuffer/nohz.h | 1 + drivers/staging/lttng/wrapper/ringbuffer/vatomic.h | 1 + drivers/staging/lttng/wrapper/ringbuffer/vfs.h | 1 + drivers/staging/lttng/wrapper/spinlock.h | 26 +++++++ drivers/staging/lttng/wrapper/splice.c | 46 ++++++++++++ drivers/staging/lttng/wrapper/splice.h | 23 ++++++ drivers/staging/lttng/wrapper/trace-clock.h | 75 ++++++++++++++++++++ drivers/staging/lttng/wrapper/uuid.h | 29 ++++++++ drivers/staging/lttng/wrapper/vmalloc.h | 49 +++++++++++++ 24 files changed, 417 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/wrapper/ftrace.h create mode 100644 drivers/staging/lttng/wrapper/inline_memcpy.h create mode 100644 drivers/staging/lttng/wrapper/kallsyms.h create mode 100644 drivers/staging/lttng/wrapper/perf.h create mode 100644 drivers/staging/lttng/wrapper/poll.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/api.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/backend_types.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/config.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/iterator.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/nohz.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/vatomic.h create mode 100644 drivers/staging/lttng/wrapper/ringbuffer/vfs.h create mode 100644 drivers/staging/lttng/wrapper/spinlock.h create mode 100644 drivers/staging/lttng/wrapper/splice.c create mode 100644 drivers/staging/lttng/wrapper/splice.h create mode 100644 drivers/staging/lttng/wrapper/trace-clock.h create mode 100644 drivers/staging/lttng/wrapper/uuid.h create mode 100644 drivers/staging/lttng/wrapper/vmalloc.h diff --git a/drivers/staging/lttng/wrapper/ftrace.h b/drivers/staging/lttng/wrapper/ftrace.h new file mode 100644 index 0000000..ace33c5 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ftrace.h @@ -0,0 +1,70 @@ +#ifndef _LTT_WRAPPER_FTRACE_H +#define _LTT_WRAPPER_FTRACE_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when + * available, else we need to have a kernel that exports this function to GPL + * modules. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/ftrace.h> + +#ifdef CONFIG_KALLSYMS + +#include <linux/kallsyms.h> +#include "kallsyms.h" + +static inline +int wrapper_register_ftrace_function_probe(char *glob, + struct ftrace_probe_ops *ops, void *data) +{ + int (*register_ftrace_function_probe_sym)(char *glob, + struct ftrace_probe_ops *ops, void *data); + + register_ftrace_function_probe_sym = (void *) kallsyms_lookup_funcptr("register_ftrace_function_probe"); + if (register_ftrace_function_probe_sym) { + return register_ftrace_function_probe_sym(glob, ops, data); + } else { + printk(KERN_WARNING "LTTng: register_ftrace_function_probe symbol lookup failed.\n"); + return -EINVAL; + } +} + +static inline +void wrapper_unregister_ftrace_function_probe(char *glob, + struct ftrace_probe_ops *ops, void *data) +{ + void (*unregister_ftrace_function_probe_sym)(char *glob, + struct ftrace_probe_ops *ops, void *data); + + unregister_ftrace_function_probe_sym = (void *) kallsyms_lookup_funcptr("unregister_ftrace_function_probe"); + if (unregister_ftrace_function_probe_sym) { + unregister_ftrace_function_probe_sym(glob, ops, data); + } else { + printk(KERN_WARNING "LTTng: unregister_ftrace_function_probe symbol lookup failed.\n"); + WARN_ON(1); + } +} + +#else + +static inline +int wrapper_register_ftrace_function_probe(char *glob, + struct ftrace_probe_ops *ops, void *data) +{ + return register_ftrace_function_probe(glob, ops, data); +} + +static inline +void wrapper_unregister_ftrace_function_probe(char *glob, + struct ftrace_probe_ops *ops, void *data) +{ + return unregister_ftrace_function_probe(glob, ops, data); +} +#endif + +#endif /* _LTT_WRAPPER_FTRACE_H */ diff --git a/drivers/staging/lttng/wrapper/inline_memcpy.h b/drivers/staging/lttng/wrapper/inline_memcpy.h new file mode 100644 index 0000000..33150cd --- /dev/null +++ b/drivers/staging/lttng/wrapper/inline_memcpy.h @@ -0,0 +1,11 @@ +/* + * wrapper/inline_memcpy.h + * + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#if !defined(__HAVE_ARCH_INLINE_MEMCPY) && !defined(inline_memcpy) +#define inline_memcpy memcpy +#endif diff --git a/drivers/staging/lttng/wrapper/kallsyms.h b/drivers/staging/lttng/wrapper/kallsyms.h new file mode 100644 index 0000000..bb45f38 --- /dev/null +++ b/drivers/staging/lttng/wrapper/kallsyms.h @@ -0,0 +1,28 @@ +#ifndef _LTT_WRAPPER_KALLSYMS_H +#define _LTT_WRAPPER_KALLSYMS_H + +/* + * Copyright (C) 2011 Avik Sil (avik.sil at linaro.org) + * + * wrapper around kallsyms_lookup_name. Implements arch-dependent code for + * arches where the address of the start of the function body is different + * from the pointer which can be used to call the function, e.g. ARM THUMB2. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +static inline +unsigned long kallsyms_lookup_funcptr(const char *name) +{ + unsigned long addr; + + addr = kallsyms_lookup_name(name); +#ifdef CONFIG_ARM +#ifdef CONFIG_THUMB2_KERNEL + if (addr) + addr |= 1; /* set bit 0 in address for thumb mode */ +#endif +#endif + return addr; +} +#endif /* _LTT_WRAPPER_KALLSYMS_H */ diff --git a/drivers/staging/lttng/wrapper/perf.h b/drivers/staging/lttng/wrapper/perf.h new file mode 100644 index 0000000..9a6dbfc --- /dev/null +++ b/drivers/staging/lttng/wrapper/perf.h @@ -0,0 +1,32 @@ +#ifndef _LTT_WRAPPER_PERF_H +#define _LTT_WRAPPER_PERF_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/perf_event.h> + +#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99)) +static inline struct perf_event * +wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr, + int cpu, + struct task_struct *task, + perf_overflow_handler_t callback) +{ + return perf_event_create_kernel_counter(attr, cpu, task, callback, NULL); +} +#else +static inline struct perf_event * +wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr, + int cpu, + struct task_struct *task, + perf_overflow_handler_t callback) +{ + return perf_event_create_kernel_counter(attr, cpu, task, callback); +} +#endif + +#endif /* _LTT_WRAPPER_PERF_H */ diff --git a/drivers/staging/lttng/wrapper/poll.h b/drivers/staging/lttng/wrapper/poll.h new file mode 100644 index 0000000..9c2d18f --- /dev/null +++ b/drivers/staging/lttng/wrapper/poll.h @@ -0,0 +1,14 @@ +#ifndef _LTTNG_WRAPPER_POLL_H +#define _LTTNG_WRAPPER_POLL_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/poll.h> + +#define poll_wait_set_exclusive(poll_table) + +#endif /* _LTTNG_WRAPPER_POLL_H */ diff --git a/drivers/staging/lttng/wrapper/ringbuffer/api.h b/drivers/staging/lttng/wrapper/ringbuffer/api.h new file mode 100644 index 0000000..182bee2 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/api.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/api.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend.h b/drivers/staging/lttng/wrapper/ringbuffer/backend.h new file mode 100644 index 0000000..bfdd39d --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/backend.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/backend.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h b/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h new file mode 100644 index 0000000..00d45e4 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/backend_internal.h @@ -0,0 +1,2 @@ +#include "../../wrapper/inline_memcpy.h" +#include "../../lib/ringbuffer/backend_internal.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h b/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h new file mode 100644 index 0000000..c59effd --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/backend_types.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/backend_types.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/config.h b/drivers/staging/lttng/wrapper/ringbuffer/config.h new file mode 100644 index 0000000..0ce7a9d --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/config.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/config.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend.h new file mode 100644 index 0000000..7c6c070 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/frontend.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h new file mode 100644 index 0000000..b03c501 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_api.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/frontend_api.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h new file mode 100644 index 0000000..1899101 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_internal.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/frontend_internal.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h b/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h new file mode 100644 index 0000000..0c23244 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/frontend_types.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/frontend_types.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/iterator.h b/drivers/staging/lttng/wrapper/ringbuffer/iterator.h new file mode 100644 index 0000000..76e9edb --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/iterator.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/iterator.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/nohz.h b/drivers/staging/lttng/wrapper/ringbuffer/nohz.h new file mode 100644 index 0000000..9fbb84d --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/nohz.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/nohz.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h b/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h new file mode 100644 index 0000000..d578445 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/vatomic.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/vatomic.h" diff --git a/drivers/staging/lttng/wrapper/ringbuffer/vfs.h b/drivers/staging/lttng/wrapper/ringbuffer/vfs.h new file mode 100644 index 0000000..f8e9ed9 --- /dev/null +++ b/drivers/staging/lttng/wrapper/ringbuffer/vfs.h @@ -0,0 +1 @@ +#include "../../lib/ringbuffer/vfs.h" diff --git a/drivers/staging/lttng/wrapper/spinlock.h b/drivers/staging/lttng/wrapper/spinlock.h new file mode 100644 index 0000000..8b1ad99 --- /dev/null +++ b/drivers/staging/lttng/wrapper/spinlock.h @@ -0,0 +1,26 @@ +#ifndef _LTT_WRAPPER_SPINLOCK_H +#define _LTT_WRAPPER_SPINLOCK_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/version.h> + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + +#include <linux/string.h> + +#define raw_spin_lock_init(lock) \ + do { \ + raw_spinlock_t __lock = __RAW_SPIN_LOCK_UNLOCKED; \ + memcpy(lock, &__lock, sizeof(lock)); \ + } while (0) + +#define raw_spin_is_locked(lock) __raw_spin_is_locked(lock) + + +#endif +#endif /* _LTT_WRAPPER_SPINLOCK_H */ diff --git a/drivers/staging/lttng/wrapper/splice.c b/drivers/staging/lttng/wrapper/splice.c new file mode 100644 index 0000000..ba224ee --- /dev/null +++ b/drivers/staging/lttng/wrapper/splice.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when + * available, else we need to have a kernel that exports this function to GPL + * modules. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef CONFIG_KALLSYMS + +#include <linux/kallsyms.h> +#include <linux/fs.h> +#include <linux/splice.h> +#include "kallsyms.h" + +static +ssize_t (*splice_to_pipe_sym)(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd); + +ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd) +{ + if (!splice_to_pipe_sym) + splice_to_pipe_sym = (void *) kallsyms_lookup_funcptr("splice_to_pipe"); + if (splice_to_pipe_sym) { + return splice_to_pipe_sym(pipe, spd); + } else { + printk(KERN_WARNING "LTTng: splice_to_pipe symbol lookup failed.\n"); + return -ENOSYS; + } +} + +#else + +#include <linux/fs.h> +#include <linux/splice.h> + +ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd) +{ + return splice_to_pipe(pipe, spd); +} + +#endif diff --git a/drivers/staging/lttng/wrapper/splice.h b/drivers/staging/lttng/wrapper/splice.h new file mode 100644 index 0000000..f75309a --- /dev/null +++ b/drivers/staging/lttng/wrapper/splice.h @@ -0,0 +1,23 @@ +#ifndef _LTT_WRAPPER_SPLICE_H +#define _LTT_WRAPPER_SPLICE_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when + * available, else we need to have a kernel that exports this function to GPL + * modules. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/splice.h> + +ssize_t wrapper_splice_to_pipe(struct pipe_inode_info *pipe, + struct splice_pipe_desc *spd); + +#ifndef PIPE_DEF_BUFFERS +#define PIPE_DEF_BUFFERS 16 +#endif + +#endif /* _LTT_WRAPPER_SPLICE_H */ diff --git a/drivers/staging/lttng/wrapper/trace-clock.h b/drivers/staging/lttng/wrapper/trace-clock.h new file mode 100644 index 0000000..8b77428 --- /dev/null +++ b/drivers/staging/lttng/wrapper/trace-clock.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * Contains LTTng trace clock mapping to LTTng trace clock or mainline monotonic + * clock. This wrapper depends on CONFIG_HIGH_RES_TIMERS=y. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifndef _LTT_TRACE_CLOCK_H +#define _LTT_TRACE_CLOCK_H + +#ifdef CONFIG_HAVE_TRACE_CLOCK +#include <linux/trace-clock.h> +#else /* CONFIG_HAVE_TRACE_CLOCK */ + +#include <linux/hardirq.h> +#include <linux/ktime.h> +#include <linux/time.h> +#include <linux/hrtimer.h> + +static inline u64 trace_clock_monotonic_wrapper(void) +{ + ktime_t ktime; + + /* + * Refuse to trace from NMIs with this wrapper, because an NMI could + * nest over the xtime write seqlock and deadlock. + */ + if (in_nmi()) + return (u64) -EIO; + + ktime = ktime_get(); + return (u64) ktime.tv64; +} + +static inline u32 trace_clock_read32(void) +{ + return (u32) trace_clock_monotonic_wrapper(); +} + +static inline u64 trace_clock_read64(void) +{ + return (u64) trace_clock_monotonic_wrapper(); +} + +static inline u64 trace_clock_frequency(void) +{ + return (u64)NSEC_PER_SEC; +} + +static inline u32 trace_clock_freq_scale(void) +{ + return 1; +} + +static inline int get_trace_clock(void) +{ + printk(KERN_WARNING "LTTng: Using mainline kernel monotonic clock.\n"); + printk(KERN_WARNING " * NMIs will not be traced,\n"); + printk(KERN_WARNING " * expect significant performance degradation compared to the\n"); + printk(KERN_WARNING " LTTng trace clocks.\n"); + printk(KERN_WARNING "Integration of the LTTng 0.x trace clocks into LTTng 2.0 is planned\n"); + printk(KERN_WARNING "in a near future.\n"); + + return 0; +} + +static inline void put_trace_clock(void) +{ +} + +#endif /* CONFIG_HAVE_TRACE_CLOCK */ + +#endif /* _LTT_TRACE_CLOCK_H */ diff --git a/drivers/staging/lttng/wrapper/uuid.h b/drivers/staging/lttng/wrapper/uuid.h new file mode 100644 index 0000000..bfa67ff --- /dev/null +++ b/drivers/staging/lttng/wrapper/uuid.h @@ -0,0 +1,29 @@ +#ifndef _LTT_WRAPPER_UUID_H +#define _LTT_WRAPPER_UUID_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/version.h> + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) +#include <linux/uuid.h> +#else + +#include <linux/random.h> + +typedef struct { + __u8 b[16]; +} uuid_le; + +static inline +void uuid_le_gen(uuid_le *u) +{ + generate_random_uuid(u->b); +} + +#endif +#endif /* _LTT_WRAPPER_UUID_H */ diff --git a/drivers/staging/lttng/wrapper/vmalloc.h b/drivers/staging/lttng/wrapper/vmalloc.h new file mode 100644 index 0000000..765f2ad --- /dev/null +++ b/drivers/staging/lttng/wrapper/vmalloc.h @@ -0,0 +1,49 @@ +#ifndef _LTT_WRAPPER_VMALLOC_H +#define _LTT_WRAPPER_VMALLOC_H + +/* + * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers at efficios.com) + * + * wrapper around vmalloc_sync_all. Using KALLSYMS to get its address when + * available, else we need to have a kernel that exports this function to GPL + * modules. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef CONFIG_KALLSYMS + +#include <linux/kallsyms.h> +#include "kallsyms.h" + +static inline +void wrapper_vmalloc_sync_all(void) +{ + void (*vmalloc_sync_all_sym)(void); + + vmalloc_sync_all_sym = (void *) kallsyms_lookup_funcptr("vmalloc_sync_all"); + if (vmalloc_sync_all_sym) { + vmalloc_sync_all_sym(); + } else { +#ifdef CONFIG_X86 + /* + * Only x86 needs vmalloc_sync_all to make sure LTTng does not + * trigger recursive page faults. + */ + printk(KERN_WARNING "LTTng: vmalloc_sync_all symbol lookup failed.\n"); + printk(KERN_WARNING "Page fault handler and NMI tracing might trigger faults.\n"); +#endif + } +} +#else + +#include <linux/vmalloc.h> + +static inline +void wrapper_vmalloc_sync_all(void) +{ + return vmalloc_sync_all(); +} +#endif + +#endif /* _LTT_WRAPPER_VMALLOC_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 07/20] lttng wrappers 2011-11-28 12:42 ` [lttng-dev] [PATCH 07/20] lttng wrappers Mathieu Desnoyers @ 2011-11-29 1:04 ` Greg KH 2011-11-29 2:22 ` Mathieu Desnoyers 0 siblings, 1 reply; 25+ messages in thread From: Greg KH @ 2011-11-29 1:04 UTC (permalink / raw) On Mon, Nov 28, 2011 at 07:42:14AM -0500, Mathieu Desnoyers wrote: > Implement wrappers for compatibility with older kernel versions and > kernels with had the libringbuffer (old) patchset applied. > > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> Are these going to still be needed anymore, now that this code is in the kernel tree? thanks, greg kh ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 07/20] lttng wrappers 2011-11-29 1:04 ` Greg KH @ 2011-11-29 2:22 ` Mathieu Desnoyers 2011-11-30 6:23 ` Greg KH 0 siblings, 1 reply; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-29 2:22 UTC (permalink / raw) * Greg KH (greg at kroah.com) wrote: > On Mon, Nov 28, 2011 at 07:42:14AM -0500, Mathieu Desnoyers wrote: > > Implement wrappers for compatibility with older kernel versions and > > kernels with had the libringbuffer (old) patchset applied. > > > > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> > > Are these going to still be needed anymore, now that this code is in the > kernel tree? Hrm, this patch changelog could have been a bit more explicit. In addition to allow compatibility for older kernel versions, some wrappers deal with missing EXPORT_SYMBOL_GPL() from the core kernel. The TODO file details what should be done to eliminate those wrappers: 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. So hopefully we can look into adding these missing symbols to the core kernel. This would be much nicer, but this does not depend only on the lttng driver: it's up to the kernel to export those. Another option would be to create a CONFIG bool (y/n) object that wraps the missing core kernel symbols. However, this would require this support option to be selected at kernel build time in order to allow loading the lttng modules, and I doubt it's a good practice for a driver. As for those wrappers that deal more specifically with compatibility with older kernels, those aren't needed anymore, of course. Thoughts ? Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 07/20] lttng wrappers 2011-11-29 2:22 ` Mathieu Desnoyers @ 2011-11-30 6:23 ` Greg KH 0 siblings, 0 replies; 25+ messages in thread From: Greg KH @ 2011-11-30 6:23 UTC (permalink / raw) On Mon, Nov 28, 2011 at 09:22:13PM -0500, Mathieu Desnoyers wrote: > * Greg KH (greg at kroah.com) wrote: > > On Mon, Nov 28, 2011 at 07:42:14AM -0500, Mathieu Desnoyers wrote: > > > Implement wrappers for compatibility with older kernel versions and > > > kernels with had the libringbuffer (old) patchset applied. > > > > > > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> > > > > Are these going to still be needed anymore, now that this code is in the > > kernel tree? > > Hrm, this patch changelog could have been a bit more explicit. In > addition to allow compatibility for older kernel versions, some wrappers > deal with missing EXPORT_SYMBOL_GPL() from the core kernel. > > The TODO file details what should be done to eliminate those wrappers: > > 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. Ugh, that's crazy, but I understand. > So hopefully we can look into adding these missing symbols to the core > kernel. This would be much nicer, but this does not depend only on the > lttng driver: it's up to the kernel to export those. > > Another option would be to create a CONFIG bool (y/n) object that wraps > the missing core kernel symbols. However, this would require this > support option to be selected at kernel build time in order to allow > loading the lttng modules, and I doubt it's a good practice for a > driver. Yes, that's not good, we can just export the symbols as needed now that we have an in-kernel user. > As for those wrappers that deal more specifically with compatibility > with older kernels, those aren't needed anymore, of course. Great, please send patches to remove them before I get to it :) thanks, greg k-h ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 08/20] lttng instrumentation: tracepoint events 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (6 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 07/20] lttng wrappers Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 09/20] lttng: syscall instrumentation Mathieu Desnoyers ` (12 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Modifications to the in-kernel TRACE_EVENT are needed to generate the compact event descriptions and the probe code LTTng generates. These changes could apply to upstream TRACE_EVENT, but requires changing the in-kernel API. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- .../staging/lttng/instrumentation/events/README | 7 + .../instrumentation/events/lttng-module/block.h | 626 ++++++++++++++++++++ .../instrumentation/events/lttng-module/irq.h | 155 +++++ .../instrumentation/events/lttng-module/kvm.h | 312 ++++++++++ .../instrumentation/events/lttng-module/lttng.h | 34 ++ .../instrumentation/events/lttng-module/sched.h | 400 +++++++++++++ .../instrumentation/events/lttng-module/syscalls.h | 76 +++ .../lttng/instrumentation/events/mainline/block.h | 569 ++++++++++++++++++ .../lttng/instrumentation/events/mainline/irq.h | 150 +++++ .../lttng/instrumentation/events/mainline/kvm.h | 312 ++++++++++ .../lttng/instrumentation/events/mainline/sched.h | 397 +++++++++++++ .../instrumentation/events/mainline/syscalls.h | 75 +++ 12 files changed, 3113 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/instrumentation/events/README create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/block.h create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/irq.h create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/sched.h create mode 100644 drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/block.h create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/irq.h create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/kvm.h create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/sched.h create mode 100644 drivers/staging/lttng/instrumentation/events/mainline/syscalls.h diff --git a/drivers/staging/lttng/instrumentation/events/README b/drivers/staging/lttng/instrumentation/events/README new file mode 100644 index 0000000..dad2cbb --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/README @@ -0,0 +1,7 @@ +The workflow for updating patches from newer kernel: + +Diff mainline/ and lttng-module/ directories. + +Pull the new headers from mainline kernel to mainline/. +Copy them into lttng-modules. +Apply diff. Fix conflicts. diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/block.h b/drivers/staging/lttng/instrumentation/events/lttng-module/block.h new file mode 100644 index 0000000..42184f3 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/block.h @@ -0,0 +1,626 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM block + +#if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_BLOCK_H + +#include <linux/blktrace_api.h> +#include <linux/blkdev.h> +#include <linux/tracepoint.h> +#include <linux/trace_seq.h> + +#ifndef _TRACE_BLOCK_DEF_ +#define _TRACE_BLOCK_DEF_ + +#define __blk_dump_cmd(cmd, len) "<unknown>" + +enum { + RWBS_FLAG_WRITE = (1 << 0), + RWBS_FLAG_DISCARD = (1 << 1), + RWBS_FLAG_READ = (1 << 2), + RWBS_FLAG_RAHEAD = (1 << 3), + RWBS_FLAG_SYNC = (1 << 4), + RWBS_FLAG_META = (1 << 5), + RWBS_FLAG_SECURE = (1 << 6), +}; + +#endif /* _TRACE_BLOCK_DEF_ */ + +#define __print_rwbs_flags(rwbs) \ + __print_flags(rwbs, "", \ + { RWBS_FLAG_WRITE, "W" }, \ + { RWBS_FLAG_DISCARD, "D" }, \ + { RWBS_FLAG_READ, "R" }, \ + { RWBS_FLAG_RAHEAD, "A" }, \ + { RWBS_FLAG_SYNC, "S" }, \ + { RWBS_FLAG_META, "M" }, \ + { RWBS_FLAG_SECURE, "E" }) + +#define blk_fill_rwbs(rwbs, rw, bytes) \ + tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE : \ + ( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD : \ + ( (bytes) ? RWBS_FLAG_READ : \ + ( 0 )))) \ + | ((rw) & REQ_RAHEAD ? RWBS_FLAG_RAHEAD : 0) \ + | ((rw) & REQ_SYNC ? RWBS_FLAG_SYNC : 0) \ + | ((rw) & REQ_META ? RWBS_FLAG_META : 0) \ + | ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0)) + +DECLARE_EVENT_CLASS(block_rq_with_error, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( int, errors ) + __field( unsigned int, rwbs ) + __dynamic_array_hex( unsigned char, cmd, + (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + rq->cmd_len : 0) + ), + + TP_fast_assign( + tp_assign(dev, rq->rq_disk ? disk_devt(rq->rq_disk) : 0) + tp_assign(sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq)) + tp_assign(nr_sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq)) + tp_assign(errors, rq->errors) + blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq)) + tp_memcpy_dyn(cmd, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + rq->cmd : NULL); + ), + + TP_printk("%d,%d %s (%s) %llu + %u [%d]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + __blk_dump_cmd(__get_dynamic_array(cmd), + __get_dynamic_array_len(cmd)), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->errors) +) + +/** + * block_rq_abort - abort block operation request + * @q: queue containing the block operation request + * @rq: block IO operation request + * + * Called immediately after pending block IO operation request @rq in + * queue @q is aborted. The fields in the operation request @rq + * can be examined to determine which device and sectors the pending + * operation would access. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_abort, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +) + +/** + * block_rq_requeue - place block IO request back on a queue + * @q: queue holding operation + * @rq: block IO operation request + * + * The block operation request @rq is being placed back into queue + * @q. For some reason the request was not completed and needs to be + * put back in the queue. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_requeue, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +) + +/** + * block_rq_complete - block IO operation completed by device driver + * @q: queue containing the block operation request + * @rq: block operations request + * + * The block_rq_complete tracepoint event indicates that some portion + * of operation request has been completed by the device driver. If + * the @rq->bio is %NULL, then there is absolutely no additional work to + * do for the request. If @rq->bio is non-NULL then there is + * additional work required to complete the request. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_complete, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +) + +DECLARE_EVENT_CLASS(block_rq, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( unsigned int, bytes ) + __field( unsigned int, rwbs ) + __array_text( char, comm, TASK_COMM_LEN ) + __dynamic_array_hex( unsigned char, cmd, + (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + rq->cmd_len : 0) + ), + + TP_fast_assign( + tp_assign(dev, rq->rq_disk ? disk_devt(rq->rq_disk) : 0) + tp_assign(sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq)) + tp_assign(nr_sector, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq)) + tp_assign(bytes, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + blk_rq_bytes(rq) : 0) + blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq)) + tp_memcpy_dyn(cmd, (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + rq->cmd : NULL); + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("%d,%d %s %u (%s) %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + __entry->bytes, + __blk_dump_cmd(__get_dynamic_array(cmd), + __get_dynamic_array_len(cmd)), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +) + +/** + * block_rq_insert - insert block operation request into queue + * @q: target queue + * @rq: block IO operation request + * + * Called immediately before block operation request @rq is inserted + * into queue @q. The fields in the operation request @rq struct can + * be examined to determine which device and sectors the pending + * operation would access. + */ +DEFINE_EVENT(block_rq, block_rq_insert, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +) + +/** + * block_rq_issue - issue pending block IO request operation to device driver + * @q: queue holding operation + * @rq: block IO operation operation request + * + * Called when block operation request @rq from queue @q is sent to a + * device driver for processing. + */ +DEFINE_EVENT(block_rq, block_rq_issue, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +) + +/** + * block_bio_bounce - used bounce buffer when processing block operation + * @q: queue holding the block operation + * @bio: block operation + * + * A bounce buffer was used to handle the block operation @bio in @q. + * This occurs when hardware limitations prevent a direct transfer of + * data between the @bio data memory area and the IO device. Use of a + * bounce buffer requires extra copying of data and decreases + * performance. + */ +TRACE_EVENT(block_bio_bounce, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( unsigned int, rwbs ) + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_assign(dev, bio->bi_bdev ? + bio->bi_bdev->bd_dev : 0) + tp_assign(sector, bio->bi_sector) + tp_assign(nr_sector, bio->bi_size >> 9) + blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size) + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +) + +/** + * block_bio_complete - completed all work on the block operation + * @q: queue holding the block operation + * @bio: block operation completed + * @error: io error value + * + * This tracepoint indicates there is no further work to do on this + * block IO operation @bio. + */ +TRACE_EVENT(block_bio_complete, + + TP_PROTO(struct request_queue *q, struct bio *bio, int error), + + TP_ARGS(q, bio, error), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned, nr_sector ) + __field( int, error ) + __field( unsigned int, rwbs ) + ), + + TP_fast_assign( + tp_assign(dev, bio->bi_bdev->bd_dev) + tp_assign(sector, bio->bi_sector) + tp_assign(nr_sector, bio->bi_size >> 9) + tp_assign(error, error) + blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size) + ), + + TP_printk("%d,%d %s %llu + %u [%d]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->error) +) + +DECLARE_EVENT_CLASS(block_bio, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( unsigned int, rwbs ) + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_assign(dev, bio->bi_bdev->bd_dev) + tp_assign(sector, bio->bi_sector) + tp_assign(nr_sector, bio->bi_size >> 9) + blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size) + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +) + +/** + * block_bio_backmerge - merging block operation to the end of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block request @bio to the end of an existing block request + * in queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_backmerge, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +) + +/** + * block_bio_frontmerge - merging block operation to the beginning of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block IO operation @bio to the beginning of an existing block + * operation in queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_frontmerge, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +) + +/** + * block_bio_queue - putting new block IO operation in queue + * @q: queue holding operation + * @bio: new block operation + * + * About to place the block IO operation @bio into queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_queue, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +) + +DECLARE_EVENT_CLASS(block_get_rq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( unsigned int, rwbs ) + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_assign(dev, bio ? bio->bi_bdev->bd_dev : 0) + tp_assign(sector, bio ? bio->bi_sector : 0) + tp_assign(nr_sector, bio ? bio->bi_size >> 9 : 0) + blk_fill_rwbs(rwbs, bio ? bio->bi_rw : 0, + bio ? bio->bi_size >> 9 : 0) + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +) + +/** + * block_getrq - get a free request entry in queue for block IO operations + * @q: queue for operations + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * A request struct for queue @q has been allocated to handle the + * block IO operation @bio. + */ +DEFINE_EVENT(block_get_rq, block_getrq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw) +) + +/** + * block_sleeprq - waiting to get a free request entry in queue for block IO operation + * @q: queue for operation + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * In the case where a request struct cannot be provided for queue @q + * the process needs to wait for an request struct to become + * available. This tracepoint event is generated each time the + * process goes to sleep waiting for request struct become available. + */ +DEFINE_EVENT(block_get_rq, block_sleeprq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw) +) + +/** + * block_plug - keep operations requests in request queue + * @q: request queue to plug + * + * Plug the request queue @q. Do not allow block operation requests + * to be sent to the device driver. Instead, accumulate requests in + * the queue to improve throughput performance of the block device. + */ +TRACE_EVENT(block_plug, + + TP_PROTO(struct request_queue *q), + + TP_ARGS(q), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("[%s]", __entry->comm) +) + +DECLARE_EVENT_CLASS(block_unplug, + + TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit), + + TP_ARGS(q, depth, explicit), + + TP_STRUCT__entry( + __field( int, nr_rq ) + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_assign(nr_rq, depth) + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("[%s] %d", __entry->comm, __entry->nr_rq) +) + +/** + * block_unplug - release of operations requests in request queue + * @q: request queue to unplug + * @depth: number of requests just added to the queue + * @explicit: whether this was an explicit unplug, or one from schedule() + * + * Unplug request queue @q because device driver is scheduled to work + * on elements in the request queue. + */ +DEFINE_EVENT(block_unplug, block_unplug, + + TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit), + + TP_ARGS(q, depth, explicit) +) + +/** + * block_split - split a single bio struct into two bio structs + * @q: queue containing the bio + * @bio: block operation being split + * @new_sector: The starting sector for the new bio + * + * The bio request @bio in request queue @q needs to be split into two + * bio requests. The newly created @bio request starts at + * @new_sector. This split may be required due to hardware limitation + * such as operation crossing device boundaries in a RAID system. + */ +TRACE_EVENT(block_split, + + TP_PROTO(struct request_queue *q, struct bio *bio, + unsigned int new_sector), + + TP_ARGS(q, bio, new_sector), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( sector_t, new_sector ) + __field( unsigned int, rwbs ) + __array_text( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + tp_assign(dev, bio->bi_bdev->bd_dev) + tp_assign(sector, bio->bi_sector) + tp_assign(new_sector, new_sector) + blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size) + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + ), + + TP_printk("%d,%d %s %llu / %llu [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + (unsigned long long)__entry->new_sector, + __entry->comm) +) + +/** + * block_bio_remap - map request for a logical device to the raw device + * @q: queue holding the operation + * @bio: revised operation + * @dev: device for the operation + * @from: original sector for the operation + * + * An operation for a logical device has been mapped to the + * raw block device. + */ +TRACE_EVENT(block_bio_remap, + + TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, + sector_t from), + + TP_ARGS(q, bio, dev, from), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( dev_t, old_dev ) + __field( sector_t, old_sector ) + __field( unsigned int, rwbs ) + ), + + TP_fast_assign( + tp_assign(dev, bio->bi_bdev->bd_dev) + tp_assign(sector, bio->bi_sector) + tp_assign(nr_sector, bio->bi_size >> 9) + tp_assign(old_dev, dev) + tp_assign(old_sector, from) + blk_fill_rwbs(rwbs, bio->bi_rw, bio->bi_size) + ), + + TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, + MAJOR(__entry->old_dev), MINOR(__entry->old_dev), + (unsigned long long)__entry->old_sector) +) + +/** + * block_rq_remap - map request for a block operation request + * @q: queue holding the operation + * @rq: block IO operation request + * @dev: device for the operation + * @from: original sector for the operation + * + * The block operation request @rq in @q has been remapped. The block + * operation request @rq holds the current information and @from hold + * the original sector. + */ +TRACE_EVENT(block_rq_remap, + + TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, + sector_t from), + + TP_ARGS(q, rq, dev, from), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( dev_t, old_dev ) + __field( sector_t, old_sector ) + __field( unsigned int, rwbs ) + ), + + TP_fast_assign( + tp_assign(dev, disk_devt(rq->rq_disk)) + tp_assign(sector, blk_rq_pos(rq)) + tp_assign(nr_sector, blk_rq_sectors(rq)) + tp_assign(old_dev, dev) + tp_assign(old_sector, from) + blk_fill_rwbs(rwbs, rq->cmd_flags, blk_rq_bytes(rq)) + ), + + TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __print_rwbs_flags(__entry->rwbs), + (unsigned long long)__entry->sector, + __entry->nr_sector, + MAJOR(__entry->old_dev), MINOR(__entry->old_dev), + (unsigned long long)__entry->old_sector) +) + +#undef __print_rwbs_flags +#undef blk_fill_rwbs + +#endif /* _TRACE_BLOCK_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h b/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h new file mode 100644 index 0000000..344015d --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/irq.h @@ -0,0 +1,155 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM irq + +#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_IRQ_H + +#include <linux/tracepoint.h> + +#ifndef _TRACE_IRQ_DEF_ +#define _TRACE_IRQ_DEF_ + +struct irqaction; +struct softirq_action; + +#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } +#define show_softirq_name(val) \ + __print_symbolic(val, \ + softirq_name(HI), \ + softirq_name(TIMER), \ + softirq_name(NET_TX), \ + softirq_name(NET_RX), \ + softirq_name(BLOCK), \ + softirq_name(BLOCK_IOPOLL), \ + softirq_name(TASKLET), \ + softirq_name(SCHED), \ + softirq_name(HRTIMER), \ + softirq_name(RCU)) + +#endif /* _TRACE_IRQ_DEF_ */ + +/** + * irq_handler_entry - called immediately before the irq action handler + * @irq: irq number + * @action: pointer to struct irqaction + * + * The struct irqaction pointed to by @action contains various + * information about the handler, including the device name, + * @action->name, and the device id, @action->dev_id. When used in + * conjunction with the irq_handler_exit tracepoint, we can figure + * out irq handler latencies. + */ +TRACE_EVENT(irq_handler_entry, + + TP_PROTO(int irq, struct irqaction *action), + + TP_ARGS(irq, action), + + TP_STRUCT__entry( + __field( int, irq ) + __string( name, action->name ) + ), + + TP_fast_assign( + tp_assign(irq, irq) + tp_strcpy(name, action->name) + ), + + TP_printk("irq=%d name=%s", __entry->irq, __get_str(name)) +) + +/** + * irq_handler_exit - called immediately after the irq action handler returns + * @irq: irq number + * @action: pointer to struct irqaction + * @ret: return value + * + * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding + * @action->handler scuccessully handled this irq. Otherwise, the irq might be + * a shared irq line, or the irq was not handled successfully. Can be used in + * conjunction with the irq_handler_entry to understand irq handler latencies. + */ +TRACE_EVENT(irq_handler_exit, + + TP_PROTO(int irq, struct irqaction *action, int ret), + + TP_ARGS(irq, action, ret), + + TP_STRUCT__entry( + __field( int, irq ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(irq, irq) + tp_assign(ret, ret) + ), + + TP_printk("irq=%d ret=%s", + __entry->irq, __entry->ret ? "handled" : "unhandled") +) + +DECLARE_EVENT_CLASS(softirq, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr), + + TP_STRUCT__entry( + __field( unsigned int, vec ) + ), + + TP_fast_assign( + tp_assign(vec, vec_nr) + ), + + TP_printk("vec=%u [action=%s]", __entry->vec, + show_softirq_name(__entry->vec)) +) + +/** + * softirq_entry - called immediately before the softirq handler + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_exit tracepoint + * we can determine the softirq handler runtine. + */ +DEFINE_EVENT(softirq, softirq_entry, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +) + +/** + * softirq_exit - called immediately after the softirq handler returns + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_entry tracepoint + * we can determine the softirq handler runtine. + */ +DEFINE_EVENT(softirq, softirq_exit, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +) + +/** + * softirq_raise - called immediately when a softirq is raised + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_entry tracepoint + * we can determine the softirq raise to run latency. + */ +DEFINE_EVENT(softirq, softirq_raise, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +) + +#endif /* _TRACE_IRQ_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h b/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h new file mode 100644 index 0000000..e10455b --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/kvm.h @@ -0,0 +1,312 @@ +#if !defined(_TRACE_KVM_MAIN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KVM_MAIN_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kvm + +#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x } + +#define kvm_trace_exit_reason \ + ERSN(UNKNOWN), ERSN(EXCEPTION), ERSN(IO), ERSN(HYPERCALL), \ + ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN), \ + ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR), \ + ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\ + ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI) + +TRACE_EVENT(kvm_userspace_exit, + TP_PROTO(__u32 reason, int errno), + TP_ARGS(reason, errno), + + TP_STRUCT__entry( + __field( __u32, reason ) + __field( int, errno ) + ), + + TP_fast_assign( + tp_assign(reason, reason) + tp_assign(errno, errno) + ), + + TP_printk("reason %s (%d)", + __entry->errno < 0 ? + (__entry->errno == -EINTR ? "restart" : "error") : + __print_symbolic(__entry->reason, kvm_trace_exit_reason), + __entry->errno < 0 ? -__entry->errno : __entry->reason) +) + +#if defined(__KVM_HAVE_IOAPIC) +TRACE_EVENT(kvm_set_irq, + TP_PROTO(unsigned int gsi, int level, int irq_source_id), + TP_ARGS(gsi, level, irq_source_id), + + TP_STRUCT__entry( + __field( unsigned int, gsi ) + __field( int, level ) + __field( int, irq_source_id ) + ), + + TP_fast_assign( + tp_assign(gsi, gsi) + tp_assign(level, level) + tp_assign(irq_source_id, irq_source_id) + ), + + TP_printk("gsi %u level %d source %d", + __entry->gsi, __entry->level, __entry->irq_source_id) +) + +#define kvm_deliver_mode \ + {0x0, "Fixed"}, \ + {0x1, "LowPrio"}, \ + {0x2, "SMI"}, \ + {0x3, "Res3"}, \ + {0x4, "NMI"}, \ + {0x5, "INIT"}, \ + {0x6, "SIPI"}, \ + {0x7, "ExtINT"} + +TRACE_EVENT(kvm_ioapic_set_irq, + TP_PROTO(__u64 e, int pin, bool coalesced), + TP_ARGS(e, pin, coalesced), + + TP_STRUCT__entry( + __field( __u64, e ) + __field( int, pin ) + __field( bool, coalesced ) + ), + + TP_fast_assign( + tp_assign(e, e) + tp_assign(pin, pin) + tp_assign(coalesced, coalesced) + ), + + TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s", + __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e, + __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode), + (__entry->e & (1<<11)) ? "logical" : "physical", + (__entry->e & (1<<15)) ? "level" : "edge", + (__entry->e & (1<<16)) ? "|masked" : "", + __entry->coalesced ? " (coalesced)" : "") +) + +TRACE_EVENT(kvm_msi_set_irq, + TP_PROTO(__u64 address, __u64 data), + TP_ARGS(address, data), + + TP_STRUCT__entry( + __field( __u64, address ) + __field( __u64, data ) + ), + + TP_fast_assign( + tp_assign(address, address) + tp_assign(data, data) + ), + + TP_printk("dst %u vec %x (%s|%s|%s%s)", + (u8)(__entry->address >> 12), (u8)__entry->data, + __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode), + (__entry->address & (1<<2)) ? "logical" : "physical", + (__entry->data & (1<<15)) ? "level" : "edge", + (__entry->address & (1<<3)) ? "|rh" : "") +) + +#define kvm_irqchips \ + {KVM_IRQCHIP_PIC_MASTER, "PIC master"}, \ + {KVM_IRQCHIP_PIC_SLAVE, "PIC slave"}, \ + {KVM_IRQCHIP_IOAPIC, "IOAPIC"} + +TRACE_EVENT(kvm_ack_irq, + TP_PROTO(unsigned int irqchip, unsigned int pin), + TP_ARGS(irqchip, pin), + + TP_STRUCT__entry( + __field( unsigned int, irqchip ) + __field( unsigned int, pin ) + ), + + TP_fast_assign( + tp_assign(irqchip, irqchip) + tp_assign(pin, pin) + ), + + TP_printk("irqchip %s pin %u", + __print_symbolic(__entry->irqchip, kvm_irqchips), + __entry->pin) +) + + + +#endif /* defined(__KVM_HAVE_IOAPIC) */ + +#define KVM_TRACE_MMIO_READ_UNSATISFIED 0 +#define KVM_TRACE_MMIO_READ 1 +#define KVM_TRACE_MMIO_WRITE 2 + +#define kvm_trace_symbol_mmio \ + { KVM_TRACE_MMIO_READ_UNSATISFIED, "unsatisfied-read" }, \ + { KVM_TRACE_MMIO_READ, "read" }, \ + { KVM_TRACE_MMIO_WRITE, "write" } + +TRACE_EVENT(kvm_mmio, + TP_PROTO(int type, int len, u64 gpa, u64 val), + TP_ARGS(type, len, gpa, val), + + TP_STRUCT__entry( + __field( u32, type ) + __field( u32, len ) + __field( u64, gpa ) + __field( u64, val ) + ), + + TP_fast_assign( + tp_assign(type, type) + tp_assign(len, len) + tp_assign(gpa, gpa) + tp_assign(val, val) + ), + + TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx", + __print_symbolic(__entry->type, kvm_trace_symbol_mmio), + __entry->len, __entry->gpa, __entry->val) +) + +#define kvm_fpu_load_symbol \ + {0, "unload"}, \ + {1, "load"} + +TRACE_EVENT(kvm_fpu, + TP_PROTO(int load), + TP_ARGS(load), + + TP_STRUCT__entry( + __field( u32, load ) + ), + + TP_fast_assign( + tp_assign(load, load) + ), + + TP_printk("%s", __print_symbolic(__entry->load, kvm_fpu_load_symbol)) +) + +TRACE_EVENT(kvm_age_page, + TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref), + TP_ARGS(hva, slot, ref), + + TP_STRUCT__entry( + __field( u64, hva ) + __field( u64, gfn ) + __field( u8, referenced ) + ), + + TP_fast_assign( + tp_assign(hva, hva) + tp_assign(gfn, + slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT)) + tp_assign(referenced, ref) + ), + + TP_printk("hva %llx gfn %llx %s", + __entry->hva, __entry->gfn, + __entry->referenced ? "YOUNG" : "OLD") +) + +#ifdef CONFIG_KVM_ASYNC_PF +DECLARE_EVENT_CLASS(kvm_async_get_page_class, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn), + + TP_STRUCT__entry( + __field(__u64, gva) + __field(u64, gfn) + ), + + TP_fast_assign( + tp_assign(gva, gva) + tp_assign(gfn, gfn) + ), + + TP_printk("gva = %#llx, gfn = %#llx", __entry->gva, __entry->gfn) +) + +DEFINE_EVENT(kvm_async_get_page_class, kvm_try_async_get_page, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn) +) + +DEFINE_EVENT(kvm_async_get_page_class, kvm_async_pf_doublefault, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn) +) + +DECLARE_EVENT_CLASS(kvm_async_pf_nopresent_ready, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva), + + TP_STRUCT__entry( + __field(__u64, token) + __field(__u64, gva) + ), + + TP_fast_assign( + tp_assign(token, token) + tp_assign(gva, gva) + ), + + TP_printk("token %#llx gva %#llx", __entry->token, __entry->gva) + +) + +DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_not_present, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva) +) + +DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_ready, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva) +) + +TRACE_EVENT( + kvm_async_pf_completed, + TP_PROTO(unsigned long address, struct page *page, u64 gva), + TP_ARGS(address, page, gva), + + TP_STRUCT__entry( + __field(unsigned long, address) + __field(pfn_t, pfn) + __field(u64, gva) + ), + + TP_fast_assign( + tp_assign(address, address) + tp_assign(pfn, page ? page_to_pfn(page) : 0) + tp_assign(gva, gva) + ), + + TP_printk("gva %#llx address %#lx pfn %#llx", __entry->gva, + __entry->address, __entry->pfn) +) + +#endif + +#endif /* _TRACE_KVM_MAIN_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h b/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h new file mode 100644 index 0000000..6f3d6d1 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/lttng.h @@ -0,0 +1,34 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lttng + +#if !defined(_TRACE_LTTNG_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_LTTNG_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(lttng_metadata, + + TP_PROTO(const char *str), + + TP_ARGS(str), + + /* + * Not exactly a string: more a sequence of bytes (dynamic + * array) without the length. This is a dummy anyway: we only + * use this declaration to generate an event metadata entry. + */ + TP_STRUCT__entry( + __string( str, str ) + ), + + TP_fast_assign( + tp_strcpy(str, str) + ), + + TP_printk("") +) + +#endif /* _TRACE_LTTNG_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h b/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h new file mode 100644 index 0000000..33f6921 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/sched.h @@ -0,0 +1,400 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sched + +#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCHED_H + +#include <linux/sched.h> +#include <linux/tracepoint.h> + +#ifndef _TRACE_SCHED_DEF_ +#define _TRACE_SCHED_DEF_ + +static inline long __trace_sched_switch_state(struct task_struct *p) +{ + long state = p->state; + +#ifdef CONFIG_PREEMPT + /* + * For all intents and purposes a preempted task is a running task. + */ + if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) + state = TASK_RUNNING; +#endif + + return state; +} + +#endif /* _TRACE_SCHED_DEF_ */ + +/* + * Tracepoint for calling kthread_stop, performed to end a kthread: + */ +TRACE_EVENT(sched_kthread_stop, + + TP_PROTO(struct task_struct *t), + + TP_ARGS(t), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + ), + + TP_fast_assign( + tp_memcpy(comm, t->comm, TASK_COMM_LEN) + tp_assign(tid, t->pid) + ), + + TP_printk("comm=%s tid=%d", __entry->comm, __entry->tid) +) + +/* + * Tracepoint for the return value of the kthread stopping: + */ +TRACE_EVENT(sched_kthread_stop_ret, + + TP_PROTO(int ret), + + TP_ARGS(ret), + + TP_STRUCT__entry( + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ret, ret) + ), + + TP_printk("ret=%d", __entry->ret) +) + +/* + * Tracepoint for waking up a task: + */ +DECLARE_EVENT_CLASS(sched_wakeup_template, + + TP_PROTO(struct task_struct *p, int success), + + TP_ARGS(p, success), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( int, prio ) + __field( int, success ) + __field( int, target_cpu ) + ), + + TP_fast_assign( + tp_memcpy(comm, p->comm, TASK_COMM_LEN) + tp_assign(tid, p->pid) + tp_assign(prio, p->prio) + tp_assign(success, success) + tp_assign(target_cpu, task_cpu(p)) + ), + + TP_printk("comm=%s tid=%d prio=%d success=%d target_cpu=%03d", + __entry->comm, __entry->tid, __entry->prio, + __entry->success, __entry->target_cpu) +) + +DEFINE_EVENT(sched_wakeup_template, sched_wakeup, + TP_PROTO(struct task_struct *p, int success), + TP_ARGS(p, success)) + +/* + * Tracepoint for waking up a new task: + */ +DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new, + TP_PROTO(struct task_struct *p, int success), + TP_ARGS(p, success)) + +/* + * Tracepoint for task switches, performed by the scheduler: + */ +TRACE_EVENT(sched_switch, + + TP_PROTO(struct task_struct *prev, + struct task_struct *next), + + TP_ARGS(prev, next), + + TP_STRUCT__entry( + __array_text( char, prev_comm, TASK_COMM_LEN ) + __field( pid_t, prev_tid ) + __field( int, prev_prio ) + __field( long, prev_state ) + __array_text( char, next_comm, TASK_COMM_LEN ) + __field( pid_t, next_tid ) + __field( int, next_prio ) + ), + + TP_fast_assign( + tp_memcpy(next_comm, next->comm, TASK_COMM_LEN) + tp_assign(prev_tid, prev->pid) + tp_assign(prev_prio, prev->prio - MAX_RT_PRIO) + tp_assign(prev_state, __trace_sched_switch_state(prev)) + tp_memcpy(prev_comm, prev->comm, TASK_COMM_LEN) + tp_assign(next_tid, next->pid) + tp_assign(next_prio, next->prio - MAX_RT_PRIO) + ), + + TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_tid=%d next_prio=%d", + __entry->prev_comm, __entry->prev_tid, __entry->prev_prio, + __entry->prev_state ? + __print_flags(__entry->prev_state, "|", + { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, + { 16, "Z" }, { 32, "X" }, { 64, "x" }, + { 128, "W" }) : "R", + __entry->next_comm, __entry->next_tid, __entry->next_prio) +) + +/* + * Tracepoint for a task being migrated: + */ +TRACE_EVENT(sched_migrate_task, + + TP_PROTO(struct task_struct *p, int dest_cpu), + + TP_ARGS(p, dest_cpu), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( int, prio ) + __field( int, orig_cpu ) + __field( int, dest_cpu ) + ), + + TP_fast_assign( + tp_memcpy(comm, p->comm, TASK_COMM_LEN) + tp_assign(tid, p->pid) + tp_assign(prio, p->prio - MAX_RT_PRIO) + tp_assign(orig_cpu, task_cpu(p)) + tp_assign(dest_cpu, dest_cpu) + ), + + TP_printk("comm=%s tid=%d prio=%d orig_cpu=%d dest_cpu=%d", + __entry->comm, __entry->tid, __entry->prio, + __entry->orig_cpu, __entry->dest_cpu) +) + +DECLARE_EVENT_CLASS(sched_process_template, + + TP_PROTO(struct task_struct *p), + + TP_ARGS(p), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( int, prio ) + ), + + TP_fast_assign( + tp_memcpy(comm, p->comm, TASK_COMM_LEN) + tp_assign(tid, p->pid) + tp_assign(prio, p->prio - MAX_RT_PRIO) + ), + + TP_printk("comm=%s tid=%d prio=%d", + __entry->comm, __entry->tid, __entry->prio) +) + +/* + * Tracepoint for freeing a task: + */ +DEFINE_EVENT(sched_process_template, sched_process_free, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)) + + +/* + * Tracepoint for a task exiting: + */ +DEFINE_EVENT(sched_process_template, sched_process_exit, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)) + +/* + * Tracepoint for waiting on task to unschedule: + */ +DEFINE_EVENT(sched_process_template, sched_wait_task, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)) + +/* + * Tracepoint for a waiting task: + */ +TRACE_EVENT(sched_process_wait, + + TP_PROTO(struct pid *pid), + + TP_ARGS(pid), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( int, prio ) + ), + + TP_fast_assign( + tp_memcpy(comm, current->comm, TASK_COMM_LEN) + tp_assign(tid, pid_nr(pid)) + tp_assign(prio, current->prio - MAX_RT_PRIO) + ), + + TP_printk("comm=%s tid=%d prio=%d", + __entry->comm, __entry->tid, __entry->prio) +) + +/* + * Tracepoint for do_fork: + */ +TRACE_EVENT(sched_process_fork, + + TP_PROTO(struct task_struct *parent, struct task_struct *child), + + TP_ARGS(parent, child), + + TP_STRUCT__entry( + __array_text( char, parent_comm, TASK_COMM_LEN ) + __field( pid_t, parent_tid ) + __array_text( char, child_comm, TASK_COMM_LEN ) + __field( pid_t, child_tid ) + ), + + TP_fast_assign( + tp_memcpy(parent_comm, parent->comm, TASK_COMM_LEN) + tp_assign(parent_tid, parent->pid) + tp_memcpy(child_comm, child->comm, TASK_COMM_LEN) + tp_assign(child_tid, child->pid) + ), + + TP_printk("comm=%s tid=%d child_comm=%s child_tid=%d", + __entry->parent_comm, __entry->parent_tid, + __entry->child_comm, __entry->child_tid) +) + +/* + * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE + * adding sched_stat support to SCHED_FIFO/RR would be welcome. + */ +DECLARE_EVENT_CLASS(sched_stat_template, + + TP_PROTO(struct task_struct *tsk, u64 delay), + + TP_ARGS(tsk, delay), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( u64, delay ) + ), + + TP_fast_assign( + tp_memcpy(comm, tsk->comm, TASK_COMM_LEN) + tp_assign(tid, tsk->pid) + tp_assign(delay, delay) + ) + TP_perf_assign( + __perf_count(delay) + ), + + TP_printk("comm=%s tid=%d delay=%Lu [ns]", + __entry->comm, __entry->tid, + (unsigned long long)__entry->delay) +) + + +/* + * Tracepoint for accounting wait time (time the task is runnable + * but not actually running due to scheduler contention). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_wait, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)) + +/* + * Tracepoint for accounting sleep time (time the task is not runnable, + * including iowait, see below). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_sleep, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)) + +/* + * Tracepoint for accounting iowait time (time the task is not runnable + * due to waiting on IO to complete). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_iowait, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)) + +/* + * Tracepoint for accounting runtime (time the task is executing + * on a CPU). + */ +TRACE_EVENT(sched_stat_runtime, + + TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime), + + TP_ARGS(tsk, runtime, vruntime), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( u64, runtime ) + __field( u64, vruntime ) + ), + + TP_fast_assign( + tp_memcpy(comm, tsk->comm, TASK_COMM_LEN) + tp_assign(tid, tsk->pid) + tp_assign(runtime, runtime) + tp_assign(vruntime, vruntime) + ) + TP_perf_assign( + __perf_count(runtime) + ), + + TP_printk("comm=%s tid=%d runtime=%Lu [ns] vruntime=%Lu [ns]", + __entry->comm, __entry->tid, + (unsigned long long)__entry->runtime, + (unsigned long long)__entry->vruntime) +) + +/* + * Tracepoint for showing priority inheritance modifying a tasks + * priority. + */ +TRACE_EVENT(sched_pi_setprio, + + TP_PROTO(struct task_struct *tsk, int newprio), + + TP_ARGS(tsk, newprio), + + TP_STRUCT__entry( + __array_text( char, comm, TASK_COMM_LEN ) + __field( pid_t, tid ) + __field( int, oldprio ) + __field( int, newprio ) + ), + + TP_fast_assign( + tp_memcpy(comm, tsk->comm, TASK_COMM_LEN) + tp_assign(tid, tsk->pid) + tp_assign(oldprio, tsk->prio - MAX_RT_PRIO) + tp_assign(newprio, newprio - MAX_RT_PRIO) + ), + + TP_printk("comm=%s tid=%d oldprio=%d newprio=%d", + __entry->comm, __entry->tid, + __entry->oldprio, __entry->newprio) +) + +#endif /* _TRACE_SCHED_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h b/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h new file mode 100644 index 0000000..a2bb956 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/lttng-module/syscalls.h @@ -0,0 +1,76 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM raw_syscalls +#define TRACE_INCLUDE_FILE syscalls + +#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EVENTS_SYSCALLS_H + +#include <linux/tracepoint.h> + +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS + +#ifndef _TRACE_SYSCALLS_DEF_ +#define _TRACE_SYSCALLS_DEF_ + +#include <asm/ptrace.h> +#include <asm/syscall.h> + +#endif /* _TRACE_SYSCALLS_DEF_ */ + +TRACE_EVENT(sys_enter, + + TP_PROTO(struct pt_regs *regs, long id), + + TP_ARGS(regs, id), + + TP_STRUCT__entry( + __field( long, id ) + __array( unsigned long, args, 6 ) + ), + + TP_fast_assign( + tp_assign(id, id) + { + tp_memcpy(args, + ({ + unsigned long args_copy[6]; + syscall_get_arguments(current, regs, + 0, 6, args_copy); + args_copy; + }), 6 * sizeof(unsigned long)); + } + ), + + TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", + __entry->id, + __entry->args[0], __entry->args[1], __entry->args[2], + __entry->args[3], __entry->args[4], __entry->args[5]) +) + +TRACE_EVENT(sys_exit, + + TP_PROTO(struct pt_regs *regs, long ret), + + TP_ARGS(regs, ret), + + TP_STRUCT__entry( + __field( long, id ) + __field( long, ret ) + ), + + TP_fast_assign( + tp_assign(id, syscall_get_nr(current, regs)) + tp_assign(ret, ret) + ), + + TP_printk("NR %ld = %ld", + __entry->id, __entry->ret) +) + +#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ + +#endif /* _TRACE_EVENTS_SYSCALLS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + diff --git a/drivers/staging/lttng/instrumentation/events/mainline/block.h b/drivers/staging/lttng/instrumentation/events/mainline/block.h new file mode 100644 index 0000000..bf36654 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/mainline/block.h @@ -0,0 +1,569 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM block + +#if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_BLOCK_H + +#include <linux/blktrace_api.h> +#include <linux/blkdev.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(block_rq_with_error, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( int, errors ) + __array( char, rwbs, 6 ) + __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) + ), + + TP_fast_assign( + __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0; + __entry->sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq); + __entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq); + __entry->errors = rq->errors; + + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); + blk_dump_cmd(__get_str(cmd), rq); + ), + + TP_printk("%d,%d %s (%s) %llu + %u [%d]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->rwbs, __get_str(cmd), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->errors) +); + +/** + * block_rq_abort - abort block operation request + * @q: queue containing the block operation request + * @rq: block IO operation request + * + * Called immediately after pending block IO operation request @rq in + * queue @q is aborted. The fields in the operation request @rq + * can be examined to determine which device and sectors the pending + * operation would access. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_abort, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +); + +/** + * block_rq_requeue - place block IO request back on a queue + * @q: queue holding operation + * @rq: block IO operation request + * + * The block operation request @rq is being placed back into queue + * @q. For some reason the request was not completed and needs to be + * put back in the queue. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_requeue, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +); + +/** + * block_rq_complete - block IO operation completed by device driver + * @q: queue containing the block operation request + * @rq: block operations request + * + * The block_rq_complete tracepoint event indicates that some portion + * of operation request has been completed by the device driver. If + * the @rq->bio is %NULL, then there is absolutely no additional work to + * do for the request. If @rq->bio is non-NULL then there is + * additional work required to complete the request. + */ +DEFINE_EVENT(block_rq_with_error, block_rq_complete, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +); + +DECLARE_EVENT_CLASS(block_rq, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( unsigned int, bytes ) + __array( char, rwbs, 6 ) + __array( char, comm, TASK_COMM_LEN ) + __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) + ), + + TP_fast_assign( + __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0; + __entry->sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq); + __entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq); + __entry->bytes = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + blk_rq_bytes(rq) : 0; + + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); + blk_dump_cmd(__get_str(cmd), rq); + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("%d,%d %s %u (%s) %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->rwbs, __entry->bytes, __get_str(cmd), + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +); + +/** + * block_rq_insert - insert block operation request into queue + * @q: target queue + * @rq: block IO operation request + * + * Called immediately before block operation request @rq is inserted + * into queue @q. The fields in the operation request @rq struct can + * be examined to determine which device and sectors the pending + * operation would access. + */ +DEFINE_EVENT(block_rq, block_rq_insert, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +); + +/** + * block_rq_issue - issue pending block IO request operation to device driver + * @q: queue holding operation + * @rq: block IO operation operation request + * + * Called when block operation request @rq from queue @q is sent to a + * device driver for processing. + */ +DEFINE_EVENT(block_rq, block_rq_issue, + + TP_PROTO(struct request_queue *q, struct request *rq), + + TP_ARGS(q, rq) +); + +/** + * block_bio_bounce - used bounce buffer when processing block operation + * @q: queue holding the block operation + * @bio: block operation + * + * A bounce buffer was used to handle the block operation @bio in @q. + * This occurs when hardware limitations prevent a direct transfer of + * data between the @bio data memory area and the IO device. Use of a + * bounce buffer requires extra copying of data and decreases + * performance. + */ +TRACE_EVENT(block_bio_bounce, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __array( char, rwbs, 6 ) + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + __entry->dev = bio->bi_bdev ? + bio->bi_bdev->bd_dev : 0; + __entry->sector = bio->bi_sector; + __entry->nr_sector = bio->bi_size >> 9; + blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +); + +/** + * block_bio_complete - completed all work on the block operation + * @q: queue holding the block operation + * @bio: block operation completed + * @error: io error value + * + * This tracepoint indicates there is no further work to do on this + * block IO operation @bio. + */ +TRACE_EVENT(block_bio_complete, + + TP_PROTO(struct request_queue *q, struct bio *bio, int error), + + TP_ARGS(q, bio, error), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned, nr_sector ) + __field( int, error ) + __array( char, rwbs, 6 ) + ), + + TP_fast_assign( + __entry->dev = bio->bi_bdev->bd_dev; + __entry->sector = bio->bi_sector; + __entry->nr_sector = bio->bi_size >> 9; + __entry->error = error; + blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); + ), + + TP_printk("%d,%d %s %llu + %u [%d]", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->error) +); + +DECLARE_EVENT_CLASS(block_bio, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __array( char, rwbs, 6 ) + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + __entry->dev = bio->bi_bdev->bd_dev; + __entry->sector = bio->bi_sector; + __entry->nr_sector = bio->bi_size >> 9; + blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +); + +/** + * block_bio_backmerge - merging block operation to the end of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block request @bio to the end of an existing block request + * in queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_backmerge, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +); + +/** + * block_bio_frontmerge - merging block operation to the beginning of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block IO operation @bio to the beginning of an existing block + * operation in queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_frontmerge, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +); + +/** + * block_bio_queue - putting new block IO operation in queue + * @q: queue holding operation + * @bio: new block operation + * + * About to place the block IO operation @bio into queue @q. + */ +DEFINE_EVENT(block_bio, block_bio_queue, + + TP_PROTO(struct request_queue *q, struct bio *bio), + + TP_ARGS(q, bio) +); + +DECLARE_EVENT_CLASS(block_get_rq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __array( char, rwbs, 6 ) + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + __entry->dev = bio ? bio->bi_bdev->bd_dev : 0; + __entry->sector = bio ? bio->bi_sector : 0; + __entry->nr_sector = bio ? bio->bi_size >> 9 : 0; + blk_fill_rwbs(__entry->rwbs, + bio ? bio->bi_rw : 0, __entry->nr_sector); + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("%d,%d %s %llu + %u [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, __entry->comm) +); + +/** + * block_getrq - get a free request entry in queue for block IO operations + * @q: queue for operations + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * A request struct for queue @q has been allocated to handle the + * block IO operation @bio. + */ +DEFINE_EVENT(block_get_rq, block_getrq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw) +); + +/** + * block_sleeprq - waiting to get a free request entry in queue for block IO operation + * @q: queue for operation + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * In the case where a request struct cannot be provided for queue @q + * the process needs to wait for an request struct to become + * available. This tracepoint event is generated each time the + * process goes to sleep waiting for request struct become available. + */ +DEFINE_EVENT(block_get_rq, block_sleeprq, + + TP_PROTO(struct request_queue *q, struct bio *bio, int rw), + + TP_ARGS(q, bio, rw) +); + +/** + * block_plug - keep operations requests in request queue + * @q: request queue to plug + * + * Plug the request queue @q. Do not allow block operation requests + * to be sent to the device driver. Instead, accumulate requests in + * the queue to improve throughput performance of the block device. + */ +TRACE_EVENT(block_plug, + + TP_PROTO(struct request_queue *q), + + TP_ARGS(q), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("[%s]", __entry->comm) +); + +DECLARE_EVENT_CLASS(block_unplug, + + TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit), + + TP_ARGS(q, depth, explicit), + + TP_STRUCT__entry( + __field( int, nr_rq ) + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + __entry->nr_rq = depth; + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("[%s] %d", __entry->comm, __entry->nr_rq) +); + +/** + * block_unplug - release of operations requests in request queue + * @q: request queue to unplug + * @depth: number of requests just added to the queue + * @explicit: whether this was an explicit unplug, or one from schedule() + * + * Unplug request queue @q because device driver is scheduled to work + * on elements in the request queue. + */ +DEFINE_EVENT(block_unplug, block_unplug, + + TP_PROTO(struct request_queue *q, unsigned int depth, bool explicit), + + TP_ARGS(q, depth, explicit) +); + +/** + * block_split - split a single bio struct into two bio structs + * @q: queue containing the bio + * @bio: block operation being split + * @new_sector: The starting sector for the new bio + * + * The bio request @bio in request queue @q needs to be split into two + * bio requests. The newly created @bio request starts at + * @new_sector. This split may be required due to hardware limitation + * such as operation crossing device boundaries in a RAID system. + */ +TRACE_EVENT(block_split, + + TP_PROTO(struct request_queue *q, struct bio *bio, + unsigned int new_sector), + + TP_ARGS(q, bio, new_sector), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( sector_t, new_sector ) + __array( char, rwbs, 6 ) + __array( char, comm, TASK_COMM_LEN ) + ), + + TP_fast_assign( + __entry->dev = bio->bi_bdev->bd_dev; + __entry->sector = bio->bi_sector; + __entry->new_sector = new_sector; + blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + ), + + TP_printk("%d,%d %s %llu / %llu [%s]", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + (unsigned long long)__entry->new_sector, + __entry->comm) +); + +/** + * block_bio_remap - map request for a logical device to the raw device + * @q: queue holding the operation + * @bio: revised operation + * @dev: device for the operation + * @from: original sector for the operation + * + * An operation for a logical device has been mapped to the + * raw block device. + */ +TRACE_EVENT(block_bio_remap, + + TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, + sector_t from), + + TP_ARGS(q, bio, dev, from), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( dev_t, old_dev ) + __field( sector_t, old_sector ) + __array( char, rwbs, 6 ) + ), + + TP_fast_assign( + __entry->dev = bio->bi_bdev->bd_dev; + __entry->sector = bio->bi_sector; + __entry->nr_sector = bio->bi_size >> 9; + __entry->old_dev = dev; + __entry->old_sector = from; + blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size); + ), + + TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, + MAJOR(__entry->old_dev), MINOR(__entry->old_dev), + (unsigned long long)__entry->old_sector) +); + +/** + * block_rq_remap - map request for a block operation request + * @q: queue holding the operation + * @rq: block IO operation request + * @dev: device for the operation + * @from: original sector for the operation + * + * The block operation request @rq in @q has been remapped. The block + * operation request @rq holds the current information and @from hold + * the original sector. + */ +TRACE_EVENT(block_rq_remap, + + TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, + sector_t from), + + TP_ARGS(q, rq, dev, from), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( sector_t, sector ) + __field( unsigned int, nr_sector ) + __field( dev_t, old_dev ) + __field( sector_t, old_sector ) + __array( char, rwbs, 6 ) + ), + + TP_fast_assign( + __entry->dev = disk_devt(rq->rq_disk); + __entry->sector = blk_rq_pos(rq); + __entry->nr_sector = blk_rq_sectors(rq); + __entry->old_dev = dev; + __entry->old_sector = from; + blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq)); + ), + + TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, + (unsigned long long)__entry->sector, + __entry->nr_sector, + MAJOR(__entry->old_dev), MINOR(__entry->old_dev), + (unsigned long long)__entry->old_sector) +); + +#endif /* _TRACE_BLOCK_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> + diff --git a/drivers/staging/lttng/instrumentation/events/mainline/irq.h b/drivers/staging/lttng/instrumentation/events/mainline/irq.h new file mode 100644 index 0000000..1c09820 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/mainline/irq.h @@ -0,0 +1,150 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM irq + +#if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_IRQ_H + +#include <linux/tracepoint.h> + +struct irqaction; +struct softirq_action; + +#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } +#define show_softirq_name(val) \ + __print_symbolic(val, \ + softirq_name(HI), \ + softirq_name(TIMER), \ + softirq_name(NET_TX), \ + softirq_name(NET_RX), \ + softirq_name(BLOCK), \ + softirq_name(BLOCK_IOPOLL), \ + softirq_name(TASKLET), \ + softirq_name(SCHED), \ + softirq_name(HRTIMER), \ + softirq_name(RCU)) + +/** + * irq_handler_entry - called immediately before the irq action handler + * @irq: irq number + * @action: pointer to struct irqaction + * + * The struct irqaction pointed to by @action contains various + * information about the handler, including the device name, + * @action->name, and the device id, @action->dev_id. When used in + * conjunction with the irq_handler_exit tracepoint, we can figure + * out irq handler latencies. + */ +TRACE_EVENT(irq_handler_entry, + + TP_PROTO(int irq, struct irqaction *action), + + TP_ARGS(irq, action), + + TP_STRUCT__entry( + __field( int, irq ) + __string( name, action->name ) + ), + + TP_fast_assign( + __entry->irq = irq; + __assign_str(name, action->name); + ), + + TP_printk("irq=%d name=%s", __entry->irq, __get_str(name)) +); + +/** + * irq_handler_exit - called immediately after the irq action handler returns + * @irq: irq number + * @action: pointer to struct irqaction + * @ret: return value + * + * If the @ret value is set to IRQ_HANDLED, then we know that the corresponding + * @action->handler scuccessully handled this irq. Otherwise, the irq might be + * a shared irq line, or the irq was not handled successfully. Can be used in + * conjunction with the irq_handler_entry to understand irq handler latencies. + */ +TRACE_EVENT(irq_handler_exit, + + TP_PROTO(int irq, struct irqaction *action, int ret), + + TP_ARGS(irq, action, ret), + + TP_STRUCT__entry( + __field( int, irq ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->irq = irq; + __entry->ret = ret; + ), + + TP_printk("irq=%d ret=%s", + __entry->irq, __entry->ret ? "handled" : "unhandled") +); + +DECLARE_EVENT_CLASS(softirq, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr), + + TP_STRUCT__entry( + __field( unsigned int, vec ) + ), + + TP_fast_assign( + __entry->vec = vec_nr; + ), + + TP_printk("vec=%u [action=%s]", __entry->vec, + show_softirq_name(__entry->vec)) +); + +/** + * softirq_entry - called immediately before the softirq handler + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_exit tracepoint + * we can determine the softirq handler runtine. + */ +DEFINE_EVENT(softirq, softirq_entry, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +); + +/** + * softirq_exit - called immediately after the softirq handler returns + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_entry tracepoint + * we can determine the softirq handler runtine. + */ +DEFINE_EVENT(softirq, softirq_exit, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +); + +/** + * softirq_raise - called immediately when a softirq is raised + * @vec_nr: softirq vector number + * + * When used in combination with the softirq_entry tracepoint + * we can determine the softirq raise to run latency. + */ +DEFINE_EVENT(softirq, softirq_raise, + + TP_PROTO(unsigned int vec_nr), + + TP_ARGS(vec_nr) +); + +#endif /* _TRACE_IRQ_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/staging/lttng/instrumentation/events/mainline/kvm.h b/drivers/staging/lttng/instrumentation/events/mainline/kvm.h new file mode 100644 index 0000000..46e3cd8 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/mainline/kvm.h @@ -0,0 +1,312 @@ +#if !defined(_TRACE_KVM_MAIN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KVM_MAIN_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kvm + +#define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x } + +#define kvm_trace_exit_reason \ + ERSN(UNKNOWN), ERSN(EXCEPTION), ERSN(IO), ERSN(HYPERCALL), \ + ERSN(DEBUG), ERSN(HLT), ERSN(MMIO), ERSN(IRQ_WINDOW_OPEN), \ + ERSN(SHUTDOWN), ERSN(FAIL_ENTRY), ERSN(INTR), ERSN(SET_TPR), \ + ERSN(TPR_ACCESS), ERSN(S390_SIEIC), ERSN(S390_RESET), ERSN(DCR),\ + ERSN(NMI), ERSN(INTERNAL_ERROR), ERSN(OSI) + +TRACE_EVENT(kvm_userspace_exit, + TP_PROTO(__u32 reason, int errno), + TP_ARGS(reason, errno), + + TP_STRUCT__entry( + __field( __u32, reason ) + __field( int, errno ) + ), + + TP_fast_assign( + __entry->reason = reason; + __entry->errno = errno; + ), + + TP_printk("reason %s (%d)", + __entry->errno < 0 ? + (__entry->errno == -EINTR ? "restart" : "error") : + __print_symbolic(__entry->reason, kvm_trace_exit_reason), + __entry->errno < 0 ? -__entry->errno : __entry->reason) +); + +#if defined(__KVM_HAVE_IOAPIC) +TRACE_EVENT(kvm_set_irq, + TP_PROTO(unsigned int gsi, int level, int irq_source_id), + TP_ARGS(gsi, level, irq_source_id), + + TP_STRUCT__entry( + __field( unsigned int, gsi ) + __field( int, level ) + __field( int, irq_source_id ) + ), + + TP_fast_assign( + __entry->gsi = gsi; + __entry->level = level; + __entry->irq_source_id = irq_source_id; + ), + + TP_printk("gsi %u level %d source %d", + __entry->gsi, __entry->level, __entry->irq_source_id) +); + +#define kvm_deliver_mode \ + {0x0, "Fixed"}, \ + {0x1, "LowPrio"}, \ + {0x2, "SMI"}, \ + {0x3, "Res3"}, \ + {0x4, "NMI"}, \ + {0x5, "INIT"}, \ + {0x6, "SIPI"}, \ + {0x7, "ExtINT"} + +TRACE_EVENT(kvm_ioapic_set_irq, + TP_PROTO(__u64 e, int pin, bool coalesced), + TP_ARGS(e, pin, coalesced), + + TP_STRUCT__entry( + __field( __u64, e ) + __field( int, pin ) + __field( bool, coalesced ) + ), + + TP_fast_assign( + __entry->e = e; + __entry->pin = pin; + __entry->coalesced = coalesced; + ), + + TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s", + __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e, + __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode), + (__entry->e & (1<<11)) ? "logical" : "physical", + (__entry->e & (1<<15)) ? "level" : "edge", + (__entry->e & (1<<16)) ? "|masked" : "", + __entry->coalesced ? " (coalesced)" : "") +); + +TRACE_EVENT(kvm_msi_set_irq, + TP_PROTO(__u64 address, __u64 data), + TP_ARGS(address, data), + + TP_STRUCT__entry( + __field( __u64, address ) + __field( __u64, data ) + ), + + TP_fast_assign( + __entry->address = address; + __entry->data = data; + ), + + TP_printk("dst %u vec %x (%s|%s|%s%s)", + (u8)(__entry->address >> 12), (u8)__entry->data, + __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode), + (__entry->address & (1<<2)) ? "logical" : "physical", + (__entry->data & (1<<15)) ? "level" : "edge", + (__entry->address & (1<<3)) ? "|rh" : "") +); + +#define kvm_irqchips \ + {KVM_IRQCHIP_PIC_MASTER, "PIC master"}, \ + {KVM_IRQCHIP_PIC_SLAVE, "PIC slave"}, \ + {KVM_IRQCHIP_IOAPIC, "IOAPIC"} + +TRACE_EVENT(kvm_ack_irq, + TP_PROTO(unsigned int irqchip, unsigned int pin), + TP_ARGS(irqchip, pin), + + TP_STRUCT__entry( + __field( unsigned int, irqchip ) + __field( unsigned int, pin ) + ), + + TP_fast_assign( + __entry->irqchip = irqchip; + __entry->pin = pin; + ), + + TP_printk("irqchip %s pin %u", + __print_symbolic(__entry->irqchip, kvm_irqchips), + __entry->pin) +); + + + +#endif /* defined(__KVM_HAVE_IOAPIC) */ + +#define KVM_TRACE_MMIO_READ_UNSATISFIED 0 +#define KVM_TRACE_MMIO_READ 1 +#define KVM_TRACE_MMIO_WRITE 2 + +#define kvm_trace_symbol_mmio \ + { KVM_TRACE_MMIO_READ_UNSATISFIED, "unsatisfied-read" }, \ + { KVM_TRACE_MMIO_READ, "read" }, \ + { KVM_TRACE_MMIO_WRITE, "write" } + +TRACE_EVENT(kvm_mmio, + TP_PROTO(int type, int len, u64 gpa, u64 val), + TP_ARGS(type, len, gpa, val), + + TP_STRUCT__entry( + __field( u32, type ) + __field( u32, len ) + __field( u64, gpa ) + __field( u64, val ) + ), + + TP_fast_assign( + __entry->type = type; + __entry->len = len; + __entry->gpa = gpa; + __entry->val = val; + ), + + TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx", + __print_symbolic(__entry->type, kvm_trace_symbol_mmio), + __entry->len, __entry->gpa, __entry->val) +); + +#define kvm_fpu_load_symbol \ + {0, "unload"}, \ + {1, "load"} + +TRACE_EVENT(kvm_fpu, + TP_PROTO(int load), + TP_ARGS(load), + + TP_STRUCT__entry( + __field( u32, load ) + ), + + TP_fast_assign( + __entry->load = load; + ), + + TP_printk("%s", __print_symbolic(__entry->load, kvm_fpu_load_symbol)) +); + +TRACE_EVENT(kvm_age_page, + TP_PROTO(ulong hva, struct kvm_memory_slot *slot, int ref), + TP_ARGS(hva, slot, ref), + + TP_STRUCT__entry( + __field( u64, hva ) + __field( u64, gfn ) + __field( u8, referenced ) + ), + + TP_fast_assign( + __entry->hva = hva; + __entry->gfn = + slot->base_gfn + ((hva - slot->userspace_addr) >> PAGE_SHIFT); + __entry->referenced = ref; + ), + + TP_printk("hva %llx gfn %llx %s", + __entry->hva, __entry->gfn, + __entry->referenced ? "YOUNG" : "OLD") +); + +#ifdef CONFIG_KVM_ASYNC_PF +DECLARE_EVENT_CLASS(kvm_async_get_page_class, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn), + + TP_STRUCT__entry( + __field(__u64, gva) + __field(u64, gfn) + ), + + TP_fast_assign( + __entry->gva = gva; + __entry->gfn = gfn; + ), + + TP_printk("gva = %#llx, gfn = %#llx", __entry->gva, __entry->gfn) +); + +DEFINE_EVENT(kvm_async_get_page_class, kvm_try_async_get_page, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn) +); + +DEFINE_EVENT(kvm_async_get_page_class, kvm_async_pf_doublefault, + + TP_PROTO(u64 gva, u64 gfn), + + TP_ARGS(gva, gfn) +); + +DECLARE_EVENT_CLASS(kvm_async_pf_nopresent_ready, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva), + + TP_STRUCT__entry( + __field(__u64, token) + __field(__u64, gva) + ), + + TP_fast_assign( + __entry->token = token; + __entry->gva = gva; + ), + + TP_printk("token %#llx gva %#llx", __entry->token, __entry->gva) + +); + +DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_not_present, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva) +); + +DEFINE_EVENT(kvm_async_pf_nopresent_ready, kvm_async_pf_ready, + + TP_PROTO(u64 token, u64 gva), + + TP_ARGS(token, gva) +); + +TRACE_EVENT( + kvm_async_pf_completed, + TP_PROTO(unsigned long address, struct page *page, u64 gva), + TP_ARGS(address, page, gva), + + TP_STRUCT__entry( + __field(unsigned long, address) + __field(pfn_t, pfn) + __field(u64, gva) + ), + + TP_fast_assign( + __entry->address = address; + __entry->pfn = page ? page_to_pfn(page) : 0; + __entry->gva = gva; + ), + + TP_printk("gva %#llx address %#lx pfn %#llx", __entry->gva, + __entry->address, __entry->pfn) +); + +#endif + +#endif /* _TRACE_KVM_MAIN_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/staging/lttng/instrumentation/events/mainline/sched.h b/drivers/staging/lttng/instrumentation/events/mainline/sched.h new file mode 100644 index 0000000..f633478 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/mainline/sched.h @@ -0,0 +1,397 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sched + +#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCHED_H + +#include <linux/sched.h> +#include <linux/tracepoint.h> + +/* + * Tracepoint for calling kthread_stop, performed to end a kthread: + */ +TRACE_EVENT(sched_kthread_stop, + + TP_PROTO(struct task_struct *t), + + TP_ARGS(t), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + ), + + TP_fast_assign( + memcpy(__entry->comm, t->comm, TASK_COMM_LEN); + __entry->pid = t->pid; + ), + + TP_printk("comm=%s pid=%d", __entry->comm, __entry->pid) +); + +/* + * Tracepoint for the return value of the kthread stopping: + */ +TRACE_EVENT(sched_kthread_stop_ret, + + TP_PROTO(int ret), + + TP_ARGS(ret), + + TP_STRUCT__entry( + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ret = ret; + ), + + TP_printk("ret=%d", __entry->ret) +); + +/* + * Tracepoint for waking up a task: + */ +DECLARE_EVENT_CLASS(sched_wakeup_template, + + TP_PROTO(struct task_struct *p, int success), + + TP_ARGS(p, success), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + __field( int, success ) + __field( int, target_cpu ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->success = success; + __entry->target_cpu = task_cpu(p); + ), + + TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d", + __entry->comm, __entry->pid, __entry->prio, + __entry->success, __entry->target_cpu) +); + +DEFINE_EVENT(sched_wakeup_template, sched_wakeup, + TP_PROTO(struct task_struct *p, int success), + TP_ARGS(p, success)); + +/* + * Tracepoint for waking up a new task: + */ +DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new, + TP_PROTO(struct task_struct *p, int success), + TP_ARGS(p, success)); + +#ifdef CREATE_TRACE_POINTS +static inline long __trace_sched_switch_state(struct task_struct *p) +{ + long state = p->state; + +#ifdef CONFIG_PREEMPT + /* + * For all intents and purposes a preempted task is a running task. + */ + if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) + state = TASK_RUNNING; +#endif + + return state; +} +#endif + +/* + * Tracepoint for task switches, performed by the scheduler: + */ +TRACE_EVENT(sched_switch, + + TP_PROTO(struct task_struct *prev, + struct task_struct *next), + + TP_ARGS(prev, next), + + TP_STRUCT__entry( + __array( char, prev_comm, TASK_COMM_LEN ) + __field( pid_t, prev_pid ) + __field( int, prev_prio ) + __field( long, prev_state ) + __array( char, next_comm, TASK_COMM_LEN ) + __field( pid_t, next_pid ) + __field( int, next_prio ) + ), + + TP_fast_assign( + memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); + __entry->prev_pid = prev->pid; + __entry->prev_prio = prev->prio; + __entry->prev_state = __trace_sched_switch_state(prev); + memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); + __entry->next_pid = next->pid; + __entry->next_prio = next->prio; + ), + + TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d next_prio=%d", + __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, + __entry->prev_state ? + __print_flags(__entry->prev_state, "|", + { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, + { 16, "Z" }, { 32, "X" }, { 64, "x" }, + { 128, "W" }) : "R", + __entry->next_comm, __entry->next_pid, __entry->next_prio) +); + +/* + * Tracepoint for a task being migrated: + */ +TRACE_EVENT(sched_migrate_task, + + TP_PROTO(struct task_struct *p, int dest_cpu), + + TP_ARGS(p, dest_cpu), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + __field( int, orig_cpu ) + __field( int, dest_cpu ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->orig_cpu = task_cpu(p); + __entry->dest_cpu = dest_cpu; + ), + + TP_printk("comm=%s pid=%d prio=%d orig_cpu=%d dest_cpu=%d", + __entry->comm, __entry->pid, __entry->prio, + __entry->orig_cpu, __entry->dest_cpu) +); + +DECLARE_EVENT_CLASS(sched_process_template, + + TP_PROTO(struct task_struct *p), + + TP_ARGS(p), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + ), + + TP_printk("comm=%s pid=%d prio=%d", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for freeing a task: + */ +DEFINE_EVENT(sched_process_template, sched_process_free, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)); + + +/* + * Tracepoint for a task exiting: + */ +DEFINE_EVENT(sched_process_template, sched_process_exit, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)); + +/* + * Tracepoint for waiting on task to unschedule: + */ +DEFINE_EVENT(sched_process_template, sched_wait_task, + TP_PROTO(struct task_struct *p), + TP_ARGS(p)); + +/* + * Tracepoint for a waiting task: + */ +TRACE_EVENT(sched_process_wait, + + TP_PROTO(struct pid *pid), + + TP_ARGS(pid), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, prio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, current->comm, TASK_COMM_LEN); + __entry->pid = pid_nr(pid); + __entry->prio = current->prio; + ), + + TP_printk("comm=%s pid=%d prio=%d", + __entry->comm, __entry->pid, __entry->prio) +); + +/* + * Tracepoint for do_fork: + */ +TRACE_EVENT(sched_process_fork, + + TP_PROTO(struct task_struct *parent, struct task_struct *child), + + TP_ARGS(parent, child), + + TP_STRUCT__entry( + __array( char, parent_comm, TASK_COMM_LEN ) + __field( pid_t, parent_pid ) + __array( char, child_comm, TASK_COMM_LEN ) + __field( pid_t, child_pid ) + ), + + TP_fast_assign( + memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN); + __entry->parent_pid = parent->pid; + memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN); + __entry->child_pid = child->pid; + ), + + TP_printk("comm=%s pid=%d child_comm=%s child_pid=%d", + __entry->parent_comm, __entry->parent_pid, + __entry->child_comm, __entry->child_pid) +); + +/* + * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE + * adding sched_stat support to SCHED_FIFO/RR would be welcome. + */ +DECLARE_EVENT_CLASS(sched_stat_template, + + TP_PROTO(struct task_struct *tsk, u64 delay), + + TP_ARGS(tsk, delay), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( u64, delay ) + ), + + TP_fast_assign( + memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN); + __entry->pid = tsk->pid; + __entry->delay = delay; + ) + TP_perf_assign( + __perf_count(delay); + ), + + TP_printk("comm=%s pid=%d delay=%Lu [ns]", + __entry->comm, __entry->pid, + (unsigned long long)__entry->delay) +); + + +/* + * Tracepoint for accounting wait time (time the task is runnable + * but not actually running due to scheduler contention). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_wait, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)); + +/* + * Tracepoint for accounting sleep time (time the task is not runnable, + * including iowait, see below). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_sleep, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)); + +/* + * Tracepoint for accounting iowait time (time the task is not runnable + * due to waiting on IO to complete). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_iowait, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)); + +/* + * Tracepoint for accounting runtime (time the task is executing + * on a CPU). + */ +TRACE_EVENT(sched_stat_runtime, + + TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime), + + TP_ARGS(tsk, runtime, vruntime), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( u64, runtime ) + __field( u64, vruntime ) + ), + + TP_fast_assign( + memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN); + __entry->pid = tsk->pid; + __entry->runtime = runtime; + __entry->vruntime = vruntime; + ) + TP_perf_assign( + __perf_count(runtime); + ), + + TP_printk("comm=%s pid=%d runtime=%Lu [ns] vruntime=%Lu [ns]", + __entry->comm, __entry->pid, + (unsigned long long)__entry->runtime, + (unsigned long long)__entry->vruntime) +); + +/* + * Tracepoint for showing priority inheritance modifying a tasks + * priority. + */ +TRACE_EVENT(sched_pi_setprio, + + TP_PROTO(struct task_struct *tsk, int newprio), + + TP_ARGS(tsk, newprio), + + TP_STRUCT__entry( + __array( char, comm, TASK_COMM_LEN ) + __field( pid_t, pid ) + __field( int, oldprio ) + __field( int, newprio ) + ), + + TP_fast_assign( + memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN); + __entry->pid = tsk->pid; + __entry->oldprio = tsk->prio; + __entry->newprio = newprio; + ), + + TP_printk("comm=%s pid=%d oldprio=%d newprio=%d", + __entry->comm, __entry->pid, + __entry->oldprio, __entry->newprio) +); + +#endif /* _TRACE_SCHED_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h b/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h new file mode 100644 index 0000000..5a4c04a --- /dev/null +++ b/drivers/staging/lttng/instrumentation/events/mainline/syscalls.h @@ -0,0 +1,75 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM raw_syscalls +#define TRACE_INCLUDE_FILE syscalls + +#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EVENTS_SYSCALLS_H + +#include <linux/tracepoint.h> + +#include <asm/ptrace.h> +#include <asm/syscall.h> + + +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS + +extern void syscall_regfunc(void); +extern void syscall_unregfunc(void); + +TRACE_EVENT_FN(sys_enter, + + TP_PROTO(struct pt_regs *regs, long id), + + TP_ARGS(regs, id), + + TP_STRUCT__entry( + __field( long, id ) + __array( unsigned long, args, 6 ) + ), + + TP_fast_assign( + __entry->id = id; + syscall_get_arguments(current, regs, 0, 6, __entry->args); + ), + + TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", + __entry->id, + __entry->args[0], __entry->args[1], __entry->args[2], + __entry->args[3], __entry->args[4], __entry->args[5]), + + syscall_regfunc, syscall_unregfunc +); + +TRACE_EVENT_FLAGS(sys_enter, TRACE_EVENT_FL_CAP_ANY) + +TRACE_EVENT_FN(sys_exit, + + TP_PROTO(struct pt_regs *regs, long ret), + + TP_ARGS(regs, ret), + + TP_STRUCT__entry( + __field( long, id ) + __field( long, ret ) + ), + + TP_fast_assign( + __entry->id = syscall_get_nr(current, regs); + __entry->ret = ret; + ), + + TP_printk("NR %ld = %ld", + __entry->id, __entry->ret), + + syscall_regfunc, syscall_unregfunc +); + +TRACE_EVENT_FLAGS(sys_exit, TRACE_EVENT_FL_CAP_ANY) + +#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ + +#endif /* _TRACE_EVENTS_SYSCALLS_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> + -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 09/20] lttng: syscall instrumentation 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (7 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 08/20] lttng instrumentation: tracepoint events Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 10/20] lttng: lib ring buffer clients Mathieu Desnoyers ` (11 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) x86-32 and x86-64 system call instrumentation, along with the lttng-syscalls-generate-headers.sh script that generates the headers from the system call list. See README for details. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- .../syscalls/3.0.4/x86-64-syscalls-3.0.4 | 263 +++ .../syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 | 291 +++ .../staging/lttng/instrumentation/syscalls/README | 18 + .../syscalls/headers/compat_syscalls_integers.h | 3 + .../syscalls/headers/compat_syscalls_pointers.h | 3 + .../syscalls/headers/syscalls_integers.h | 7 + .../syscalls/headers/syscalls_integers_override.h | 14 + .../syscalls/headers/syscalls_pointers.h | 7 + .../syscalls/headers/syscalls_pointers_override.h | 4 + .../syscalls/headers/syscalls_unknown.h | 55 + .../headers/x86-32-syscalls-3.1.0-rc6_integers.h | 1163 ++++++++++ .../x86-32-syscalls-3.1.0-rc6_integers_override.h | 38 + .../headers/x86-32-syscalls-3.1.0-rc6_pointers.h | 2232 ++++++++++++++++++++ .../x86-32-syscalls-3.1.0-rc6_pointers_override.h | 17 + .../headers/x86-64-syscalls-3.0.4_integers.h | 1013 +++++++++ .../x86-64-syscalls-3.0.4_integers_override.h | 3 + .../headers/x86-64-syscalls-3.0.4_pointers.h | 2076 ++++++++++++++++++ .../x86-64-syscalls-3.0.4_pointers_override.h | 5 + .../syscalls/lttng-syscalls-extractor/Makefile | 1 + .../lttng-syscalls-extractor.c | 85 + .../syscalls/lttng-syscalls-generate-headers.sh | 275 +++ 21 files changed, 7573 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 create mode 100644 drivers/staging/lttng/instrumentation/syscalls/README create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c create mode 100644 drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh diff --git a/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 b/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 new file mode 100644 index 0000000..b229472 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/3.0.4/x86-64-syscalls-3.0.4 @@ -0,0 +1,263 @@ +syscall sys_read nr 0 nbargs 3 types: (unsigned int, char *, size_t) args: (fd, buf, count) +syscall sys_write nr 1 nbargs 3 types: (unsigned int, const char *, size_t) args: (fd, buf, count) +syscall sys_open nr 2 nbargs 3 types: (const char *, int, int) args: (filename, flags, mode) +syscall sys_close nr 3 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_newstat nr 4 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf) +syscall sys_newfstat nr 5 nbargs 2 types: (unsigned int, struct stat *) args: (fd, statbuf) +syscall sys_newlstat nr 6 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf) +syscall sys_poll nr 7 nbargs 3 types: (struct pollfd *, unsigned int, long) args: (ufds, nfds, timeout_msecs) +syscall sys_lseek nr 8 nbargs 3 types: (unsigned int, off_t, unsigned int) args: (fd, offset, origin) +syscall sys_mmap nr 9 nbargs 6 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, len, prot, flags, fd, off) +syscall sys_mprotect nr 10 nbargs 3 types: (unsigned long, size_t, unsigned long) args: (start, len, prot) +syscall sys_munmap nr 11 nbargs 2 types: (unsigned long, size_t) args: (addr, len) +syscall sys_brk nr 12 nbargs 1 types: (unsigned long) args: (brk) +syscall sys_rt_sigaction nr 13 nbargs 4 types: (int, const struct sigaction *, struct sigaction *, size_t) args: (sig, act, oact, sigsetsize) +syscall sys_rt_sigprocmask nr 14 nbargs 4 types: (int, sigset_t *, sigset_t *, size_t) args: (how, nset, oset, sigsetsize) +syscall sys_ioctl nr 16 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg) +syscall sys_readv nr 19 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen) +syscall sys_writev nr 20 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen) +syscall sys_access nr 21 nbargs 2 types: (const char *, int) args: (filename, mode) +syscall sys_pipe nr 22 nbargs 1 types: (int *) args: (fildes) +syscall sys_select nr 23 nbargs 5 types: (int, fd_set *, fd_set *, fd_set *, struct timeval *) args: (n, inp, outp, exp, tvp) +syscall sys_sched_yield nr 24 nbargs 0 types: () args: () +syscall sys_mremap nr 25 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, old_len, new_len, flags, new_addr) +syscall sys_msync nr 26 nbargs 3 types: (unsigned long, size_t, int) args: (start, len, flags) +syscall sys_mincore nr 27 nbargs 3 types: (unsigned long, size_t, unsigned char *) args: (start, len, vec) +syscall sys_madvise nr 28 nbargs 3 types: (unsigned long, size_t, int) args: (start, len_in, behavior) +syscall sys_shmget nr 29 nbargs 3 types: (key_t, size_t, int) args: (key, size, shmflg) +syscall sys_shmat nr 30 nbargs 3 types: (int, char *, int) args: (shmid, shmaddr, shmflg) +syscall sys_shmctl nr 31 nbargs 3 types: (int, int, struct shmid_ds *) args: (shmid, cmd, buf) +syscall sys_dup nr 32 nbargs 1 types: (unsigned int) args: (fildes) +syscall sys_dup2 nr 33 nbargs 2 types: (unsigned int, unsigned int) args: (oldfd, newfd) +syscall sys_pause nr 34 nbargs 0 types: () args: () +syscall sys_nanosleep nr 35 nbargs 2 types: (struct timespec *, struct timespec *) args: (rqtp, rmtp) +syscall sys_getitimer nr 36 nbargs 2 types: (int, struct itimerval *) args: (which, value) +syscall sys_alarm nr 37 nbargs 1 types: (unsigned int) args: (seconds) +syscall sys_setitimer nr 38 nbargs 3 types: (int, struct itimerval *, struct itimerval *) args: (which, value, ovalue) +syscall sys_getpid nr 39 nbargs 0 types: () args: () +syscall sys_sendfile64 nr 40 nbargs 4 types: (int, int, loff_t *, size_t) args: (out_fd, in_fd, offset, count) +syscall sys_socket nr 41 nbargs 3 types: (int, int, int) args: (family, type, protocol) +syscall sys_connect nr 42 nbargs 3 types: (int, struct sockaddr *, int) args: (fd, uservaddr, addrlen) +syscall sys_accept nr 43 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, upeer_sockaddr, upeer_addrlen) +syscall sys_sendto nr 44 nbargs 6 types: (int, void *, size_t, unsigned, struct sockaddr *, int) args: (fd, buff, len, flags, addr, addr_len) +syscall sys_recvfrom nr 45 nbargs 6 types: (int, void *, size_t, unsigned, struct sockaddr *, int *) args: (fd, ubuf, size, flags, addr, addr_len) +syscall sys_sendmsg nr 46 nbargs 3 types: (int, struct msghdr *, unsigned) args: (fd, msg, flags) +syscall sys_recvmsg nr 47 nbargs 3 types: (int, struct msghdr *, unsigned int) args: (fd, msg, flags) +syscall sys_shutdown nr 48 nbargs 2 types: (int, int) args: (fd, how) +syscall sys_bind nr 49 nbargs 3 types: (int, struct sockaddr *, int) args: (fd, umyaddr, addrlen) +syscall sys_listen nr 50 nbargs 2 types: (int, int) args: (fd, backlog) +syscall sys_getsockname nr 51 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, usockaddr, usockaddr_len) +syscall sys_getpeername nr 52 nbargs 3 types: (int, struct sockaddr *, int *) args: (fd, usockaddr, usockaddr_len) +syscall sys_socketpair nr 53 nbargs 4 types: (int, int, int, int *) args: (family, type, protocol, usockvec) +syscall sys_setsockopt nr 54 nbargs 5 types: (int, int, int, char *, int) args: (fd, level, optname, optval, optlen) +syscall sys_getsockopt nr 55 nbargs 5 types: (int, int, int, char *, int *) args: (fd, level, optname, optval, optlen) +syscall sys_exit nr 60 nbargs 1 types: (int) args: (error_code) +syscall sys_wait4 nr 61 nbargs 4 types: (pid_t, int *, int, struct rusage *) args: (upid, stat_addr, options, ru) +syscall sys_kill nr 62 nbargs 2 types: (pid_t, int) args: (pid, sig) +syscall sys_newuname nr 63 nbargs 1 types: (struct new_utsname *) args: (name) +syscall sys_semget nr 64 nbargs 3 types: (key_t, int, int) args: (key, nsems, semflg) +syscall sys_semop nr 65 nbargs 3 types: (int, struct sembuf *, unsigned) args: (semid, tsops, nsops) +syscall sys_shmdt nr 67 nbargs 1 types: (char *) args: (shmaddr) +syscall sys_msgget nr 68 nbargs 2 types: (key_t, int) args: (key, msgflg) +syscall sys_msgsnd nr 69 nbargs 4 types: (int, struct msgbuf *, size_t, int) args: (msqid, msgp, msgsz, msgflg) +syscall sys_msgrcv nr 70 nbargs 5 types: (int, struct msgbuf *, size_t, long, int) args: (msqid, msgp, msgsz, msgtyp, msgflg) +syscall sys_msgctl nr 71 nbargs 3 types: (int, int, struct msqid_ds *) args: (msqid, cmd, buf) +syscall sys_fcntl nr 72 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg) +syscall sys_flock nr 73 nbargs 2 types: (unsigned int, unsigned int) args: (fd, cmd) +syscall sys_fsync nr 74 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_fdatasync nr 75 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_truncate nr 76 nbargs 2 types: (const char *, long) args: (path, length) +syscall sys_ftruncate nr 77 nbargs 2 types: (unsigned int, unsigned long) args: (fd, length) +syscall sys_getdents nr 78 nbargs 3 types: (unsigned int, struct linux_dirent *, unsigned int) args: (fd, dirent, count) +syscall sys_getcwd nr 79 nbargs 2 types: (char *, unsigned long) args: (buf, size) +syscall sys_chdir nr 80 nbargs 1 types: (const char *) args: (filename) +syscall sys_fchdir nr 81 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_rename nr 82 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_mkdir nr 83 nbargs 2 types: (const char *, int) args: (pathname, mode) +syscall sys_rmdir nr 84 nbargs 1 types: (const char *) args: (pathname) +syscall sys_creat nr 85 nbargs 2 types: (const char *, int) args: (pathname, mode) +syscall sys_link nr 86 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_unlink nr 87 nbargs 1 types: (const char *) args: (pathname) +syscall sys_symlink nr 88 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_readlink nr 89 nbargs 3 types: (const char *, char *, int) args: (path, buf, bufsiz) +syscall sys_chmod nr 90 nbargs 2 types: (const char *, mode_t) args: (filename, mode) +syscall sys_fchmod nr 91 nbargs 2 types: (unsigned int, mode_t) args: (fd, mode) +syscall sys_chown nr 92 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group) +syscall sys_fchown nr 93 nbargs 3 types: (unsigned int, uid_t, gid_t) args: (fd, user, group) +syscall sys_lchown nr 94 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group) +syscall sys_umask nr 95 nbargs 1 types: (int) args: (mask) +syscall sys_gettimeofday nr 96 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz) +syscall sys_getrlimit nr 97 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim) +syscall sys_getrusage nr 98 nbargs 2 types: (int, struct rusage *) args: (who, ru) +syscall sys_sysinfo nr 99 nbargs 1 types: (struct sysinfo *) args: (info) +syscall sys_times nr 100 nbargs 1 types: (struct tms *) args: (tbuf) +syscall sys_ptrace nr 101 nbargs 4 types: (long, long, unsigned long, unsigned long) args: (request, pid, addr, data) +syscall sys_getuid nr 102 nbargs 0 types: () args: () +syscall sys_syslog nr 103 nbargs 3 types: (int, char *, int) args: (type, buf, len) +syscall sys_getgid nr 104 nbargs 0 types: () args: () +syscall sys_setuid nr 105 nbargs 1 types: (uid_t) args: (uid) +syscall sys_setgid nr 106 nbargs 1 types: (gid_t) args: (gid) +syscall sys_geteuid nr 107 nbargs 0 types: () args: () +syscall sys_getegid nr 108 nbargs 0 types: () args: () +syscall sys_setpgid nr 109 nbargs 2 types: (pid_t, pid_t) args: (pid, pgid) +syscall sys_getppid nr 110 nbargs 0 types: () args: () +syscall sys_getpgrp nr 111 nbargs 0 types: () args: () +syscall sys_setsid nr 112 nbargs 0 types: () args: () +syscall sys_setreuid nr 113 nbargs 2 types: (uid_t, uid_t) args: (ruid, euid) +syscall sys_setregid nr 114 nbargs 2 types: (gid_t, gid_t) args: (rgid, egid) +syscall sys_getgroups nr 115 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist) +syscall sys_setgroups nr 116 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist) +syscall sys_setresuid nr 117 nbargs 3 types: (uid_t, uid_t, uid_t) args: (ruid, euid, suid) +syscall sys_getresuid nr 118 nbargs 3 types: (uid_t *, uid_t *, uid_t *) args: (ruid, euid, suid) +syscall sys_setresgid nr 119 nbargs 3 types: (gid_t, gid_t, gid_t) args: (rgid, egid, sgid) +syscall sys_getresgid nr 120 nbargs 3 types: (gid_t *, gid_t *, gid_t *) args: (rgid, egid, sgid) +syscall sys_getpgid nr 121 nbargs 1 types: (pid_t) args: (pid) +syscall sys_setfsuid nr 122 nbargs 1 types: (uid_t) args: (uid) +syscall sys_setfsgid nr 123 nbargs 1 types: (gid_t) args: (gid) +syscall sys_getsid nr 124 nbargs 1 types: (pid_t) args: (pid) +syscall sys_capget nr 125 nbargs 2 types: (cap_user_header_t, cap_user_data_t) args: (header, dataptr) +syscall sys_capset nr 126 nbargs 2 types: (cap_user_header_t, const cap_user_data_t) args: (header, data) +syscall sys_rt_sigpending nr 127 nbargs 2 types: (sigset_t *, size_t) args: (set, sigsetsize) +syscall sys_rt_sigtimedwait nr 128 nbargs 4 types: (const sigset_t *, siginfo_t *, const struct timespec *, size_t) args: (uthese, uinfo, uts, sigsetsize) +syscall sys_rt_sigqueueinfo nr 129 nbargs 3 types: (pid_t, int, siginfo_t *) args: (pid, sig, uinfo) +syscall sys_rt_sigsuspend nr 130 nbargs 2 types: (sigset_t *, size_t) args: (unewset, sigsetsize) +syscall sys_utime nr 132 nbargs 2 types: (char *, struct utimbuf *) args: (filename, times) +syscall sys_mknod nr 133 nbargs 3 types: (const char *, int, unsigned) args: (filename, mode, dev) +syscall sys_personality nr 135 nbargs 1 types: (unsigned int) args: (personality) +syscall sys_ustat nr 136 nbargs 2 types: (unsigned, struct ustat *) args: (dev, ubuf) +syscall sys_statfs nr 137 nbargs 2 types: (const char *, struct statfs *) args: (pathname, buf) +syscall sys_fstatfs nr 138 nbargs 2 types: (unsigned int, struct statfs *) args: (fd, buf) +syscall sys_sysfs nr 139 nbargs 3 types: (int, unsigned long, unsigned long) args: (option, arg1, arg2) +syscall sys_getpriority nr 140 nbargs 2 types: (int, int) args: (which, who) +syscall sys_setpriority nr 141 nbargs 3 types: (int, int, int) args: (which, who, niceval) +syscall sys_sched_setparam nr 142 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param) +syscall sys_sched_getparam nr 143 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param) +syscall sys_sched_setscheduler nr 144 nbargs 3 types: (pid_t, int, struct sched_param *) args: (pid, policy, param) +syscall sys_sched_getscheduler nr 145 nbargs 1 types: (pid_t) args: (pid) +syscall sys_sched_get_priority_max nr 146 nbargs 1 types: (int) args: (policy) +syscall sys_sched_get_priority_min nr 147 nbargs 1 types: (int) args: (policy) +syscall sys_sched_rr_get_interval nr 148 nbargs 2 types: (pid_t, struct timespec *) args: (pid, interval) +syscall sys_mlock nr 149 nbargs 2 types: (unsigned long, size_t) args: (start, len) +syscall sys_munlock nr 150 nbargs 2 types: (unsigned long, size_t) args: (start, len) +syscall sys_mlockall nr 151 nbargs 1 types: (int) args: (flags) +syscall sys_munlockall nr 152 nbargs 0 types: () args: () +syscall sys_vhangup nr 153 nbargs 0 types: () args: () +syscall sys_pivot_root nr 155 nbargs 2 types: (const char *, const char *) args: (new_root, put_old) +syscall sys_sysctl nr 156 nbargs 1 types: (struct __sysctl_args *) args: (args) +syscall sys_prctl nr 157 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5) +syscall sys_adjtimex nr 159 nbargs 1 types: (struct timex *) args: (txc_p) +syscall sys_setrlimit nr 160 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim) +syscall sys_chroot nr 161 nbargs 1 types: (const char *) args: (filename) +syscall sys_sync nr 162 nbargs 0 types: () args: () +syscall sys_settimeofday nr 164 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz) +syscall sys_mount nr 165 nbargs 5 types: (char *, char *, char *, unsigned long, void *) args: (dev_name, dir_name, type, flags, data) +syscall sys_umount nr 166 nbargs 2 types: (char *, int) args: (name, flags) +syscall sys_swapon nr 167 nbargs 2 types: (const char *, int) args: (specialfile, swap_flags) +syscall sys_swapoff nr 168 nbargs 1 types: (const char *) args: (specialfile) +syscall sys_reboot nr 169 nbargs 4 types: (int, int, unsigned int, void *) args: (magic1, magic2, cmd, arg) +syscall sys_sethostname nr 170 nbargs 2 types: (char *, int) args: (name, len) +syscall sys_setdomainname nr 171 nbargs 2 types: (char *, int) args: (name, len) +syscall sys_init_module nr 175 nbargs 3 types: (void *, unsigned long, const char *) args: (umod, len, uargs) +syscall sys_delete_module nr 176 nbargs 2 types: (const char *, unsigned int) args: (name_user, flags) +syscall sys_nfsservctl nr 180 nbargs 3 types: (int, struct nfsctl_arg *, void *) args: (cmd, arg, res) +syscall sys_gettid nr 186 nbargs 0 types: () args: () +syscall sys_setxattr nr 188 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags) +syscall sys_lsetxattr nr 189 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags) +syscall sys_fsetxattr nr 190 nbargs 5 types: (int, const char *, const void *, size_t, int) args: (fd, name, value, size, flags) +syscall sys_getxattr nr 191 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size) +syscall sys_lgetxattr nr 192 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size) +syscall sys_fgetxattr nr 193 nbargs 4 types: (int, const char *, void *, size_t) args: (fd, name, value, size) +syscall sys_listxattr nr 194 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size) +syscall sys_llistxattr nr 195 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size) +syscall sys_flistxattr nr 196 nbargs 3 types: (int, char *, size_t) args: (fd, list, size) +syscall sys_removexattr nr 197 nbargs 2 types: (const char *, const char *) args: (pathname, name) +syscall sys_lremovexattr nr 198 nbargs 2 types: (const char *, const char *) args: (pathname, name) +syscall sys_fremovexattr nr 199 nbargs 2 types: (int, const char *) args: (fd, name) +syscall sys_tkill nr 200 nbargs 2 types: (pid_t, int) args: (pid, sig) +syscall sys_time nr 201 nbargs 1 types: (time_t *) args: (tloc) +syscall sys_futex nr 202 nbargs 6 types: (u32 *, int, u32, struct timespec *, u32 *, u32) args: (uaddr, op, val, utime, uaddr2, val3) +syscall sys_sched_setaffinity nr 203 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr) +syscall sys_sched_getaffinity nr 204 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr) +syscall sys_io_setup nr 206 nbargs 2 types: (unsigned, aio_context_t *) args: (nr_events, ctxp) +syscall sys_io_destroy nr 207 nbargs 1 types: (aio_context_t) args: (ctx) +syscall sys_io_getevents nr 208 nbargs 5 types: (aio_context_t, long, long, struct io_event *, struct timespec *) args: (ctx_id, min_nr, nr, events, timeout) +syscall sys_io_submit nr 209 nbargs 3 types: (aio_context_t, long, struct iocb * *) args: (ctx_id, nr, iocbpp) +syscall sys_io_cancel nr 210 nbargs 3 types: (aio_context_t, struct iocb *, struct io_event *) args: (ctx_id, iocb, result) +syscall sys_epoll_create nr 213 nbargs 1 types: (int) args: (size) +syscall sys_remap_file_pages nr 216 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (start, size, prot, pgoff, flags) +syscall sys_getdents64 nr 217 nbargs 3 types: (unsigned int, struct linux_dirent64 *, unsigned int) args: (fd, dirent, count) +syscall sys_set_tid_address nr 218 nbargs 1 types: (int *) args: (tidptr) +syscall sys_restart_syscall nr 219 nbargs 0 types: () args: () +syscall sys_semtimedop nr 220 nbargs 4 types: (int, struct sembuf *, unsigned, const struct timespec *) args: (semid, tsops, nsops, timeout) +syscall sys_timer_create nr 222 nbargs 3 types: (const clockid_t, struct sigevent *, timer_t *) args: (which_clock, timer_event_spec, created_timer_id) +syscall sys_timer_settime nr 223 nbargs 4 types: (timer_t, int, const struct itimerspec *, struct itimerspec *) args: (timer_id, flags, new_setting, old_setting) +syscall sys_timer_gettime nr 224 nbargs 2 types: (timer_t, struct itimerspec *) args: (timer_id, setting) +syscall sys_timer_getoverrun nr 225 nbargs 1 types: (timer_t) args: (timer_id) +syscall sys_timer_delete nr 226 nbargs 1 types: (timer_t) args: (timer_id) +syscall sys_clock_settime nr 227 nbargs 2 types: (const clockid_t, const struct timespec *) args: (which_clock, tp) +syscall sys_clock_gettime nr 228 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp) +syscall sys_clock_getres nr 229 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp) +syscall sys_clock_nanosleep nr 230 nbargs 4 types: (const clockid_t, int, const struct timespec *, struct timespec *) args: (which_clock, flags, rqtp, rmtp) +syscall sys_exit_group nr 231 nbargs 1 types: (int) args: (error_code) +syscall sys_epoll_wait nr 232 nbargs 4 types: (int, struct epoll_event *, int, int) args: (epfd, events, maxevents, timeout) +syscall sys_epoll_ctl nr 233 nbargs 4 types: (int, int, int, struct epoll_event *) args: (epfd, op, fd, event) +syscall sys_tgkill nr 234 nbargs 3 types: (pid_t, pid_t, int) args: (tgid, pid, sig) +syscall sys_utimes nr 235 nbargs 2 types: (char *, struct timeval *) args: (filename, utimes) +syscall sys_mq_open nr 240 nbargs 4 types: (const char *, int, mode_t, struct mq_attr *) args: (u_name, oflag, mode, u_attr) +syscall sys_mq_unlink nr 241 nbargs 1 types: (const char *) args: (u_name) +syscall sys_mq_timedsend nr 242 nbargs 5 types: (mqd_t, const char *, size_t, unsigned int, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout) +syscall sys_mq_timedreceive nr 243 nbargs 5 types: (mqd_t, char *, size_t, unsigned int *, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout) +syscall sys_mq_notify nr 244 nbargs 2 types: (mqd_t, const struct sigevent *) args: (mqdes, u_notification) +syscall sys_mq_getsetattr nr 245 nbargs 3 types: (mqd_t, const struct mq_attr *, struct mq_attr *) args: (mqdes, u_mqstat, u_omqstat) +syscall sys_kexec_load nr 246 nbargs 4 types: (unsigned long, unsigned long, struct kexec_segment *, unsigned long) args: (entry, nr_segments, segments, flags) +syscall sys_waitid nr 247 nbargs 5 types: (int, pid_t, struct siginfo *, int, struct rusage *) args: (which, upid, infop, options, ru) +syscall sys_ioprio_set nr 251 nbargs 3 types: (int, int, int) args: (which, who, ioprio) +syscall sys_ioprio_get nr 252 nbargs 2 types: (int, int) args: (which, who) +syscall sys_inotify_init nr 253 nbargs 0 types: () args: () +syscall sys_inotify_add_watch nr 254 nbargs 3 types: (int, const char *, u32) args: (fd, pathname, mask) +syscall sys_inotify_rm_watch nr 255 nbargs 2 types: (int, __s32) args: (fd, wd) +syscall sys_openat nr 257 nbargs 4 types: (int, const char *, int, int) args: (dfd, filename, flags, mode) +syscall sys_mkdirat nr 258 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, mode) +syscall sys_mknodat nr 259 nbargs 4 types: (int, const char *, int, unsigned) args: (dfd, filename, mode, dev) +syscall sys_fchownat nr 260 nbargs 5 types: (int, const char *, uid_t, gid_t, int) args: (dfd, filename, user, group, flag) +syscall sys_futimesat nr 261 nbargs 3 types: (int, const char *, struct timeval *) args: (dfd, filename, utimes) +syscall sys_newfstatat nr 262 nbargs 4 types: (int, const char *, struct stat *, int) args: (dfd, filename, statbuf, flag) +syscall sys_unlinkat nr 263 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, flag) +syscall sys_renameat nr 264 nbargs 4 types: (int, const char *, int, const char *) args: (olddfd, oldname, newdfd, newname) +syscall sys_linkat nr 265 nbargs 5 types: (int, const char *, int, const char *, int) args: (olddfd, oldname, newdfd, newname, flags) +syscall sys_symlinkat nr 266 nbargs 3 types: (const char *, int, const char *) args: (oldname, newdfd, newname) +syscall sys_readlinkat nr 267 nbargs 4 types: (int, const char *, char *, int) args: (dfd, pathname, buf, bufsiz) +syscall sys_fchmodat nr 268 nbargs 3 types: (int, const char *, mode_t) args: (dfd, filename, mode) +syscall sys_faccessat nr 269 nbargs 3 types: (int, const char *, int) args: (dfd, filename, mode) +syscall sys_pselect6 nr 270 nbargs 6 types: (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *) args: (n, inp, outp, exp, tsp, sig) +syscall sys_ppoll nr 271 nbargs 5 types: (struct pollfd *, unsigned int, struct timespec *, const sigset_t *, size_t) args: (ufds, nfds, tsp, sigmask, sigsetsize) +syscall sys_unshare nr 272 nbargs 1 types: (unsigned long) args: (unshare_flags) +syscall sys_set_robust_list nr 273 nbargs 2 types: (struct robust_list_head *, size_t) args: (head, len) +syscall sys_get_robust_list nr 274 nbargs 3 types: (int, struct robust_list_head * *, size_t *) args: (pid, head_ptr, len_ptr) +syscall sys_splice nr 275 nbargs 6 types: (int, loff_t *, int, loff_t *, size_t, unsigned int) args: (fd_in, off_in, fd_out, off_out, len, flags) +syscall sys_tee nr 276 nbargs 4 types: (int, int, size_t, unsigned int) args: (fdin, fdout, len, flags) +syscall sys_vmsplice nr 278 nbargs 4 types: (int, const struct iovec *, unsigned long, unsigned int) args: (fd, iov, nr_segs, flags) +syscall sys_utimensat nr 280 nbargs 4 types: (int, const char *, struct timespec *, int) args: (dfd, filename, utimes, flags) +syscall sys_epoll_pwait nr 281 nbargs 6 types: (int, struct epoll_event *, int, int, const sigset_t *, size_t) args: (epfd, events, maxevents, timeout, sigmask, sigsetsize) +syscall sys_signalfd nr 282 nbargs 3 types: (int, sigset_t *, size_t) args: (ufd, user_mask, sizemask) +syscall sys_timerfd_create nr 283 nbargs 2 types: (int, int) args: (clockid, flags) +syscall sys_eventfd nr 284 nbargs 1 types: (unsigned int) args: (count) +syscall sys_timerfd_settime nr 286 nbargs 4 types: (int, int, const struct itimerspec *, struct itimerspec *) args: (ufd, flags, utmr, otmr) +syscall sys_timerfd_gettime nr 287 nbargs 2 types: (int, struct itimerspec *) args: (ufd, otmr) +syscall sys_accept4 nr 288 nbargs 4 types: (int, struct sockaddr *, int *, int) args: (fd, upeer_sockaddr, upeer_addrlen, flags) +syscall sys_signalfd4 nr 289 nbargs 4 types: (int, sigset_t *, size_t, int) args: (ufd, user_mask, sizemask, flags) +syscall sys_eventfd2 nr 290 nbargs 2 types: (unsigned int, int) args: (count, flags) +syscall sys_epoll_create1 nr 291 nbargs 1 types: (int) args: (flags) +syscall sys_dup3 nr 292 nbargs 3 types: (unsigned int, unsigned int, int) args: (oldfd, newfd, flags) +syscall sys_pipe2 nr 293 nbargs 2 types: (int *, int) args: (fildes, flags) +syscall sys_inotify_init1 nr 294 nbargs 1 types: (int) args: (flags) +syscall sys_preadv nr 295 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h) +syscall sys_pwritev nr 296 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h) +syscall sys_rt_tgsigqueueinfo nr 297 nbargs 4 types: (pid_t, pid_t, int, siginfo_t *) args: (tgid, pid, sig, uinfo) +syscall sys_perf_event_open nr 298 nbargs 5 types: (struct perf_event_attr *, pid_t, int, int, unsigned long) args: (attr_uptr, pid, cpu, group_fd, flags) +syscall sys_recvmmsg nr 299 nbargs 5 types: (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *) args: (fd, mmsg, vlen, flags, timeout) +syscall sys_prlimit64 nr 302 nbargs 4 types: (pid_t, unsigned int, const struct rlimit64 *, struct rlimit64 *) args: (pid, resource, new_rlim, old_rlim) +syscall sys_clock_adjtime nr 305 nbargs 2 types: (const clockid_t, struct timex *) args: (which_clock, utx) +syscall sys_syncfs nr 306 nbargs 1 types: (int) args: (fd) +syscall sys_sendmmsg nr 307 nbargs 4 types: (int, struct mmsghdr *, unsigned int, unsigned int) args: (fd, mmsg, vlen, flags) +syscall sys_setns nr 308 nbargs 2 types: (int, int) args: (fd, nstype) diff --git a/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 b/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 new file mode 100644 index 0000000..130c1e3 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/3.1.0-rc6/x86-32-syscalls-3.1.0-rc6 @@ -0,0 +1,291 @@ +syscall sys_restart_syscall nr 0 nbargs 0 types: () args: () +syscall sys_exit nr 1 nbargs 1 types: (int) args: (error_code) +syscall sys_read nr 3 nbargs 3 types: (unsigned int, char *, size_t) args: (fd, buf, count) +syscall sys_write nr 4 nbargs 3 types: (unsigned int, const char *, size_t) args: (fd, buf, count) +syscall sys_open nr 5 nbargs 3 types: (const char *, int, int) args: (filename, flags, mode) +syscall sys_close nr 6 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_waitpid nr 7 nbargs 3 types: (pid_t, int *, int) args: (pid, stat_addr, options) +syscall sys_creat nr 8 nbargs 2 types: (const char *, int) args: (pathname, mode) +syscall sys_link nr 9 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_unlink nr 10 nbargs 1 types: (const char *) args: (pathname) +syscall sys_chdir nr 12 nbargs 1 types: (const char *) args: (filename) +syscall sys_time nr 13 nbargs 1 types: (time_t *) args: (tloc) +syscall sys_mknod nr 14 nbargs 3 types: (const char *, int, unsigned) args: (filename, mode, dev) +syscall sys_chmod nr 15 nbargs 2 types: (const char *, mode_t) args: (filename, mode) +syscall sys_lchown16 nr 16 nbargs 3 types: (const char *, old_uid_t, old_gid_t) args: (filename, user, group) +syscall sys_stat nr 18 nbargs 2 types: (const char *, struct __old_kernel_stat *) args: (filename, statbuf) +syscall sys_lseek nr 19 nbargs 3 types: (unsigned int, off_t, unsigned int) args: (fd, offset, origin) +syscall sys_getpid nr 20 nbargs 0 types: () args: () +syscall sys_mount nr 21 nbargs 5 types: (char *, char *, char *, unsigned long, void *) args: (dev_name, dir_name, type, flags, data) +syscall sys_oldumount nr 22 nbargs 1 types: (char *) args: (name) +syscall sys_setuid16 nr 23 nbargs 1 types: (old_uid_t) args: (uid) +syscall sys_getuid16 nr 24 nbargs 0 types: () args: () +syscall sys_stime nr 25 nbargs 1 types: (time_t *) args: (tptr) +syscall sys_ptrace nr 26 nbargs 4 types: (long, long, unsigned long, unsigned long) args: (request, pid, addr, data) +syscall sys_alarm nr 27 nbargs 1 types: (unsigned int) args: (seconds) +syscall sys_fstat nr 28 nbargs 2 types: (unsigned int, struct __old_kernel_stat *) args: (fd, statbuf) +syscall sys_pause nr 29 nbargs 0 types: () args: () +syscall sys_utime nr 30 nbargs 2 types: (char *, struct utimbuf *) args: (filename, times) +syscall sys_access nr 33 nbargs 2 types: (const char *, int) args: (filename, mode) +syscall sys_nice nr 34 nbargs 1 types: (int) args: (increment) +syscall sys_sync nr 36 nbargs 0 types: () args: () +syscall sys_kill nr 37 nbargs 2 types: (pid_t, int) args: (pid, sig) +syscall sys_rename nr 38 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_mkdir nr 39 nbargs 2 types: (const char *, int) args: (pathname, mode) +syscall sys_rmdir nr 40 nbargs 1 types: (const char *) args: (pathname) +syscall sys_dup nr 41 nbargs 1 types: (unsigned int) args: (fildes) +syscall sys_pipe nr 42 nbargs 1 types: (int *) args: (fildes) +syscall sys_times nr 43 nbargs 1 types: (struct tms *) args: (tbuf) +syscall sys_brk nr 45 nbargs 1 types: (unsigned long) args: (brk) +syscall sys_setgid16 nr 46 nbargs 1 types: (old_gid_t) args: (gid) +syscall sys_getgid16 nr 47 nbargs 0 types: () args: () +syscall sys_signal nr 48 nbargs 2 types: (int, __sighandler_t) args: (sig, handler) +syscall sys_geteuid16 nr 49 nbargs 0 types: () args: () +syscall sys_getegid16 nr 50 nbargs 0 types: () args: () +syscall sys_acct nr 51 nbargs 1 types: (const char *) args: (name) +syscall sys_umount nr 52 nbargs 2 types: (char *, int) args: (name, flags) +syscall sys_ioctl nr 54 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg) +syscall sys_fcntl nr 55 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg) +syscall sys_setpgid nr 57 nbargs 2 types: (pid_t, pid_t) args: (pid, pgid) +syscall sys_olduname nr 59 nbargs 1 types: (struct oldold_utsname *) args: (name) +syscall sys_umask nr 60 nbargs 1 types: (int) args: (mask) +syscall sys_chroot nr 61 nbargs 1 types: (const char *) args: (filename) +syscall sys_ustat nr 62 nbargs 2 types: (unsigned, struct ustat *) args: (dev, ubuf) +syscall sys_dup2 nr 63 nbargs 2 types: (unsigned int, unsigned int) args: (oldfd, newfd) +syscall sys_getppid nr 64 nbargs 0 types: () args: () +syscall sys_getpgrp nr 65 nbargs 0 types: () args: () +syscall sys_setsid nr 66 nbargs 0 types: () args: () +syscall sys_sgetmask nr 68 nbargs 0 types: () args: () +syscall sys_ssetmask nr 69 nbargs 1 types: (int) args: (newmask) +syscall sys_setreuid16 nr 70 nbargs 2 types: (old_uid_t, old_uid_t) args: (ruid, euid) +syscall sys_setregid16 nr 71 nbargs 2 types: (old_gid_t, old_gid_t) args: (rgid, egid) +syscall sys_sigpending nr 73 nbargs 1 types: (old_sigset_t *) args: (set) +syscall sys_sethostname nr 74 nbargs 2 types: (char *, int) args: (name, len) +syscall sys_setrlimit nr 75 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim) +syscall sys_old_getrlimit nr 76 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim) +syscall sys_getrusage nr 77 nbargs 2 types: (int, struct rusage *) args: (who, ru) +syscall sys_gettimeofday nr 78 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz) +syscall sys_settimeofday nr 79 nbargs 2 types: (struct timeval *, struct timezone *) args: (tv, tz) +syscall sys_getgroups16 nr 80 nbargs 2 types: (int, old_gid_t *) args: (gidsetsize, grouplist) +syscall sys_setgroups16 nr 81 nbargs 2 types: (int, old_gid_t *) args: (gidsetsize, grouplist) +syscall sys_old_select nr 82 nbargs 1 types: (struct sel_arg_struct *) args: (arg) +syscall sys_symlink nr 83 nbargs 2 types: (const char *, const char *) args: (oldname, newname) +syscall sys_lstat nr 84 nbargs 2 types: (const char *, struct __old_kernel_stat *) args: (filename, statbuf) +syscall sys_readlink nr 85 nbargs 3 types: (const char *, char *, int) args: (path, buf, bufsiz) +syscall sys_uselib nr 86 nbargs 1 types: (const char *) args: (library) +syscall sys_swapon nr 87 nbargs 2 types: (const char *, int) args: (specialfile, swap_flags) +syscall sys_reboot nr 88 nbargs 4 types: (int, int, unsigned int, void *) args: (magic1, magic2, cmd, arg) +syscall sys_old_readdir nr 89 nbargs 3 types: (unsigned int, struct old_linux_dirent *, unsigned int) args: (fd, dirent, count) +syscall sys_old_mmap nr 90 nbargs 1 types: (struct mmap_arg_struct *) args: (arg) +syscall sys_munmap nr 91 nbargs 2 types: (unsigned long, size_t) args: (addr, len) +syscall sys_truncate nr 92 nbargs 2 types: (const char *, long) args: (path, length) +syscall sys_ftruncate nr 93 nbargs 2 types: (unsigned int, unsigned long) args: (fd, length) +syscall sys_fchmod nr 94 nbargs 2 types: (unsigned int, mode_t) args: (fd, mode) +syscall sys_fchown16 nr 95 nbargs 3 types: (unsigned int, old_uid_t, old_gid_t) args: (fd, user, group) +syscall sys_getpriority nr 96 nbargs 2 types: (int, int) args: (which, who) +syscall sys_setpriority nr 97 nbargs 3 types: (int, int, int) args: (which, who, niceval) +syscall sys_statfs nr 99 nbargs 2 types: (const char *, struct statfs *) args: (pathname, buf) +syscall sys_fstatfs nr 100 nbargs 2 types: (unsigned int, struct statfs *) args: (fd, buf) +syscall sys_socketcall nr 102 nbargs 2 types: (int, unsigned long *) args: (call, args) +syscall sys_syslog nr 103 nbargs 3 types: (int, char *, int) args: (type, buf, len) +syscall sys_setitimer nr 104 nbargs 3 types: (int, struct itimerval *, struct itimerval *) args: (which, value, ovalue) +syscall sys_getitimer nr 105 nbargs 2 types: (int, struct itimerval *) args: (which, value) +syscall sys_newstat nr 106 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf) +syscall sys_newlstat nr 107 nbargs 2 types: (const char *, struct stat *) args: (filename, statbuf) +syscall sys_newfstat nr 108 nbargs 2 types: (unsigned int, struct stat *) args: (fd, statbuf) +syscall sys_uname nr 109 nbargs 1 types: (struct old_utsname *) args: (name) +syscall sys_vhangup nr 111 nbargs 0 types: () args: () +syscall sys_wait4 nr 114 nbargs 4 types: (pid_t, int *, int, struct rusage *) args: (upid, stat_addr, options, ru) +syscall sys_swapoff nr 115 nbargs 1 types: (const char *) args: (specialfile) +syscall sys_sysinfo nr 116 nbargs 1 types: (struct sysinfo *) args: (info) +syscall sys_ipc nr 117 nbargs 6 types: (unsigned int, int, unsigned long, unsigned long, void *, long) args: (call, first, second, third, ptr, fifth) +syscall sys_fsync nr 118 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_setdomainname nr 121 nbargs 2 types: (char *, int) args: (name, len) +syscall sys_newuname nr 122 nbargs 1 types: (struct new_utsname *) args: (name) +syscall sys_adjtimex nr 124 nbargs 1 types: (struct timex *) args: (txc_p) +syscall sys_mprotect nr 125 nbargs 3 types: (unsigned long, size_t, unsigned long) args: (start, len, prot) +syscall sys_sigprocmask nr 126 nbargs 3 types: (int, old_sigset_t *, old_sigset_t *) args: (how, nset, oset) +syscall sys_init_module nr 128 nbargs 3 types: (void *, unsigned long, const char *) args: (umod, len, uargs) +syscall sys_delete_module nr 129 nbargs 2 types: (const char *, unsigned int) args: (name_user, flags) +syscall sys_quotactl nr 131 nbargs 4 types: (unsigned int, const char *, qid_t, void *) args: (cmd, special, id, addr) +syscall sys_getpgid nr 132 nbargs 1 types: (pid_t) args: (pid) +syscall sys_fchdir nr 133 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_bdflush nr 134 nbargs 2 types: (int, long) args: (func, data) +syscall sys_sysfs nr 135 nbargs 3 types: (int, unsigned long, unsigned long) args: (option, arg1, arg2) +syscall sys_personality nr 136 nbargs 1 types: (unsigned int) args: (personality) +syscall sys_setfsuid16 nr 138 nbargs 1 types: (old_uid_t) args: (uid) +syscall sys_setfsgid16 nr 139 nbargs 1 types: (old_gid_t) args: (gid) +syscall sys_llseek nr 140 nbargs 5 types: (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int) args: (fd, offset_high, offset_low, result, origin) +syscall sys_getdents nr 141 nbargs 3 types: (unsigned int, struct linux_dirent *, unsigned int) args: (fd, dirent, count) +syscall sys_select nr 142 nbargs 5 types: (int, fd_set *, fd_set *, fd_set *, struct timeval *) args: (n, inp, outp, exp, tvp) +syscall sys_flock nr 143 nbargs 2 types: (unsigned int, unsigned int) args: (fd, cmd) +syscall sys_msync nr 144 nbargs 3 types: (unsigned long, size_t, int) args: (start, len, flags) +syscall sys_readv nr 145 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen) +syscall sys_writev nr 146 nbargs 3 types: (unsigned long, const struct iovec *, unsigned long) args: (fd, vec, vlen) +syscall sys_getsid nr 147 nbargs 1 types: (pid_t) args: (pid) +syscall sys_fdatasync nr 148 nbargs 1 types: (unsigned int) args: (fd) +syscall sys_sysctl nr 149 nbargs 1 types: (struct __sysctl_args *) args: (args) +syscall sys_mlock nr 150 nbargs 2 types: (unsigned long, size_t) args: (start, len) +syscall sys_munlock nr 151 nbargs 2 types: (unsigned long, size_t) args: (start, len) +syscall sys_mlockall nr 152 nbargs 1 types: (int) args: (flags) +syscall sys_munlockall nr 153 nbargs 0 types: () args: () +syscall sys_sched_setparam nr 154 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param) +syscall sys_sched_getparam nr 155 nbargs 2 types: (pid_t, struct sched_param *) args: (pid, param) +syscall sys_sched_setscheduler nr 156 nbargs 3 types: (pid_t, int, struct sched_param *) args: (pid, policy, param) +syscall sys_sched_getscheduler nr 157 nbargs 1 types: (pid_t) args: (pid) +syscall sys_sched_yield nr 158 nbargs 0 types: () args: () +syscall sys_sched_get_priority_max nr 159 nbargs 1 types: (int) args: (policy) +syscall sys_sched_get_priority_min nr 160 nbargs 1 types: (int) args: (policy) +syscall sys_sched_rr_get_interval nr 161 nbargs 2 types: (pid_t, struct timespec *) args: (pid, interval) +syscall sys_nanosleep nr 162 nbargs 2 types: (struct timespec *, struct timespec *) args: (rqtp, rmtp) +syscall sys_mremap nr 163 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, old_len, new_len, flags, new_addr) +syscall sys_setresuid16 nr 164 nbargs 3 types: (old_uid_t, old_uid_t, old_uid_t) args: (ruid, euid, suid) +syscall sys_getresuid16 nr 165 nbargs 3 types: (old_uid_t *, old_uid_t *, old_uid_t *) args: (ruid, euid, suid) +syscall sys_poll nr 168 nbargs 3 types: (struct pollfd *, unsigned int, long) args: (ufds, nfds, timeout_msecs) +syscall sys_setresgid16 nr 170 nbargs 3 types: (old_gid_t, old_gid_t, old_gid_t) args: (rgid, egid, sgid) +syscall sys_getresgid16 nr 171 nbargs 3 types: (old_gid_t *, old_gid_t *, old_gid_t *) args: (rgid, egid, sgid) +syscall sys_prctl nr 172 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5) +syscall sys_rt_sigaction nr 174 nbargs 4 types: (int, const struct sigaction *, struct sigaction *, size_t) args: (sig, act, oact, sigsetsize) +syscall sys_rt_sigprocmask nr 175 nbargs 4 types: (int, sigset_t *, sigset_t *, size_t) args: (how, nset, oset, sigsetsize) +syscall sys_rt_sigpending nr 176 nbargs 2 types: (sigset_t *, size_t) args: (set, sigsetsize) +syscall sys_rt_sigtimedwait nr 177 nbargs 4 types: (const sigset_t *, siginfo_t *, const struct timespec *, size_t) args: (uthese, uinfo, uts, sigsetsize) +syscall sys_rt_sigqueueinfo nr 178 nbargs 3 types: (pid_t, int, siginfo_t *) args: (pid, sig, uinfo) +syscall sys_rt_sigsuspend nr 179 nbargs 2 types: (sigset_t *, size_t) args: (unewset, sigsetsize) +syscall sys_chown16 nr 182 nbargs 3 types: (const char *, old_uid_t, old_gid_t) args: (filename, user, group) +syscall sys_getcwd nr 183 nbargs 2 types: (char *, unsigned long) args: (buf, size) +syscall sys_capget nr 184 nbargs 2 types: (cap_user_header_t, cap_user_data_t) args: (header, dataptr) +syscall sys_capset nr 185 nbargs 2 types: (cap_user_header_t, const cap_user_data_t) args: (header, data) +syscall sys_sendfile nr 187 nbargs 4 types: (int, int, off_t *, size_t) args: (out_fd, in_fd, offset, count) +syscall sys_getrlimit nr 191 nbargs 2 types: (unsigned int, struct rlimit *) args: (resource, rlim) +syscall sys_mmap_pgoff nr 192 nbargs 6 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (addr, len, prot, flags, fd, pgoff) +syscall sys_stat64 nr 195 nbargs 2 types: (const char *, struct stat64 *) args: (filename, statbuf) +syscall sys_lstat64 nr 196 nbargs 2 types: (const char *, struct stat64 *) args: (filename, statbuf) +syscall sys_fstat64 nr 197 nbargs 2 types: (unsigned long, struct stat64 *) args: (fd, statbuf) +syscall sys_lchown nr 198 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group) +syscall sys_getuid nr 199 nbargs 0 types: () args: () +syscall sys_getgid nr 200 nbargs 0 types: () args: () +syscall sys_geteuid nr 201 nbargs 0 types: () args: () +syscall sys_getegid nr 202 nbargs 0 types: () args: () +syscall sys_setreuid nr 203 nbargs 2 types: (uid_t, uid_t) args: (ruid, euid) +syscall sys_setregid nr 204 nbargs 2 types: (gid_t, gid_t) args: (rgid, egid) +syscall sys_getgroups nr 205 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist) +syscall sys_setgroups nr 206 nbargs 2 types: (int, gid_t *) args: (gidsetsize, grouplist) +syscall sys_fchown nr 207 nbargs 3 types: (unsigned int, uid_t, gid_t) args: (fd, user, group) +syscall sys_setresuid nr 208 nbargs 3 types: (uid_t, uid_t, uid_t) args: (ruid, euid, suid) +syscall sys_getresuid nr 209 nbargs 3 types: (uid_t *, uid_t *, uid_t *) args: (ruid, euid, suid) +syscall sys_setresgid nr 210 nbargs 3 types: (gid_t, gid_t, gid_t) args: (rgid, egid, sgid) +syscall sys_getresgid nr 211 nbargs 3 types: (gid_t *, gid_t *, gid_t *) args: (rgid, egid, sgid) +syscall sys_chown nr 212 nbargs 3 types: (const char *, uid_t, gid_t) args: (filename, user, group) +syscall sys_setuid nr 213 nbargs 1 types: (uid_t) args: (uid) +syscall sys_setgid nr 214 nbargs 1 types: (gid_t) args: (gid) +syscall sys_setfsuid nr 215 nbargs 1 types: (uid_t) args: (uid) +syscall sys_setfsgid nr 216 nbargs 1 types: (gid_t) args: (gid) +syscall sys_pivot_root nr 217 nbargs 2 types: (const char *, const char *) args: (new_root, put_old) +syscall sys_mincore nr 218 nbargs 3 types: (unsigned long, size_t, unsigned char *) args: (start, len, vec) +syscall sys_madvise nr 219 nbargs 3 types: (unsigned long, size_t, int) args: (start, len_in, behavior) +syscall sys_getdents64 nr 220 nbargs 3 types: (unsigned int, struct linux_dirent64 *, unsigned int) args: (fd, dirent, count) +syscall sys_fcntl64 nr 221 nbargs 3 types: (unsigned int, unsigned int, unsigned long) args: (fd, cmd, arg) +syscall sys_gettid nr 224 nbargs 0 types: () args: () +syscall sys_setxattr nr 226 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags) +syscall sys_lsetxattr nr 227 nbargs 5 types: (const char *, const char *, const void *, size_t, int) args: (pathname, name, value, size, flags) +syscall sys_fsetxattr nr 228 nbargs 5 types: (int, const char *, const void *, size_t, int) args: (fd, name, value, size, flags) +syscall sys_getxattr nr 229 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size) +syscall sys_lgetxattr nr 230 nbargs 4 types: (const char *, const char *, void *, size_t) args: (pathname, name, value, size) +syscall sys_fgetxattr nr 231 nbargs 4 types: (int, const char *, void *, size_t) args: (fd, name, value, size) +syscall sys_listxattr nr 232 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size) +syscall sys_llistxattr nr 233 nbargs 3 types: (const char *, char *, size_t) args: (pathname, list, size) +syscall sys_flistxattr nr 234 nbargs 3 types: (int, char *, size_t) args: (fd, list, size) +syscall sys_removexattr nr 235 nbargs 2 types: (const char *, const char *) args: (pathname, name) +syscall sys_lremovexattr nr 236 nbargs 2 types: (const char *, const char *) args: (pathname, name) +syscall sys_fremovexattr nr 237 nbargs 2 types: (int, const char *) args: (fd, name) +syscall sys_tkill nr 238 nbargs 2 types: (pid_t, int) args: (pid, sig) +syscall sys_sendfile64 nr 239 nbargs 4 types: (int, int, loff_t *, size_t) args: (out_fd, in_fd, offset, count) +syscall sys_futex nr 240 nbargs 6 types: (u32 *, int, u32, struct timespec *, u32 *, u32) args: (uaddr, op, val, utime, uaddr2, val3) +syscall sys_sched_setaffinity nr 241 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr) +syscall sys_sched_getaffinity nr 242 nbargs 3 types: (pid_t, unsigned int, unsigned long *) args: (pid, len, user_mask_ptr) +syscall sys_io_setup nr 245 nbargs 2 types: (unsigned, aio_context_t *) args: (nr_events, ctxp) +syscall sys_io_destroy nr 246 nbargs 1 types: (aio_context_t) args: (ctx) +syscall sys_io_getevents nr 247 nbargs 5 types: (aio_context_t, long, long, struct io_event *, struct timespec *) args: (ctx_id, min_nr, nr, events, timeout) +syscall sys_io_submit nr 248 nbargs 3 types: (aio_context_t, long, struct iocb * *) args: (ctx_id, nr, iocbpp) +syscall sys_io_cancel nr 249 nbargs 3 types: (aio_context_t, struct iocb *, struct io_event *) args: (ctx_id, iocb, result) +syscall sys_exit_group nr 252 nbargs 1 types: (int) args: (error_code) +syscall sys_epoll_create nr 254 nbargs 1 types: (int) args: (size) +syscall sys_epoll_ctl nr 255 nbargs 4 types: (int, int, int, struct epoll_event *) args: (epfd, op, fd, event) +syscall sys_epoll_wait nr 256 nbargs 4 types: (int, struct epoll_event *, int, int) args: (epfd, events, maxevents, timeout) +syscall sys_remap_file_pages nr 257 nbargs 5 types: (unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) args: (start, size, prot, pgoff, flags) +syscall sys_set_tid_address nr 258 nbargs 1 types: (int *) args: (tidptr) +syscall sys_timer_create nr 259 nbargs 3 types: (const clockid_t, struct sigevent *, timer_t *) args: (which_clock, timer_event_spec, created_timer_id) +syscall sys_timer_settime nr 260 nbargs 4 types: (timer_t, int, const struct itimerspec *, struct itimerspec *) args: (timer_id, flags, new_setting, old_setting) +syscall sys_timer_gettime nr 261 nbargs 2 types: (timer_t, struct itimerspec *) args: (timer_id, setting) +syscall sys_timer_getoverrun nr 262 nbargs 1 types: (timer_t) args: (timer_id) +syscall sys_timer_delete nr 263 nbargs 1 types: (timer_t) args: (timer_id) +syscall sys_clock_settime nr 264 nbargs 2 types: (const clockid_t, const struct timespec *) args: (which_clock, tp) +syscall sys_clock_gettime nr 265 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp) +syscall sys_clock_getres nr 266 nbargs 2 types: (const clockid_t, struct timespec *) args: (which_clock, tp) +syscall sys_clock_nanosleep nr 267 nbargs 4 types: (const clockid_t, int, const struct timespec *, struct timespec *) args: (which_clock, flags, rqtp, rmtp) +syscall sys_statfs64 nr 268 nbargs 3 types: (const char *, size_t, struct statfs64 *) args: (pathname, sz, buf) +syscall sys_fstatfs64 nr 269 nbargs 3 types: (unsigned int, size_t, struct statfs64 *) args: (fd, sz, buf) +syscall sys_tgkill nr 270 nbargs 3 types: (pid_t, pid_t, int) args: (tgid, pid, sig) +syscall sys_utimes nr 271 nbargs 2 types: (char *, struct timeval *) args: (filename, utimes) +syscall sys_mq_open nr 277 nbargs 4 types: (const char *, int, mode_t, struct mq_attr *) args: (u_name, oflag, mode, u_attr) +syscall sys_mq_unlink nr 278 nbargs 1 types: (const char *) args: (u_name) +syscall sys_mq_timedsend nr 279 nbargs 5 types: (mqd_t, const char *, size_t, unsigned int, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout) +syscall sys_mq_timedreceive nr 280 nbargs 5 types: (mqd_t, char *, size_t, unsigned int *, const struct timespec *) args: (mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout) +syscall sys_mq_notify nr 281 nbargs 2 types: (mqd_t, const struct sigevent *) args: (mqdes, u_notification) +syscall sys_mq_getsetattr nr 282 nbargs 3 types: (mqd_t, const struct mq_attr *, struct mq_attr *) args: (mqdes, u_mqstat, u_omqstat) +syscall sys_kexec_load nr 283 nbargs 4 types: (unsigned long, unsigned long, struct kexec_segment *, unsigned long) args: (entry, nr_segments, segments, flags) +syscall sys_waitid nr 284 nbargs 5 types: (int, pid_t, struct siginfo *, int, struct rusage *) args: (which, upid, infop, options, ru) +syscall sys_add_key nr 286 nbargs 5 types: (const char *, const char *, const void *, size_t, key_serial_t) args: (_type, _description, _payload, plen, ringid) +syscall sys_request_key nr 287 nbargs 4 types: (const char *, const char *, const char *, key_serial_t) args: (_type, _description, _callout_info, destringid) +syscall sys_keyctl nr 288 nbargs 5 types: (int, unsigned long, unsigned long, unsigned long, unsigned long) args: (option, arg2, arg3, arg4, arg5) +syscall sys_ioprio_set nr 289 nbargs 3 types: (int, int, int) args: (which, who, ioprio) +syscall sys_ioprio_get nr 290 nbargs 2 types: (int, int) args: (which, who) +syscall sys_inotify_init nr 291 nbargs 0 types: () args: () +syscall sys_inotify_add_watch nr 292 nbargs 3 types: (int, const char *, u32) args: (fd, pathname, mask) +syscall sys_inotify_rm_watch nr 293 nbargs 2 types: (int, __s32) args: (fd, wd) +syscall sys_openat nr 295 nbargs 4 types: (int, const char *, int, int) args: (dfd, filename, flags, mode) +syscall sys_mkdirat nr 296 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, mode) +syscall sys_mknodat nr 297 nbargs 4 types: (int, const char *, int, unsigned) args: (dfd, filename, mode, dev) +syscall sys_fchownat nr 298 nbargs 5 types: (int, const char *, uid_t, gid_t, int) args: (dfd, filename, user, group, flag) +syscall sys_futimesat nr 299 nbargs 3 types: (int, const char *, struct timeval *) args: (dfd, filename, utimes) +syscall sys_fstatat64 nr 300 nbargs 4 types: (int, const char *, struct stat64 *, int) args: (dfd, filename, statbuf, flag) +syscall sys_unlinkat nr 301 nbargs 3 types: (int, const char *, int) args: (dfd, pathname, flag) +syscall sys_renameat nr 302 nbargs 4 types: (int, const char *, int, const char *) args: (olddfd, oldname, newdfd, newname) +syscall sys_linkat nr 303 nbargs 5 types: (int, const char *, int, const char *, int) args: (olddfd, oldname, newdfd, newname, flags) +syscall sys_symlinkat nr 304 nbargs 3 types: (const char *, int, const char *) args: (oldname, newdfd, newname) +syscall sys_readlinkat nr 305 nbargs 4 types: (int, const char *, char *, int) args: (dfd, pathname, buf, bufsiz) +syscall sys_fchmodat nr 306 nbargs 3 types: (int, const char *, mode_t) args: (dfd, filename, mode) +syscall sys_faccessat nr 307 nbargs 3 types: (int, const char *, int) args: (dfd, filename, mode) +syscall sys_pselect6 nr 308 nbargs 6 types: (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *) args: (n, inp, outp, exp, tsp, sig) +syscall sys_ppoll nr 309 nbargs 5 types: (struct pollfd *, unsigned int, struct timespec *, const sigset_t *, size_t) args: (ufds, nfds, tsp, sigmask, sigsetsize) +syscall sys_unshare nr 310 nbargs 1 types: (unsigned long) args: (unshare_flags) +syscall sys_set_robust_list nr 311 nbargs 2 types: (struct robust_list_head *, size_t) args: (head, len) +syscall sys_get_robust_list nr 312 nbargs 3 types: (int, struct robust_list_head * *, size_t *) args: (pid, head_ptr, len_ptr) +syscall sys_splice nr 313 nbargs 6 types: (int, loff_t *, int, loff_t *, size_t, unsigned int) args: (fd_in, off_in, fd_out, off_out, len, flags) +syscall sys_tee nr 315 nbargs 4 types: (int, int, size_t, unsigned int) args: (fdin, fdout, len, flags) +syscall sys_vmsplice nr 316 nbargs 4 types: (int, const struct iovec *, unsigned long, unsigned int) args: (fd, iov, nr_segs, flags) +syscall sys_getcpu nr 318 nbargs 3 types: (unsigned *, unsigned *, struct getcpu_cache *) args: (cpup, nodep, unused) +syscall sys_epoll_pwait nr 319 nbargs 6 types: (int, struct epoll_event *, int, int, const sigset_t *, size_t) args: (epfd, events, maxevents, timeout, sigmask, sigsetsize) +syscall sys_utimensat nr 320 nbargs 4 types: (int, const char *, struct timespec *, int) args: (dfd, filename, utimes, flags) +syscall sys_signalfd nr 321 nbargs 3 types: (int, sigset_t *, size_t) args: (ufd, user_mask, sizemask) +syscall sys_timerfd_create nr 322 nbargs 2 types: (int, int) args: (clockid, flags) +syscall sys_eventfd nr 323 nbargs 1 types: (unsigned int) args: (count) +syscall sys_timerfd_settime nr 325 nbargs 4 types: (int, int, const struct itimerspec *, struct itimerspec *) args: (ufd, flags, utmr, otmr) +syscall sys_timerfd_gettime nr 326 nbargs 2 types: (int, struct itimerspec *) args: (ufd, otmr) +syscall sys_signalfd4 nr 327 nbargs 4 types: (int, sigset_t *, size_t, int) args: (ufd, user_mask, sizemask, flags) +syscall sys_eventfd2 nr 328 nbargs 2 types: (unsigned int, int) args: (count, flags) +syscall sys_epoll_create1 nr 329 nbargs 1 types: (int) args: (flags) +syscall sys_dup3 nr 330 nbargs 3 types: (unsigned int, unsigned int, int) args: (oldfd, newfd, flags) +syscall sys_pipe2 nr 331 nbargs 2 types: (int *, int) args: (fildes, flags) +syscall sys_inotify_init1 nr 332 nbargs 1 types: (int) args: (flags) +syscall sys_preadv nr 333 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h) +syscall sys_pwritev nr 334 nbargs 5 types: (unsigned long, const struct iovec *, unsigned long, unsigned long, unsigned long) args: (fd, vec, vlen, pos_l, pos_h) +syscall sys_rt_tgsigqueueinfo nr 335 nbargs 4 types: (pid_t, pid_t, int, siginfo_t *) args: (tgid, pid, sig, uinfo) +syscall sys_perf_event_open nr 336 nbargs 5 types: (struct perf_event_attr *, pid_t, int, int, unsigned long) args: (attr_uptr, pid, cpu, group_fd, flags) +syscall sys_recvmmsg nr 337 nbargs 5 types: (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *) args: (fd, mmsg, vlen, flags, timeout) +syscall sys_fanotify_init nr 338 nbargs 2 types: (unsigned int, unsigned int) args: (flags, event_f_flags) +syscall sys_prlimit64 nr 340 nbargs 4 types: (pid_t, unsigned int, const struct rlimit64 *, struct rlimit64 *) args: (pid, resource, new_rlim, old_rlim) +syscall sys_clock_adjtime nr 343 nbargs 2 types: (const clockid_t, struct timex *) args: (which_clock, utx) +syscall sys_syncfs nr 344 nbargs 1 types: (int) args: (fd) +syscall sys_sendmmsg nr 345 nbargs 4 types: (int, struct mmsghdr *, unsigned int, unsigned int) args: (fd, mmsg, vlen, flags) +syscall sys_setns nr 346 nbargs 2 types: (int, int) args: (fd, nstype) diff --git a/drivers/staging/lttng/instrumentation/syscalls/README b/drivers/staging/lttng/instrumentation/syscalls/README new file mode 100644 index 0000000..6c235e1 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/README @@ -0,0 +1,18 @@ +LTTng system call tracing + +1) lttng-syscall-extractor + +You need to build a kernel with CONFIG_FTRACE_SYSCALLS=y and +CONFIG_KALLSYMS_ALL=y for extraction. Apply the linker patch to get your +kernel to keep the system call metadata after boot. Then build and load +the LTTng syscall extractor module. The module will fail to load (this +is expected). See the dmesg output for system call metadata. + +2) Generate system call TRACE_EVENT(). + +Take the dmesg metadata and feed it to lttng-syscalls-generate-headers.sh, e.g., +from the instrumentation/syscalls directory. See the script header for +usage example. + +After these are created, we just need to follow the new system call additions, +no need to regenerate the whole thing, since system calls are only appended to. diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h new file mode 100644 index 0000000..dabc4bf --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_integers.h @@ -0,0 +1,3 @@ +#ifdef CONFIG_X86_64 +#include "x86-32-syscalls-3.1.0-rc6_integers.h" +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h new file mode 100644 index 0000000..a84423c --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/compat_syscalls_pointers.h @@ -0,0 +1,3 @@ +#ifdef CONFIG_X86_64 +#include "x86-32-syscalls-3.1.0-rc6_pointers.h" +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h new file mode 100644 index 0000000..41db916 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers.h @@ -0,0 +1,7 @@ +#ifdef CONFIG_X86_64 +#include "x86-64-syscalls-3.0.4_integers.h" +#endif + +#ifdef CONFIG_X86_32 +#include "x86-32-syscalls-3.1.0-rc6_integers.h" +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h new file mode 100644 index 0000000..276d9a6 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_integers_override.h @@ -0,0 +1,14 @@ +#define OVERRIDE_32_sys_mmap +#define OVERRIDE_64_sys_mmap + +#ifndef CREATE_SYSCALL_TABLE + +SC_TRACE_EVENT(sys_mmap, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off), + TP_ARGS(addr, len, prot, flags, fd, off), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len) __field(int, prot) __field(int, flags) __field(int, fd) __field(off_t, offset)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(offset, off)), + TP_printk() +) + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h new file mode 100644 index 0000000..3223890 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers.h @@ -0,0 +1,7 @@ +#ifdef CONFIG_X86_64 +#include "x86-64-syscalls-3.0.4_pointers.h" +#endif + +#ifdef CONFIG_X86_32 +#include "x86-32-syscalls-3.1.0-rc6_pointers.h" +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h new file mode 100644 index 0000000..e464a4e --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -0,0 +1,4 @@ +/* + * This is a place-holder for override defines for system calls with + * pointers (all architectures). + */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h new file mode 100644 index 0000000..4582d03 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/syscalls_unknown.h @@ -0,0 +1,55 @@ +#if !defined(_TRACE_SYSCALLS_UNKNOWN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_UNKNOWN_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> + +#define UNKNOWN_SYSCALL_NRARGS 6 + +TRACE_EVENT(sys_unknown, + TP_PROTO(unsigned int id, unsigned long *args), + TP_ARGS(id, args), + TP_STRUCT__entry( + __field(unsigned int, id) + __array(unsigned long, args, UNKNOWN_SYSCALL_NRARGS) + ), + TP_fast_assign( + tp_assign(id, id) + tp_memcpy(args, args, UNKNOWN_SYSCALL_NRARGS * sizeof(*args)) + ), + TP_printk() +) +TRACE_EVENT(compat_sys_unknown, + TP_PROTO(unsigned int id, unsigned long *args), + TP_ARGS(id, args), + TP_STRUCT__entry( + __field(unsigned int, id) + __array(unsigned long, args, UNKNOWN_SYSCALL_NRARGS) + ), + TP_fast_assign( + tp_assign(id, id) + tp_memcpy(args, args, UNKNOWN_SYSCALL_NRARGS * sizeof(*args)) + ), + TP_printk() +) +/* + * This is going to hook on sys_exit in the kernel. + * We change the name so we don't clash with the sys_exit syscall entry + * event. + */ +TRACE_EVENT(exit_syscall, + TP_PROTO(struct pt_regs *regs, long ret), + TP_ARGS(regs, ret), + TP_STRUCT__entry( + __field(long, ret) + ), + TP_fast_assign( + tp_assign(ret, ret) + ), + TP_printk() +) + +#endif /* _TRACE_SYSCALLS_UNKNOWN_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h new file mode 100644 index 0000000..f4ee16c --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers.h @@ -0,0 +1,1163 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_INTEGERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_INTEGERS_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> +#include "x86-32-syscalls-3.1.0-rc6_integers_override.h" +#include "syscalls_integers_override.h" + +SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs, + TP_STRUCT__entry(), + TP_fast_assign(), + TP_printk() +) +#ifndef OVERRIDE_32_sys_restart_syscall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall) +#endif +#ifndef OVERRIDE_32_sys_getpid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid) +#endif +#ifndef OVERRIDE_32_sys_getuid16 +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid16) +#endif +#ifndef OVERRIDE_32_sys_pause +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause) +#endif +#ifndef OVERRIDE_32_sys_sync +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync) +#endif +#ifndef OVERRIDE_32_sys_getgid16 +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid16) +#endif +#ifndef OVERRIDE_32_sys_geteuid16 +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid16) +#endif +#ifndef OVERRIDE_32_sys_getegid16 +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid16) +#endif +#ifndef OVERRIDE_32_sys_getppid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid) +#endif +#ifndef OVERRIDE_32_sys_getpgrp +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp) +#endif +#ifndef OVERRIDE_32_sys_setsid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid) +#endif +#ifndef OVERRIDE_32_sys_sgetmask +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sgetmask) +#endif +#ifndef OVERRIDE_32_sys_vhangup +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup) +#endif +#ifndef OVERRIDE_32_sys_munlockall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall) +#endif +#ifndef OVERRIDE_32_sys_sched_yield +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield) +#endif +#ifndef OVERRIDE_32_sys_getuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid) +#endif +#ifndef OVERRIDE_32_sys_getgid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid) +#endif +#ifndef OVERRIDE_32_sys_geteuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid) +#endif +#ifndef OVERRIDE_32_sys_getegid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid) +#endif +#ifndef OVERRIDE_32_sys_gettid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid) +#endif +#ifndef OVERRIDE_32_sys_inotify_init +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init) +#endif +#ifndef OVERRIDE_32_sys_exit +SC_TRACE_EVENT(sys_exit, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_close +SC_TRACE_EVENT(sys_close, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setuid16 +SC_TRACE_EVENT(sys_setuid16, + TP_PROTO(old_uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(old_uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_alarm +SC_TRACE_EVENT(sys_alarm, + TP_PROTO(unsigned int seconds), + TP_ARGS(seconds), + TP_STRUCT__entry(__field(unsigned int, seconds)), + TP_fast_assign(tp_assign(seconds, seconds)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_nice +SC_TRACE_EVENT(sys_nice, + TP_PROTO(int increment), + TP_ARGS(increment), + TP_STRUCT__entry(__field(int, increment)), + TP_fast_assign(tp_assign(increment, increment)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_dup +SC_TRACE_EVENT(sys_dup, + TP_PROTO(unsigned int fildes), + TP_ARGS(fildes), + TP_STRUCT__entry(__field(unsigned int, fildes)), + TP_fast_assign(tp_assign(fildes, fildes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_brk +SC_TRACE_EVENT(sys_brk, + TP_PROTO(unsigned long brk), + TP_ARGS(brk), + TP_STRUCT__entry(__field(unsigned long, brk)), + TP_fast_assign(tp_assign(brk, brk)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setgid16 +SC_TRACE_EVENT(sys_setgid16, + TP_PROTO(old_gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(old_gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_umask +SC_TRACE_EVENT(sys_umask, + TP_PROTO(int mask), + TP_ARGS(mask), + TP_STRUCT__entry(__field(int, mask)), + TP_fast_assign(tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ssetmask +SC_TRACE_EVENT(sys_ssetmask, + TP_PROTO(int newmask), + TP_ARGS(newmask), + TP_STRUCT__entry(__field(int, newmask)), + TP_fast_assign(tp_assign(newmask, newmask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fsync +SC_TRACE_EVENT(sys_fsync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getpgid +SC_TRACE_EVENT(sys_getpgid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchdir +SC_TRACE_EVENT(sys_fchdir, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_personality +SC_TRACE_EVENT(sys_personality, + TP_PROTO(unsigned int personality), + TP_ARGS(personality), + TP_STRUCT__entry(__field(unsigned int, personality)), + TP_fast_assign(tp_assign(personality, personality)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setfsuid16 +SC_TRACE_EVENT(sys_setfsuid16, + TP_PROTO(old_uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(old_uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setfsgid16 +SC_TRACE_EVENT(sys_setfsgid16, + TP_PROTO(old_gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(old_gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getsid +SC_TRACE_EVENT(sys_getsid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fdatasync +SC_TRACE_EVENT(sys_fdatasync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mlockall +SC_TRACE_EVENT(sys_mlockall, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_getscheduler +SC_TRACE_EVENT(sys_sched_getscheduler, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_get_priority_max +SC_TRACE_EVENT(sys_sched_get_priority_max, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_get_priority_min +SC_TRACE_EVENT(sys_sched_get_priority_min, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setuid +SC_TRACE_EVENT(sys_setuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setgid +SC_TRACE_EVENT(sys_setgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setfsuid +SC_TRACE_EVENT(sys_setfsuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setfsgid +SC_TRACE_EVENT(sys_setfsgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_io_destroy +SC_TRACE_EVENT(sys_io_destroy, + TP_PROTO(aio_context_t ctx), + TP_ARGS(ctx), + TP_STRUCT__entry(__field(aio_context_t, ctx)), + TP_fast_assign(tp_assign(ctx, ctx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_exit_group +SC_TRACE_EVENT(sys_exit_group, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_epoll_create +SC_TRACE_EVENT(sys_epoll_create, + TP_PROTO(int size), + TP_ARGS(size), + TP_STRUCT__entry(__field(int, size)), + TP_fast_assign(tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timer_getoverrun +SC_TRACE_EVENT(sys_timer_getoverrun, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timer_delete +SC_TRACE_EVENT(sys_timer_delete, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_unshare +SC_TRACE_EVENT(sys_unshare, + TP_PROTO(unsigned long unshare_flags), + TP_ARGS(unshare_flags), + TP_STRUCT__entry(__field(unsigned long, unshare_flags)), + TP_fast_assign(tp_assign(unshare_flags, unshare_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_eventfd +SC_TRACE_EVENT(sys_eventfd, + TP_PROTO(unsigned int count), + TP_ARGS(count), + TP_STRUCT__entry(__field(unsigned int, count)), + TP_fast_assign(tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_epoll_create1 +SC_TRACE_EVENT(sys_epoll_create1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_inotify_init1 +SC_TRACE_EVENT(sys_inotify_init1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_syncfs +SC_TRACE_EVENT(sys_syncfs, + TP_PROTO(int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_kill +SC_TRACE_EVENT(sys_kill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_signal +SC_TRACE_EVENT(sys_signal, + TP_PROTO(int sig, __sighandler_t handler), + TP_ARGS(sig, handler), + TP_STRUCT__entry(__field(int, sig) __field(__sighandler_t, handler)), + TP_fast_assign(tp_assign(sig, sig) tp_assign(handler, handler)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setpgid +SC_TRACE_EVENT(sys_setpgid, + TP_PROTO(pid_t pid, pid_t pgid), + TP_ARGS(pid, pgid), + TP_STRUCT__entry(__field(pid_t, pid) __field(pid_t, pgid)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(pgid, pgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_dup2 +SC_TRACE_EVENT(sys_dup2, + TP_PROTO(unsigned int oldfd, unsigned int newfd), + TP_ARGS(oldfd, newfd), + TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd)), + TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setreuid16 +SC_TRACE_EVENT(sys_setreuid16, + TP_PROTO(old_uid_t ruid, old_uid_t euid), + TP_ARGS(ruid, euid), + TP_STRUCT__entry(__field(old_uid_t, ruid) __field(old_uid_t, euid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setregid16 +SC_TRACE_EVENT(sys_setregid16, + TP_PROTO(old_gid_t rgid, old_gid_t egid), + TP_ARGS(rgid, egid), + TP_STRUCT__entry(__field(old_gid_t, rgid) __field(old_gid_t, egid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_munmap +SC_TRACE_EVENT(sys_munmap, + TP_PROTO(unsigned long addr, size_t len), + TP_ARGS(addr, len), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ftruncate +SC_TRACE_EVENT(sys_ftruncate, + TP_PROTO(unsigned int fd, unsigned long length), + TP_ARGS(fd, length), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, length)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchmod +SC_TRACE_EVENT(sys_fchmod, + TP_PROTO(unsigned int fd, mode_t mode), + TP_ARGS(fd, mode), + TP_STRUCT__entry(__field(unsigned int, fd) __field(mode_t, mode)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getpriority +SC_TRACE_EVENT(sys_getpriority, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_bdflush +SC_TRACE_EVENT(sys_bdflush, + TP_PROTO(int func, long data), + TP_ARGS(func, data), + TP_STRUCT__entry(__field(int, func) __field(long, data)), + TP_fast_assign(tp_assign(func, func) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_flock +SC_TRACE_EVENT(sys_flock, + TP_PROTO(unsigned int fd, unsigned int cmd), + TP_ARGS(fd, cmd), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mlock +SC_TRACE_EVENT(sys_mlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_munlock +SC_TRACE_EVENT(sys_munlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setreuid +SC_TRACE_EVENT(sys_setreuid, + TP_PROTO(uid_t ruid, uid_t euid), + TP_ARGS(ruid, euid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setregid +SC_TRACE_EVENT(sys_setregid, + TP_PROTO(gid_t rgid, gid_t egid), + TP_ARGS(rgid, egid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_tkill +SC_TRACE_EVENT(sys_tkill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ioprio_get +SC_TRACE_EVENT(sys_ioprio_get, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_inotify_rm_watch +SC_TRACE_EVENT(sys_inotify_rm_watch, + TP_PROTO(int fd, __s32 wd), + TP_ARGS(fd, wd), + TP_STRUCT__entry(__field(int, fd) __field(__s32, wd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(wd, wd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timerfd_create +SC_TRACE_EVENT(sys_timerfd_create, + TP_PROTO(int clockid, int flags), + TP_ARGS(clockid, flags), + TP_STRUCT__entry(__field(int, clockid) __field(int, flags)), + TP_fast_assign(tp_assign(clockid, clockid) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_eventfd2 +SC_TRACE_EVENT(sys_eventfd2, + TP_PROTO(unsigned int count, int flags), + TP_ARGS(count, flags), + TP_STRUCT__entry(__field(unsigned int, count) __field(int, flags)), + TP_fast_assign(tp_assign(count, count) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fanotify_init +SC_TRACE_EVENT(sys_fanotify_init, + TP_PROTO(unsigned int flags, unsigned int event_f_flags), + TP_ARGS(flags, event_f_flags), + TP_STRUCT__entry(__field(unsigned int, flags) __field(unsigned int, event_f_flags)), + TP_fast_assign(tp_assign(flags, flags) tp_assign(event_f_flags, event_f_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setns +SC_TRACE_EVENT(sys_setns, + TP_PROTO(int fd, int nstype), + TP_ARGS(fd, nstype), + TP_STRUCT__entry(__field(int, fd) __field(int, nstype)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(nstype, nstype)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lseek +SC_TRACE_EVENT(sys_lseek, + TP_PROTO(unsigned int fd, off_t offset, unsigned int origin), + TP_ARGS(fd, offset, origin), + TP_STRUCT__entry(__field(unsigned int, fd) __field(off_t, offset) __field(unsigned int, origin)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(offset, offset) tp_assign(origin, origin)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ioctl +SC_TRACE_EVENT(sys_ioctl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fcntl +SC_TRACE_EVENT(sys_fcntl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchown16 +SC_TRACE_EVENT(sys_fchown16, + TP_PROTO(unsigned int fd, old_uid_t user, old_gid_t group), + TP_ARGS(fd, user, group), + TP_STRUCT__entry(__field(unsigned int, fd) __field(old_uid_t, user) __field(old_gid_t, group)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setpriority +SC_TRACE_EVENT(sys_setpriority, + TP_PROTO(int which, int who, int niceval), + TP_ARGS(which, who, niceval), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, niceval)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(niceval, niceval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mprotect +SC_TRACE_EVENT(sys_mprotect, + TP_PROTO(unsigned long start, size_t len, unsigned long prot), + TP_ARGS(start, len, prot), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(unsigned long, prot)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(prot, prot)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sysfs +SC_TRACE_EVENT(sys_sysfs, + TP_PROTO(int option, unsigned long arg1, unsigned long arg2), + TP_ARGS(option, arg1, arg2), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg1) __field(unsigned long, arg2)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg1, arg1) tp_assign(arg2, arg2)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_msync +SC_TRACE_EVENT(sys_msync, + TP_PROTO(unsigned long start, size_t len, int flags), + TP_ARGS(start, len, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(int, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setresuid16 +SC_TRACE_EVENT(sys_setresuid16, + TP_PROTO(old_uid_t ruid, old_uid_t euid, old_uid_t suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field(old_uid_t, ruid) __field(old_uid_t, euid) __field(old_uid_t, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setresgid16 +SC_TRACE_EVENT(sys_setresgid16, + TP_PROTO(old_gid_t rgid, old_gid_t egid, old_gid_t sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field(old_gid_t, rgid) __field(old_gid_t, egid) __field(old_gid_t, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchown +SC_TRACE_EVENT(sys_fchown, + TP_PROTO(unsigned int fd, uid_t user, gid_t group), + TP_ARGS(fd, user, group), + TP_STRUCT__entry(__field(unsigned int, fd) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setresuid +SC_TRACE_EVENT(sys_setresuid, + TP_PROTO(uid_t ruid, uid_t euid, uid_t suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid) __field(uid_t, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setresgid +SC_TRACE_EVENT(sys_setresgid, + TP_PROTO(gid_t rgid, gid_t egid, gid_t sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid) __field(gid_t, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_madvise +SC_TRACE_EVENT(sys_madvise, + TP_PROTO(unsigned long start, size_t len_in, int behavior), + TP_ARGS(start, len_in, behavior), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len_in) __field(int, behavior)), + TP_fast_assign(tp_assign(start, start) tp_assign(len_in, len_in) tp_assign(behavior, behavior)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fcntl64 +SC_TRACE_EVENT(sys_fcntl64, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_tgkill +SC_TRACE_EVENT(sys_tgkill, + TP_PROTO(pid_t tgid, pid_t pid, int sig), + TP_ARGS(tgid, pid, sig), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ioprio_set +SC_TRACE_EVENT(sys_ioprio_set, + TP_PROTO(int which, int who, int ioprio), + TP_ARGS(which, who, ioprio), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, ioprio)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(ioprio, ioprio)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_dup3 +SC_TRACE_EVENT(sys_dup3, + TP_PROTO(unsigned int oldfd, unsigned int newfd, int flags), + TP_ARGS(oldfd, newfd, flags), + TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd) __field(int, flags)), + TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ptrace +SC_TRACE_EVENT(sys_ptrace, + TP_PROTO(long request, long pid, unsigned long addr, unsigned long data), + TP_ARGS(request, pid, addr, data), + TP_STRUCT__entry(__field(long, request) __field(long, pid) __field_hex(unsigned long, addr) __field(unsigned long, data)), + TP_fast_assign(tp_assign(request, request) tp_assign(pid, pid) tp_assign(addr, addr) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_tee +SC_TRACE_EVENT(sys_tee, + TP_PROTO(int fdin, int fdout, size_t len, unsigned int flags), + TP_ARGS(fdin, fdout, len, flags), + TP_STRUCT__entry(__field(int, fdin) __field(int, fdout) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fdin, fdin) tp_assign(fdout, fdout) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mremap +SC_TRACE_EVENT(sys_mremap, + TP_PROTO(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr), + TP_ARGS(addr, old_len, new_len, flags, new_addr), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, old_len) __field(unsigned long, new_len) __field(unsigned long, flags) __field_hex(unsigned long, new_addr)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(old_len, old_len) tp_assign(new_len, new_len) tp_assign(flags, flags) tp_assign(new_addr, new_addr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_prctl +SC_TRACE_EVENT(sys_prctl, + TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5), + TP_ARGS(option, arg2, arg3, arg4, arg5), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_remap_file_pages +SC_TRACE_EVENT(sys_remap_file_pages, + TP_PROTO(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags), + TP_ARGS(start, size, prot, pgoff, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, size) __field(unsigned long, prot) __field(unsigned long, pgoff) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(size, size) tp_assign(prot, prot) tp_assign(pgoff, pgoff) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_keyctl +SC_TRACE_EVENT(sys_keyctl, + TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5), + TP_ARGS(option, arg2, arg3, arg4, arg5), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mmap_pgoff +SC_TRACE_EVENT(sys_mmap_pgoff, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff), + TP_ARGS(addr, len, prot, flags, fd, pgoff), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, prot) __field(unsigned long, flags) __field(unsigned long, fd) __field(unsigned long, pgoff)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(pgoff, pgoff)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_INTEGERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "x86-32-syscalls-3.1.0-rc6_integers_override.h" +#include "syscalls_integers_override.h" + +#ifndef OVERRIDE_TABLE_32_sys_restart_syscall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 0, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getpid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 20, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getuid16 +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid16, 24, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pause +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 29, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sync +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 36, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getgid16 +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid16, 47, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_geteuid16 +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid16, 49, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getegid16 +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid16, 50, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getppid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 64, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getpgrp +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 65, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setsid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 66, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sgetmask +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sgetmask, 68, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_vhangup +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 111, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_munlockall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 153, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_yield +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 158, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 199, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getgid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 200, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_geteuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 201, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getegid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 202, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_gettid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 224, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_inotify_init +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 291, 0) +#endif +#ifndef OVERRIDE_TABLE_32_sys_exit +TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 1, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_close +TRACE_SYSCALL_TABLE(sys_close, sys_close, 6, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lseek +TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 19, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setuid16 +TRACE_SYSCALL_TABLE(sys_setuid16, sys_setuid16, 23, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ptrace +TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 26, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_alarm +TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 27, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_nice +TRACE_SYSCALL_TABLE(sys_nice, sys_nice, 34, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_kill +TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 37, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_dup +TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 41, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_brk +TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 45, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setgid16 +TRACE_SYSCALL_TABLE(sys_setgid16, sys_setgid16, 46, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_signal +TRACE_SYSCALL_TABLE(sys_signal, sys_signal, 48, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ioctl +TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 54, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fcntl +TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 55, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setpgid +TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 57, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_umask +TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 60, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_dup2 +TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 63, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ssetmask +TRACE_SYSCALL_TABLE(sys_ssetmask, sys_ssetmask, 69, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setreuid16 +TRACE_SYSCALL_TABLE(sys_setreuid16, sys_setreuid16, 70, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setregid16 +TRACE_SYSCALL_TABLE(sys_setregid16, sys_setregid16, 71, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_munmap +TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 91, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ftruncate +TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 93, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchmod +TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 94, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchown16 +TRACE_SYSCALL_TABLE(sys_fchown16, sys_fchown16, 95, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getpriority +TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 96, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setpriority +TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 97, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fsync +TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 118, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mprotect +TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 125, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getpgid +TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 132, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchdir +TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 133, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_bdflush +TRACE_SYSCALL_TABLE(sys_bdflush, sys_bdflush, 134, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sysfs +TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 135, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_personality +TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 136, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setfsuid16 +TRACE_SYSCALL_TABLE(sys_setfsuid16, sys_setfsuid16, 138, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setfsgid16 +TRACE_SYSCALL_TABLE(sys_setfsgid16, sys_setfsgid16, 139, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_flock +TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 143, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_msync +TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 144, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getsid +TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 147, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fdatasync +TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 148, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mlock +TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 150, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_munlock +TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 151, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mlockall +TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 152, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_getscheduler +TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 157, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_get_priority_max +TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 159, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_get_priority_min +TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 160, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mremap +TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 163, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setresuid16 +TRACE_SYSCALL_TABLE(sys_setresuid16, sys_setresuid16, 164, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setresgid16 +TRACE_SYSCALL_TABLE(sys_setresgid16, sys_setresgid16, 170, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_prctl +TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 172, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mmap_pgoff +TRACE_SYSCALL_TABLE(sys_mmap_pgoff, sys_mmap_pgoff, 192, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setreuid +TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 203, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setregid +TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 204, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchown +TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 207, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setresuid +TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 208, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setresgid +TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 210, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setuid +TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 213, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setgid +TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 214, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setfsuid +TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 215, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setfsgid +TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 216, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_madvise +TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 219, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fcntl64 +TRACE_SYSCALL_TABLE(sys_fcntl64, sys_fcntl64, 221, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_tkill +TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 238, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_io_destroy +TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 246, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_exit_group +TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 252, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_epoll_create +TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 254, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_remap_file_pages +TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 257, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timer_getoverrun +TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 262, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timer_delete +TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 263, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_tgkill +TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 270, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_keyctl +TRACE_SYSCALL_TABLE(sys_keyctl, sys_keyctl, 288, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ioprio_set +TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 289, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ioprio_get +TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 290, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_inotify_rm_watch +TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 293, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_unshare +TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 310, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_tee +TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 315, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timerfd_create +TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 322, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_eventfd +TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 323, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_eventfd2 +TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 328, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_epoll_create1 +TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 329, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_dup3 +TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 330, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_inotify_init1 +TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 332, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fanotify_init +TRACE_SYSCALL_TABLE(sys_fanotify_init, sys_fanotify_init, 338, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_syncfs +TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 344, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setns +TRACE_SYSCALL_TABLE(sys_setns, sys_setns, 346, 2) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h new file mode 100644 index 0000000..ed2cf1f --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_integers_override.h @@ -0,0 +1,38 @@ +#ifndef CONFIG_UID16 + +#define OVERRIDE_32_sys_getuid16 +#define OVERRIDE_32_sys_getgid16 +#define OVERRIDE_32_sys_geteuid16 +#define OVERRIDE_32_sys_getegid16 +#define OVERRIDE_32_sys_setuid16 +#define OVERRIDE_32_sys_setgid16 +#define OVERRIDE_32_sys_setfsuid16 +#define OVERRIDE_32_sys_setfsgid16 +#define OVERRIDE_32_sys_setreuid16 +#define OVERRIDE_32_sys_setregid16 +#define OVERRIDE_32_sys_fchown16 +#define OVERRIDE_32_sys_setresuid16 +#define OVERRIDE_32_sys_setresgid16 + +#define OVERRIDE_TABLE_32_sys_getuid16 +#define OVERRIDE_TABLE_32_sys_getgid16 +#define OVERRIDE_TABLE_32_sys_geteuid16 +#define OVERRIDE_TABLE_32_sys_getegid16 +#define OVERRIDE_TABLE_32_sys_setuid16 +#define OVERRIDE_TABLE_32_sys_setgid16 +#define OVERRIDE_TABLE_32_sys_setreuid16 +#define OVERRIDE_TABLE_32_sys_setregid16 +#define OVERRIDE_TABLE_32_sys_fchown16 +#define OVERRIDE_TABLE_32_sys_setfsuid16 +#define OVERRIDE_TABLE_32_sys_setfsgid16 +#define OVERRIDE_TABLE_32_sys_setresuid16 +#define OVERRIDE_TABLE_32_sys_setresgid16 + +#endif + +#ifdef CREATE_SYSCALL_TABLE + +#define OVERRIDE_TABLE_32_sys_mmap +TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 90, 6) + +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h new file mode 100644 index 0000000..ec5b301 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers.h @@ -0,0 +1,2232 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_POINTERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_POINTERS_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> +#include "x86-32-syscalls-3.1.0-rc6_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_32_sys_unlink +SC_TRACE_EVENT(sys_unlink, + TP_PROTO(const char * pathname), + TP_ARGS(pathname), + TP_STRUCT__entry(__string_from_user(pathname, pathname)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_chdir +SC_TRACE_EVENT(sys_chdir, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_time +SC_TRACE_EVENT(sys_time, + TP_PROTO(time_t * tloc), + TP_ARGS(tloc), + TP_STRUCT__entry(__field_hex(time_t *, tloc)), + TP_fast_assign(tp_assign(tloc, tloc)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_oldumount +SC_TRACE_EVENT(sys_oldumount, + TP_PROTO(char * name), + TP_ARGS(name), + TP_STRUCT__entry(__string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_stime +SC_TRACE_EVENT(sys_stime, + TP_PROTO(time_t * tptr), + TP_ARGS(tptr), + TP_STRUCT__entry(__field_hex(time_t *, tptr)), + TP_fast_assign(tp_assign(tptr, tptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rmdir +SC_TRACE_EVENT(sys_rmdir, + TP_PROTO(const char * pathname), + TP_ARGS(pathname), + TP_STRUCT__entry(__string_from_user(pathname, pathname)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_pipe +SC_TRACE_EVENT(sys_pipe, + TP_PROTO(int * fildes), + TP_ARGS(fildes), + TP_STRUCT__entry(__field_hex(int *, fildes)), + TP_fast_assign(tp_assign(fildes, fildes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_times +SC_TRACE_EVENT(sys_times, + TP_PROTO(struct tms * tbuf), + TP_ARGS(tbuf), + TP_STRUCT__entry(__field_hex(struct tms *, tbuf)), + TP_fast_assign(tp_assign(tbuf, tbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_acct +SC_TRACE_EVENT(sys_acct, + TP_PROTO(const char * name), + TP_ARGS(name), + TP_STRUCT__entry(__string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_olduname +SC_TRACE_EVENT(sys_olduname, + TP_PROTO(struct oldold_utsname * name), + TP_ARGS(name), + TP_STRUCT__entry(__field_hex(struct oldold_utsname *, name)), + TP_fast_assign(tp_assign(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_chroot +SC_TRACE_EVENT(sys_chroot, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sigpending +SC_TRACE_EVENT(sys_sigpending, + TP_PROTO(old_sigset_t * set), + TP_ARGS(set), + TP_STRUCT__entry(__field_hex(old_sigset_t *, set)), + TP_fast_assign(tp_assign(set, set)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_old_select +SC_TRACE_EVENT(sys_old_select, + TP_PROTO(struct sel_arg_struct * arg), + TP_ARGS(arg), + TP_STRUCT__entry(__field_hex(struct sel_arg_struct *, arg)), + TP_fast_assign(tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_uselib +SC_TRACE_EVENT(sys_uselib, + TP_PROTO(const char * library), + TP_ARGS(library), + TP_STRUCT__entry(__field_hex(const char *, library)), + TP_fast_assign(tp_assign(library, library)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_old_mmap +SC_TRACE_EVENT(sys_old_mmap, + TP_PROTO(struct mmap_arg_struct * arg), + TP_ARGS(arg), + TP_STRUCT__entry(__field_hex(struct mmap_arg_struct *, arg)), + TP_fast_assign(tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_uname +SC_TRACE_EVENT(sys_uname, + TP_PROTO(struct old_utsname * name), + TP_ARGS(name), + TP_STRUCT__entry(__field_hex(struct old_utsname *, name)), + TP_fast_assign(tp_assign(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_swapoff +SC_TRACE_EVENT(sys_swapoff, + TP_PROTO(const char * specialfile), + TP_ARGS(specialfile), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sysinfo +SC_TRACE_EVENT(sys_sysinfo, + TP_PROTO(struct sysinfo * info), + TP_ARGS(info), + TP_STRUCT__entry(__field_hex(struct sysinfo *, info)), + TP_fast_assign(tp_assign(info, info)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_newuname +SC_TRACE_EVENT(sys_newuname, + TP_PROTO(struct new_utsname * name), + TP_ARGS(name), + TP_STRUCT__entry(__field_hex(struct new_utsname *, name)), + TP_fast_assign(tp_assign(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_adjtimex +SC_TRACE_EVENT(sys_adjtimex, + TP_PROTO(struct timex * txc_p), + TP_ARGS(txc_p), + TP_STRUCT__entry(__field_hex(struct timex *, txc_p)), + TP_fast_assign(tp_assign(txc_p, txc_p)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sysctl +SC_TRACE_EVENT(sys_sysctl, + TP_PROTO(struct __sysctl_args * args), + TP_ARGS(args), + TP_STRUCT__entry(__field_hex(struct __sysctl_args *, args)), + TP_fast_assign(tp_assign(args, args)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_set_tid_address +SC_TRACE_EVENT(sys_set_tid_address, + TP_PROTO(int * tidptr), + TP_ARGS(tidptr), + TP_STRUCT__entry(__field_hex(int *, tidptr)), + TP_fast_assign(tp_assign(tidptr, tidptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_unlink +SC_TRACE_EVENT(sys_mq_unlink, + TP_PROTO(const char * u_name), + TP_ARGS(u_name), + TP_STRUCT__entry(__string_from_user(u_name, u_name)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_creat +SC_TRACE_EVENT(sys_creat, + TP_PROTO(const char * pathname, int mode), + TP_ARGS(pathname, mode), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_link +SC_TRACE_EVENT(sys_link, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_chmod +SC_TRACE_EVENT(sys_chmod, + TP_PROTO(const char * filename, mode_t mode), + TP_ARGS(filename, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(mode_t, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_stat +SC_TRACE_EVENT(sys_stat, + TP_PROTO(const char * filename, struct __old_kernel_stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct __old_kernel_stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fstat +SC_TRACE_EVENT(sys_fstat, + TP_PROTO(unsigned int fd, struct __old_kernel_stat * statbuf), + TP_ARGS(fd, statbuf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct __old_kernel_stat *, statbuf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_utime +SC_TRACE_EVENT(sys_utime, + TP_PROTO(char * filename, struct utimbuf * times), + TP_ARGS(filename, times), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct utimbuf *, times)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(times, times)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_access +SC_TRACE_EVENT(sys_access, + TP_PROTO(const char * filename, int mode), + TP_ARGS(filename, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rename +SC_TRACE_EVENT(sys_rename, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mkdir +SC_TRACE_EVENT(sys_mkdir, + TP_PROTO(const char * pathname, int mode), + TP_ARGS(pathname, mode), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_umount +SC_TRACE_EVENT(sys_umount, + TP_PROTO(char * name, int flags), + TP_ARGS(name, flags), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ustat +SC_TRACE_EVENT(sys_ustat, + TP_PROTO(unsigned dev, struct ustat * ubuf), + TP_ARGS(dev, ubuf), + TP_STRUCT__entry(__field(unsigned, dev) __field_hex(struct ustat *, ubuf)), + TP_fast_assign(tp_assign(dev, dev) tp_assign(ubuf, ubuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sethostname +SC_TRACE_EVENT(sys_sethostname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setrlimit +SC_TRACE_EVENT(sys_setrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_old_getrlimit +SC_TRACE_EVENT(sys_old_getrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getrusage +SC_TRACE_EVENT(sys_getrusage, + TP_PROTO(int who, struct rusage * ru), + TP_ARGS(who, ru), + TP_STRUCT__entry(__field(int, who) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(who, who) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_gettimeofday +SC_TRACE_EVENT(sys_gettimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_settimeofday +SC_TRACE_EVENT(sys_settimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getgroups16 +SC_TRACE_EVENT(sys_getgroups16, + TP_PROTO(int gidsetsize, old_gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(old_gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setgroups16 +SC_TRACE_EVENT(sys_setgroups16, + TP_PROTO(int gidsetsize, old_gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(old_gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_symlink +SC_TRACE_EVENT(sys_symlink, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lstat +SC_TRACE_EVENT(sys_lstat, + TP_PROTO(const char * filename, struct __old_kernel_stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct __old_kernel_stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_swapon +SC_TRACE_EVENT(sys_swapon, + TP_PROTO(const char * specialfile, int swap_flags), + TP_ARGS(specialfile, swap_flags), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile) __field(int, swap_flags)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile) tp_assign(swap_flags, swap_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_truncate +SC_TRACE_EVENT(sys_truncate, + TP_PROTO(const char * path, long length), + TP_ARGS(path, length), + TP_STRUCT__entry(__string_from_user(path, path) __field(long, length)), + TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_statfs +SC_TRACE_EVENT(sys_statfs, + TP_PROTO(const char * pathname, struct statfs * buf), + TP_ARGS(pathname, buf), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fstatfs +SC_TRACE_EVENT(sys_fstatfs, + TP_PROTO(unsigned int fd, struct statfs * buf), + TP_ARGS(fd, buf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_socketcall +SC_TRACE_EVENT(sys_socketcall, + TP_PROTO(int call, unsigned long * args), + TP_ARGS(call, args), + TP_STRUCT__entry(__field(int, call) __field_hex(unsigned long *, args)), + TP_fast_assign(tp_assign(call, call) tp_assign(args, args)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getitimer +SC_TRACE_EVENT(sys_getitimer, + TP_PROTO(int which, struct itimerval * value), + TP_ARGS(which, value), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_newstat +SC_TRACE_EVENT(sys_newstat, + TP_PROTO(const char * filename, struct stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_newlstat +SC_TRACE_EVENT(sys_newlstat, + TP_PROTO(const char * filename, struct stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_newfstat +SC_TRACE_EVENT(sys_newfstat, + TP_PROTO(unsigned int fd, struct stat * statbuf), + TP_ARGS(fd, statbuf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setdomainname +SC_TRACE_EVENT(sys_setdomainname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_delete_module +SC_TRACE_EVENT(sys_delete_module, + TP_PROTO(const char * name_user, unsigned int flags), + TP_ARGS(name_user, flags), + TP_STRUCT__entry(__string_from_user(name_user, name_user) __field(unsigned int, flags)), + TP_fast_assign(tp_copy_string_from_user(name_user, name_user) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_setparam +SC_TRACE_EVENT(sys_sched_setparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_getparam +SC_TRACE_EVENT(sys_sched_getparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_rr_get_interval +SC_TRACE_EVENT(sys_sched_rr_get_interval, + TP_PROTO(pid_t pid, struct timespec * interval), + TP_ARGS(pid, interval), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct timespec *, interval)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(interval, interval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_nanosleep +SC_TRACE_EVENT(sys_nanosleep, + TP_PROTO(struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(rqtp, rmtp), + TP_STRUCT__entry(__field_hex(struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigpending +SC_TRACE_EVENT(sys_rt_sigpending, + TP_PROTO(sigset_t * set, size_t sigsetsize), + TP_ARGS(set, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, set) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(set, set) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigsuspend +SC_TRACE_EVENT(sys_rt_sigsuspend, + TP_PROTO(sigset_t * unewset, size_t sigsetsize), + TP_ARGS(unewset, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, unewset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(unewset, unewset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getcwd +SC_TRACE_EVENT(sys_getcwd, + TP_PROTO(char * buf, unsigned long size), + TP_ARGS(buf, size), + TP_STRUCT__entry(__field_hex(char *, buf) __field(unsigned long, size)), + TP_fast_assign(tp_assign(buf, buf) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getrlimit +SC_TRACE_EVENT(sys_getrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_stat64 +SC_TRACE_EVENT(sys_stat64, + TP_PROTO(const char * filename, struct stat64 * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lstat64 +SC_TRACE_EVENT(sys_lstat64, + TP_PROTO(const char * filename, struct stat64 * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fstat64 +SC_TRACE_EVENT(sys_fstat64, + TP_PROTO(unsigned long fd, struct stat64 * statbuf), + TP_ARGS(fd, statbuf), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(struct stat64 *, statbuf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getgroups +SC_TRACE_EVENT(sys_getgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setgroups +SC_TRACE_EVENT(sys_setgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_pivot_root +SC_TRACE_EVENT(sys_pivot_root, + TP_PROTO(const char * new_root, const char * put_old), + TP_ARGS(new_root, put_old), + TP_STRUCT__entry(__string_from_user(new_root, new_root) __string_from_user(put_old, put_old)), + TP_fast_assign(tp_copy_string_from_user(new_root, new_root) tp_copy_string_from_user(put_old, put_old)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_removexattr +SC_TRACE_EVENT(sys_removexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lremovexattr +SC_TRACE_EVENT(sys_lremovexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fremovexattr +SC_TRACE_EVENT(sys_fremovexattr, + TP_PROTO(int fd, const char * name), + TP_ARGS(fd, name), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_io_setup +SC_TRACE_EVENT(sys_io_setup, + TP_PROTO(unsigned nr_events, aio_context_t * ctxp), + TP_ARGS(nr_events, ctxp), + TP_STRUCT__entry(__field(unsigned, nr_events) __field_hex(aio_context_t *, ctxp)), + TP_fast_assign(tp_assign(nr_events, nr_events) tp_assign(ctxp, ctxp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timer_gettime +SC_TRACE_EVENT(sys_timer_gettime, + TP_PROTO(timer_t timer_id, struct itimerspec * setting), + TP_ARGS(timer_id, setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field_hex(struct itimerspec *, setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(setting, setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_clock_settime +SC_TRACE_EVENT(sys_clock_settime, + TP_PROTO(const clockid_t which_clock, const struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(const struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_clock_gettime +SC_TRACE_EVENT(sys_clock_gettime, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_clock_getres +SC_TRACE_EVENT(sys_clock_getres, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_utimes +SC_TRACE_EVENT(sys_utimes, + TP_PROTO(char * filename, struct timeval * utimes), + TP_ARGS(filename, utimes), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct timeval *, utimes)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_notify +SC_TRACE_EVENT(sys_mq_notify, + TP_PROTO(mqd_t mqdes, const struct sigevent * u_notification), + TP_ARGS(mqdes, u_notification), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct sigevent *, u_notification)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_notification, u_notification)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_set_robust_list +SC_TRACE_EVENT(sys_set_robust_list, + TP_PROTO(struct robust_list_head * head, size_t len), + TP_ARGS(head, len), + TP_STRUCT__entry(__field_hex(struct robust_list_head *, head) __field(size_t, len)), + TP_fast_assign(tp_assign(head, head) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timerfd_gettime +SC_TRACE_EVENT(sys_timerfd_gettime, + TP_PROTO(int ufd, struct itimerspec * otmr), + TP_ARGS(ufd, otmr), + TP_STRUCT__entry(__field(int, ufd) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_pipe2 +SC_TRACE_EVENT(sys_pipe2, + TP_PROTO(int * fildes, int flags), + TP_ARGS(fildes, flags), + TP_STRUCT__entry(__field_hex(int *, fildes) __field(int, flags)), + TP_fast_assign(tp_assign(fildes, fildes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_clock_adjtime +SC_TRACE_EVENT(sys_clock_adjtime, + TP_PROTO(const clockid_t which_clock, struct timex * utx), + TP_ARGS(which_clock, utx), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timex *, utx)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(utx, utx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_read +SC_TRACE_EVENT(sys_read, + TP_PROTO(unsigned int fd, char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_write +SC_TRACE_EVENT(sys_write, + TP_PROTO(unsigned int fd, const char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(const char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_open +SC_TRACE_EVENT(sys_open, + TP_PROTO(const char * filename, int flags, int mode), + TP_ARGS(filename, flags, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, flags) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_waitpid +SC_TRACE_EVENT(sys_waitpid, + TP_PROTO(pid_t pid, int * stat_addr, int options), + TP_ARGS(pid, stat_addr, options), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(int *, stat_addr) __field(int, options)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(stat_addr, stat_addr) tp_assign(options, options)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mknod +SC_TRACE_EVENT(sys_mknod, + TP_PROTO(const char * filename, int mode, unsigned dev), + TP_ARGS(filename, mode, dev), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lchown16 +SC_TRACE_EVENT(sys_lchown16, + TP_PROTO(const char * filename, old_uid_t user, old_gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(old_uid_t, user) __field(old_gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_readlink +SC_TRACE_EVENT(sys_readlink, + TP_PROTO(const char * path, char * buf, int bufsiz), + TP_ARGS(path, buf, bufsiz), + TP_STRUCT__entry(__string_from_user(path, path) __field_hex(char *, buf) __field(int, bufsiz)), + TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_old_readdir +SC_TRACE_EVENT(sys_old_readdir, + TP_PROTO(unsigned int fd, struct old_linux_dirent * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct old_linux_dirent *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_syslog +SC_TRACE_EVENT(sys_syslog, + TP_PROTO(int type, char * buf, int len), + TP_ARGS(type, buf, len), + TP_STRUCT__entry(__field(int, type) __field_hex(char *, buf) __field(int, len)), + TP_fast_assign(tp_assign(type, type) tp_assign(buf, buf) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setitimer +SC_TRACE_EVENT(sys_setitimer, + TP_PROTO(int which, struct itimerval * value, struct itimerval * ovalue), + TP_ARGS(which, value, ovalue), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value) __field_hex(struct itimerval *, ovalue)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value) tp_assign(ovalue, ovalue)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sigprocmask +SC_TRACE_EVENT(sys_sigprocmask, + TP_PROTO(int how, old_sigset_t * nset, old_sigset_t * oset), + TP_ARGS(how, nset, oset), + TP_STRUCT__entry(__field(int, how) __field_hex(old_sigset_t *, nset) __field_hex(old_sigset_t *, oset)), + TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_init_module +SC_TRACE_EVENT(sys_init_module, + TP_PROTO(void * umod, unsigned long len, const char * uargs), + TP_ARGS(umod, len, uargs), + TP_STRUCT__entry(__field_hex(void *, umod) __field(unsigned long, len) __field_hex(const char *, uargs)), + TP_fast_assign(tp_assign(umod, umod) tp_assign(len, len) tp_assign(uargs, uargs)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getdents +SC_TRACE_EVENT(sys_getdents, + TP_PROTO(unsigned int fd, struct linux_dirent * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_readv +SC_TRACE_EVENT(sys_readv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_writev +SC_TRACE_EVENT(sys_writev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_setscheduler +SC_TRACE_EVENT(sys_sched_setscheduler, + TP_PROTO(pid_t pid, int policy, struct sched_param * param), + TP_ARGS(pid, policy, param), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, policy) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(policy, policy) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getresuid16 +SC_TRACE_EVENT(sys_getresuid16, + TP_PROTO(old_uid_t * ruid, old_uid_t * euid, old_uid_t * suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field_hex(old_uid_t *, ruid) __field_hex(old_uid_t *, euid) __field_hex(old_uid_t *, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_poll +SC_TRACE_EVENT(sys_poll, + TP_PROTO(struct pollfd * ufds, unsigned int nfds, long timeout_msecs), + TP_ARGS(ufds, nfds, timeout_msecs), + TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field(long, timeout_msecs)), + TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(timeout_msecs, timeout_msecs)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getresgid16 +SC_TRACE_EVENT(sys_getresgid16, + TP_PROTO(old_gid_t * rgid, old_gid_t * egid, old_gid_t * sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field_hex(old_gid_t *, rgid) __field_hex(old_gid_t *, egid) __field_hex(old_gid_t *, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigqueueinfo +SC_TRACE_EVENT(sys_rt_sigqueueinfo, + TP_PROTO(pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_chown16 +SC_TRACE_EVENT(sys_chown16, + TP_PROTO(const char * filename, old_uid_t user, old_gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(old_uid_t, user) __field(old_gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lchown +SC_TRACE_EVENT(sys_lchown, + TP_PROTO(const char * filename, uid_t user, gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getresuid +SC_TRACE_EVENT(sys_getresuid, + TP_PROTO(uid_t * ruid, uid_t * euid, uid_t * suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field_hex(uid_t *, ruid) __field_hex(uid_t *, euid) __field_hex(uid_t *, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getresgid +SC_TRACE_EVENT(sys_getresgid, + TP_PROTO(gid_t * rgid, gid_t * egid, gid_t * sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field_hex(gid_t *, rgid) __field_hex(gid_t *, egid) __field_hex(gid_t *, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_chown +SC_TRACE_EVENT(sys_chown, + TP_PROTO(const char * filename, uid_t user, gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mincore +SC_TRACE_EVENT(sys_mincore, + TP_PROTO(unsigned long start, size_t len, unsigned char * vec), + TP_ARGS(start, len, vec), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field_hex(unsigned char *, vec)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(vec, vec)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getdents64 +SC_TRACE_EVENT(sys_getdents64, + TP_PROTO(unsigned int fd, struct linux_dirent64 * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent64 *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_listxattr +SC_TRACE_EVENT(sys_listxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_llistxattr +SC_TRACE_EVENT(sys_llistxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_flistxattr +SC_TRACE_EVENT(sys_flistxattr, + TP_PROTO(int fd, char * list, size_t size), + TP_ARGS(fd, list, size), + TP_STRUCT__entry(__field(int, fd) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_setaffinity +SC_TRACE_EVENT(sys_sched_setaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sched_getaffinity +SC_TRACE_EVENT(sys_sched_getaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_io_submit +SC_TRACE_EVENT(sys_io_submit, + TP_PROTO(aio_context_t ctx_id, long nr, struct iocb * * iocbpp), + TP_ARGS(ctx_id, nr, iocbpp), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, nr) __field_hex(struct iocb * *, iocbpp)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(nr, nr) tp_assign(iocbpp, iocbpp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_io_cancel +SC_TRACE_EVENT(sys_io_cancel, + TP_PROTO(aio_context_t ctx_id, struct iocb * iocb, struct io_event * result), + TP_ARGS(ctx_id, iocb, result), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field_hex(struct iocb *, iocb) __field_hex(struct io_event *, result)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(iocb, iocb) tp_assign(result, result)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timer_create +SC_TRACE_EVENT(sys_timer_create, + TP_PROTO(const clockid_t which_clock, struct sigevent * timer_event_spec, timer_t * created_timer_id), + TP_ARGS(which_clock, timer_event_spec, created_timer_id), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct sigevent *, timer_event_spec) __field_hex(timer_t *, created_timer_id)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(timer_event_spec, timer_event_spec) tp_assign(created_timer_id, created_timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_statfs64 +SC_TRACE_EVENT(sys_statfs64, + TP_PROTO(const char * pathname, size_t sz, struct statfs64 * buf), + TP_ARGS(pathname, sz, buf), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(size_t, sz) __field_hex(struct statfs64 *, buf)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(sz, sz) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fstatfs64 +SC_TRACE_EVENT(sys_fstatfs64, + TP_PROTO(unsigned int fd, size_t sz, struct statfs64 * buf), + TP_ARGS(fd, sz, buf), + TP_STRUCT__entry(__field(unsigned int, fd) __field(size_t, sz) __field_hex(struct statfs64 *, buf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(sz, sz) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_getsetattr +SC_TRACE_EVENT(sys_mq_getsetattr, + TP_PROTO(mqd_t mqdes, const struct mq_attr * u_mqstat, struct mq_attr * u_omqstat), + TP_ARGS(mqdes, u_mqstat, u_omqstat), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct mq_attr *, u_mqstat) __field_hex(struct mq_attr *, u_omqstat)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_mqstat, u_mqstat) tp_assign(u_omqstat, u_omqstat)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_inotify_add_watch +SC_TRACE_EVENT(sys_inotify_add_watch, + TP_PROTO(int fd, const char * pathname, u32 mask), + TP_ARGS(fd, pathname, mask), + TP_STRUCT__entry(__field(int, fd) __string_from_user(pathname, pathname) __field(u32, mask)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(pathname, pathname) tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mkdirat +SC_TRACE_EVENT(sys_mkdirat, + TP_PROTO(int dfd, const char * pathname, int mode), + TP_ARGS(dfd, pathname, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_futimesat +SC_TRACE_EVENT(sys_futimesat, + TP_PROTO(int dfd, const char * filename, struct timeval * utimes), + TP_ARGS(dfd, filename, utimes), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timeval *, utimes)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_unlinkat +SC_TRACE_EVENT(sys_unlinkat, + TP_PROTO(int dfd, const char * pathname, int flag), + TP_ARGS(dfd, pathname, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_symlinkat +SC_TRACE_EVENT(sys_symlinkat, + TP_PROTO(const char * oldname, int newdfd, const char * newname), + TP_ARGS(oldname, newdfd, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchmodat +SC_TRACE_EVENT(sys_fchmodat, + TP_PROTO(int dfd, const char * filename, mode_t mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(mode_t, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_faccessat +SC_TRACE_EVENT(sys_faccessat, + TP_PROTO(int dfd, const char * filename, int mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_get_robust_list +SC_TRACE_EVENT(sys_get_robust_list, + TP_PROTO(int pid, struct robust_list_head * * head_ptr, size_t * len_ptr), + TP_ARGS(pid, head_ptr, len_ptr), + TP_STRUCT__entry(__field(int, pid) __field_hex(struct robust_list_head * *, head_ptr) __field_hex(size_t *, len_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(head_ptr, head_ptr) tp_assign(len_ptr, len_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getcpu +SC_TRACE_EVENT(sys_getcpu, + TP_PROTO(unsigned * cpup, unsigned * nodep, struct getcpu_cache * unused), + TP_ARGS(cpup, nodep, unused), + TP_STRUCT__entry(__field_hex(unsigned *, cpup) __field_hex(unsigned *, nodep) __field_hex(struct getcpu_cache *, unused)), + TP_fast_assign(tp_assign(cpup, cpup) tp_assign(nodep, nodep) tp_assign(unused, unused)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_signalfd +SC_TRACE_EVENT(sys_signalfd, + TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask), + TP_ARGS(ufd, user_mask, sizemask), + TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_reboot +SC_TRACE_EVENT(sys_reboot, + TP_PROTO(int magic1, int magic2, unsigned int cmd, void * arg), + TP_ARGS(magic1, magic2, cmd, arg), + TP_STRUCT__entry(__field(int, magic1) __field(int, magic2) __field(unsigned int, cmd) __field_hex(void *, arg)), + TP_fast_assign(tp_assign(magic1, magic1) tp_assign(magic2, magic2) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_wait4 +SC_TRACE_EVENT(sys_wait4, + TP_PROTO(pid_t upid, int * stat_addr, int options, struct rusage * ru), + TP_ARGS(upid, stat_addr, options, ru), + TP_STRUCT__entry(__field(pid_t, upid) __field_hex(int *, stat_addr) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(upid, upid) tp_assign(stat_addr, stat_addr) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_quotactl +SC_TRACE_EVENT(sys_quotactl, + TP_PROTO(unsigned int cmd, const char * special, qid_t id, void * addr), + TP_ARGS(cmd, special, id, addr), + TP_STRUCT__entry(__field(unsigned int, cmd) __field_hex(const char *, special) __field(qid_t, id) __field_hex(void *, addr)), + TP_fast_assign(tp_assign(cmd, cmd) tp_assign(special, special) tp_assign(id, id) tp_assign(addr, addr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigaction +SC_TRACE_EVENT(sys_rt_sigaction, + TP_PROTO(int sig, const struct sigaction * act, struct sigaction * oact, size_t sigsetsize), + TP_ARGS(sig, act, oact, sigsetsize), + TP_STRUCT__entry(__field(int, sig) __field_hex(const struct sigaction *, act) __field_hex(struct sigaction *, oact) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(sig, sig) tp_assign(act, act) tp_assign(oact, oact) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigprocmask +SC_TRACE_EVENT(sys_rt_sigprocmask, + TP_PROTO(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize), + TP_ARGS(how, nset, oset, sigsetsize), + TP_STRUCT__entry(__field(int, how) __field_hex(sigset_t *, nset) __field_hex(sigset_t *, oset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_sigtimedwait +SC_TRACE_EVENT(sys_rt_sigtimedwait, + TP_PROTO(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec * uts, size_t sigsetsize), + TP_ARGS(uthese, uinfo, uts, sigsetsize), + TP_STRUCT__entry(__field_hex(const sigset_t *, uthese) __field_hex(siginfo_t *, uinfo) __field_hex(const struct timespec *, uts) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(uthese, uthese) tp_assign(uinfo, uinfo) tp_assign(uts, uts) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sendfile +SC_TRACE_EVENT(sys_sendfile, + TP_PROTO(int out_fd, int in_fd, off_t * offset, size_t count), + TP_ARGS(out_fd, in_fd, offset, count), + TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(off_t *, offset) __field(size_t, count)), + TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_getxattr +SC_TRACE_EVENT(sys_getxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lgetxattr +SC_TRACE_EVENT(sys_lgetxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fgetxattr +SC_TRACE_EVENT(sys_fgetxattr, + TP_PROTO(int fd, const char * name, void * value, size_t size), + TP_ARGS(fd, name, value, size), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sendfile64 +SC_TRACE_EVENT(sys_sendfile64, + TP_PROTO(int out_fd, int in_fd, loff_t * offset, size_t count), + TP_ARGS(out_fd, in_fd, offset, count), + TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(loff_t *, offset) __field(size_t, count)), + TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_epoll_ctl +SC_TRACE_EVENT(sys_epoll_ctl, + TP_PROTO(int epfd, int op, int fd, struct epoll_event * event), + TP_ARGS(epfd, op, fd, event), + TP_STRUCT__entry(__field(int, epfd) __field(int, op) __field(int, fd) __field_hex(struct epoll_event *, event)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(op, op) tp_assign(fd, fd) tp_assign(event, event)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_epoll_wait +SC_TRACE_EVENT(sys_epoll_wait, + TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout), + TP_ARGS(epfd, events, maxevents, timeout), + TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timer_settime +SC_TRACE_EVENT(sys_timer_settime, + TP_PROTO(timer_t timer_id, int flags, const struct itimerspec * new_setting, struct itimerspec * old_setting), + TP_ARGS(timer_id, flags, new_setting, old_setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field(int, flags) __field_hex(const struct itimerspec *, new_setting) __field_hex(struct itimerspec *, old_setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(flags, flags) tp_assign(new_setting, new_setting) tp_assign(old_setting, old_setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_clock_nanosleep +SC_TRACE_EVENT(sys_clock_nanosleep, + TP_PROTO(const clockid_t which_clock, int flags, const struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(which_clock, flags, rqtp, rmtp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field(int, flags) __field_hex(const struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(flags, flags) tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_open +SC_TRACE_EVENT(sys_mq_open, + TP_PROTO(const char * u_name, int oflag, mode_t mode, struct mq_attr * u_attr), + TP_ARGS(u_name, oflag, mode, u_attr), + TP_STRUCT__entry(__string_from_user(u_name, u_name) __field(int, oflag) __field(mode_t, mode) __field_hex(struct mq_attr *, u_attr)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name) tp_assign(oflag, oflag) tp_assign(mode, mode) tp_assign(u_attr, u_attr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_kexec_load +SC_TRACE_EVENT(sys_kexec_load, + TP_PROTO(unsigned long entry, unsigned long nr_segments, struct kexec_segment * segments, unsigned long flags), + TP_ARGS(entry, nr_segments, segments, flags), + TP_STRUCT__entry(__field(unsigned long, entry) __field(unsigned long, nr_segments) __field_hex(struct kexec_segment *, segments) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(entry, entry) tp_assign(nr_segments, nr_segments) tp_assign(segments, segments) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_request_key +SC_TRACE_EVENT(sys_request_key, + TP_PROTO(const char * _type, const char * _description, const char * _callout_info, key_serial_t destringid), + TP_ARGS(_type, _description, _callout_info, destringid), + TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const char *, _callout_info) __field(key_serial_t, destringid)), + TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_callout_info, _callout_info) tp_assign(destringid, destringid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_openat +SC_TRACE_EVENT(sys_openat, + TP_PROTO(int dfd, const char * filename, int flags, int mode), + TP_ARGS(dfd, filename, flags, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, flags) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mknodat +SC_TRACE_EVENT(sys_mknodat, + TP_PROTO(int dfd, const char * filename, int mode, unsigned dev), + TP_ARGS(dfd, filename, mode, dev), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fstatat64 +SC_TRACE_EVENT(sys_fstatat64, + TP_PROTO(int dfd, const char * filename, struct stat64 * statbuf, int flag), + TP_ARGS(dfd, filename, statbuf, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct stat64 *, statbuf) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_renameat +SC_TRACE_EVENT(sys_renameat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname), + TP_ARGS(olddfd, oldname, newdfd, newname), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_readlinkat +SC_TRACE_EVENT(sys_readlinkat, + TP_PROTO(int dfd, const char * pathname, char * buf, int bufsiz), + TP_ARGS(dfd, pathname, buf, bufsiz), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field_hex(char *, buf) __field(int, bufsiz)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_vmsplice +SC_TRACE_EVENT(sys_vmsplice, + TP_PROTO(int fd, const struct iovec * iov, unsigned long nr_segs, unsigned int flags), + TP_ARGS(fd, iov, nr_segs, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(const struct iovec *, iov) __field(unsigned long, nr_segs) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(iov, iov) tp_assign(nr_segs, nr_segs) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_utimensat +SC_TRACE_EVENT(sys_utimensat, + TP_PROTO(int dfd, const char * filename, struct timespec * utimes, int flags), + TP_ARGS(dfd, filename, utimes, flags), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timespec *, utimes) __field(int, flags)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_timerfd_settime +SC_TRACE_EVENT(sys_timerfd_settime, + TP_PROTO(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr), + TP_ARGS(ufd, flags, utmr, otmr), + TP_STRUCT__entry(__field(int, ufd) __field(int, flags) __field_hex(const struct itimerspec *, utmr) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(flags, flags) tp_assign(utmr, utmr) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_signalfd4 +SC_TRACE_EVENT(sys_signalfd4, + TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask, int flags), + TP_ARGS(ufd, user_mask, sizemask, flags), + TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask) __field(int, flags)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_rt_tgsigqueueinfo +SC_TRACE_EVENT(sys_rt_tgsigqueueinfo, + TP_PROTO(pid_t tgid, pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(tgid, pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_prlimit64 +SC_TRACE_EVENT(sys_prlimit64, + TP_PROTO(pid_t pid, unsigned int resource, const struct rlimit64 * new_rlim, struct rlimit64 * old_rlim), + TP_ARGS(pid, resource, new_rlim, old_rlim), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, resource) __field_hex(const struct rlimit64 *, new_rlim) __field_hex(struct rlimit64 *, old_rlim)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(resource, resource) tp_assign(new_rlim, new_rlim) tp_assign(old_rlim, old_rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_sendmmsg +SC_TRACE_EVENT(sys_sendmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags), + TP_ARGS(fd, mmsg, vlen, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mount +SC_TRACE_EVENT(sys_mount, + TP_PROTO(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data), + TP_ARGS(dev_name, dir_name, type, flags, data), + TP_STRUCT__entry(__string_from_user(dev_name, dev_name) __string_from_user(dir_name, dir_name) __string_from_user(type, type) __field(unsigned long, flags) __field_hex(void *, data)), + TP_fast_assign(tp_copy_string_from_user(dev_name, dev_name) tp_copy_string_from_user(dir_name, dir_name) tp_copy_string_from_user(type, type) tp_assign(flags, flags) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_llseek +SC_TRACE_EVENT(sys_llseek, + TP_PROTO(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int origin), + TP_ARGS(fd, offset_high, offset_low, result, origin), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, offset_high) __field(unsigned long, offset_low) __field_hex(loff_t *, result) __field(unsigned int, origin)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(offset_high, offset_high) tp_assign(offset_low, offset_low) tp_assign(result, result) tp_assign(origin, origin)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_select +SC_TRACE_EVENT(sys_select, + TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timeval * tvp), + TP_ARGS(n, inp, outp, exp, tvp), + TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timeval *, tvp)), + TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tvp, tvp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_setxattr +SC_TRACE_EVENT(sys_setxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_lsetxattr +SC_TRACE_EVENT(sys_lsetxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fsetxattr +SC_TRACE_EVENT(sys_fsetxattr, + TP_PROTO(int fd, const char * name, const void * value, size_t size, int flags), + TP_ARGS(fd, name, value, size, flags), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_io_getevents +SC_TRACE_EVENT(sys_io_getevents, + TP_PROTO(aio_context_t ctx_id, long min_nr, long nr, struct io_event * events, struct timespec * timeout), + TP_ARGS(ctx_id, min_nr, nr, events, timeout), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, min_nr) __field(long, nr) __field_hex(struct io_event *, events) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(min_nr, min_nr) tp_assign(nr, nr) tp_assign(events, events) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_timedsend +SC_TRACE_EVENT(sys_mq_timedsend, + TP_PROTO(mqd_t mqdes, const char * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const char *, u_msg_ptr) __field(size_t, msg_len) __field(unsigned int, msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(msg_prio, msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_mq_timedreceive +SC_TRACE_EVENT(sys_mq_timedreceive, + TP_PROTO(mqd_t mqdes, char * u_msg_ptr, size_t msg_len, unsigned int * u_msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(char *, u_msg_ptr) __field(size_t, msg_len) __field_hex(unsigned int *, u_msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(u_msg_prio, u_msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_waitid +SC_TRACE_EVENT(sys_waitid, + TP_PROTO(int which, pid_t upid, struct siginfo * infop, int options, struct rusage * ru), + TP_ARGS(which, upid, infop, options, ru), + TP_STRUCT__entry(__field(int, which) __field(pid_t, upid) __field_hex(struct siginfo *, infop) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(which, which) tp_assign(upid, upid) tp_assign(infop, infop) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_add_key +SC_TRACE_EVENT(sys_add_key, + TP_PROTO(const char * _type, const char * _description, const void * _payload, size_t plen, key_serial_t ringid), + TP_ARGS(_type, _description, _payload, plen, ringid), + TP_STRUCT__entry(__string_from_user(_type, _type) __field_hex(const char *, _description) __field_hex(const void *, _payload) __field(size_t, plen) __field(key_serial_t, ringid)), + TP_fast_assign(tp_copy_string_from_user(_type, _type) tp_assign(_description, _description) tp_assign(_payload, _payload) tp_assign(plen, plen) tp_assign(ringid, ringid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_fchownat +SC_TRACE_EVENT(sys_fchownat, + TP_PROTO(int dfd, const char * filename, uid_t user, gid_t group, int flag), + TP_ARGS(dfd, filename, user, group, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_linkat +SC_TRACE_EVENT(sys_linkat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname, int flags), + TP_ARGS(olddfd, oldname, newdfd, newname, flags), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname) __field(int, flags)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ppoll +SC_TRACE_EVENT(sys_ppoll, + TP_PROTO(struct pollfd * ufds, unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(ufds, nfds, tsp, sigmask, sigsetsize), + TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field_hex(struct timespec *, tsp) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(tsp, tsp) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_preadv +SC_TRACE_EVENT(sys_preadv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_pwritev +SC_TRACE_EVENT(sys_pwritev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_perf_event_open +SC_TRACE_EVENT(sys_perf_event_open, + TP_PROTO(struct perf_event_attr * attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags), + TP_ARGS(attr_uptr, pid, cpu, group_fd, flags), + TP_STRUCT__entry(__field_hex(struct perf_event_attr *, attr_uptr) __field(pid_t, pid) __field(int, cpu) __field(int, group_fd) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(attr_uptr, attr_uptr) tp_assign(pid, pid) tp_assign(cpu, cpu) tp_assign(group_fd, group_fd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_recvmmsg +SC_TRACE_EVENT(sys_recvmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags, struct timespec * timeout), + TP_ARGS(fd, mmsg, vlen, flags, timeout), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_ipc +SC_TRACE_EVENT(sys_ipc, + TP_PROTO(unsigned int call, int first, unsigned long second, unsigned long third, void * ptr, long fifth), + TP_ARGS(call, first, second, third, ptr, fifth), + TP_STRUCT__entry(__field(unsigned int, call) __field(int, first) __field(unsigned long, second) __field(unsigned long, third) __field_hex(void *, ptr) __field(long, fifth)), + TP_fast_assign(tp_assign(call, call) tp_assign(first, first) tp_assign(second, second) tp_assign(third, third) tp_assign(ptr, ptr) tp_assign(fifth, fifth)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_futex +SC_TRACE_EVENT(sys_futex, + TP_PROTO(u32 * uaddr, int op, u32 val, struct timespec * utime, u32 * uaddr2, u32 val3), + TP_ARGS(uaddr, op, val, utime, uaddr2, val3), + TP_STRUCT__entry(__field_hex(u32 *, uaddr) __field(int, op) __field(u32, val) __field_hex(struct timespec *, utime) __field_hex(u32 *, uaddr2) __field(u32, val3)), + TP_fast_assign(tp_assign(uaddr, uaddr) tp_assign(op, op) tp_assign(val, val) tp_assign(utime, utime) tp_assign(uaddr2, uaddr2) tp_assign(val3, val3)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_pselect6 +SC_TRACE_EVENT(sys_pselect6, + TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timespec * tsp, void * sig), + TP_ARGS(n, inp, outp, exp, tsp, sig), + TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timespec *, tsp) __field_hex(void *, sig)), + TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tsp, tsp) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_splice +SC_TRACE_EVENT(sys_splice, + TP_PROTO(int fd_in, loff_t * off_in, int fd_out, loff_t * off_out, size_t len, unsigned int flags), + TP_ARGS(fd_in, off_in, fd_out, off_out, len, flags), + TP_STRUCT__entry(__field(int, fd_in) __field_hex(loff_t *, off_in) __field(int, fd_out) __field_hex(loff_t *, off_out) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd_in, fd_in) tp_assign(off_in, off_in) tp_assign(fd_out, fd_out) tp_assign(off_out, off_out) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_32_sys_epoll_pwait +SC_TRACE_EVENT(sys_epoll_pwait, + TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(epfd, events, maxevents, timeout, sigmask, sigsetsize), + TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_POINTERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "x86-32-syscalls-3.1.0-rc6_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_TABLE_32_sys_read +TRACE_SYSCALL_TABLE(sys_read, sys_read, 3, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_write +TRACE_SYSCALL_TABLE(sys_write, sys_write, 4, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_open +TRACE_SYSCALL_TABLE(sys_open, sys_open, 5, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_waitpid +TRACE_SYSCALL_TABLE(sys_waitpid, sys_waitpid, 7, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_creat +TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 8, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_link +TRACE_SYSCALL_TABLE(sys_link, sys_link, 9, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_unlink +TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 10, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_chdir +TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 12, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_time +TRACE_SYSCALL_TABLE(sys_time, sys_time, 13, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mknod +TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 14, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_chmod +TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 15, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lchown16 +TRACE_SYSCALL_TABLE(sys_lchown16, sys_lchown16, 16, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_stat +TRACE_SYSCALL_TABLE(sys_stat, sys_stat, 18, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mount +TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 21, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_oldumount +TRACE_SYSCALL_TABLE(sys_oldumount, sys_oldumount, 22, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_stime +TRACE_SYSCALL_TABLE(sys_stime, sys_stime, 25, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fstat +TRACE_SYSCALL_TABLE(sys_fstat, sys_fstat, 28, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_utime +TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 30, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_access +TRACE_SYSCALL_TABLE(sys_access, sys_access, 33, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rename +TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 38, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mkdir +TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 39, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rmdir +TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 40, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pipe +TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 42, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_times +TRACE_SYSCALL_TABLE(sys_times, sys_times, 43, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_acct +TRACE_SYSCALL_TABLE(sys_acct, sys_acct, 51, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_umount +TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 52, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_olduname +TRACE_SYSCALL_TABLE(sys_olduname, sys_olduname, 59, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_chroot +TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 61, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ustat +TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 62, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sigpending +TRACE_SYSCALL_TABLE(sys_sigpending, sys_sigpending, 73, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sethostname +TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 74, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setrlimit +TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 75, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_old_getrlimit +TRACE_SYSCALL_TABLE(sys_old_getrlimit, sys_old_getrlimit, 76, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getrusage +TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 77, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_gettimeofday +TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 78, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_settimeofday +TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 79, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getgroups16 +TRACE_SYSCALL_TABLE(sys_getgroups16, sys_getgroups16, 80, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setgroups16 +TRACE_SYSCALL_TABLE(sys_setgroups16, sys_setgroups16, 81, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_old_select +TRACE_SYSCALL_TABLE(sys_old_select, sys_old_select, 82, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_symlink +TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 83, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lstat +TRACE_SYSCALL_TABLE(sys_lstat, sys_lstat, 84, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_readlink +TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 85, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_uselib +TRACE_SYSCALL_TABLE(sys_uselib, sys_uselib, 86, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_swapon +TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 87, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_reboot +TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 88, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_old_readdir +TRACE_SYSCALL_TABLE(sys_old_readdir, sys_old_readdir, 89, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_old_mmap +TRACE_SYSCALL_TABLE(sys_old_mmap, sys_old_mmap, 90, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_truncate +TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 92, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_statfs +TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 99, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fstatfs +TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 100, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_socketcall +TRACE_SYSCALL_TABLE(sys_socketcall, sys_socketcall, 102, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_syslog +TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setitimer +TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 104, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getitimer +TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 105, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_newstat +TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 106, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_newlstat +TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 107, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_newfstat +TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 108, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_uname +TRACE_SYSCALL_TABLE(sys_uname, sys_uname, 109, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_wait4 +TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 114, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_swapoff +TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 115, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sysinfo +TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 116, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ipc +TRACE_SYSCALL_TABLE(sys_ipc, sys_ipc, 117, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setdomainname +TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 121, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_newuname +TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 122, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_adjtimex +TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 124, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sigprocmask +TRACE_SYSCALL_TABLE(sys_sigprocmask, sys_sigprocmask, 126, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_init_module +TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 128, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_delete_module +TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 129, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_quotactl +TRACE_SYSCALL_TABLE(sys_quotactl, sys_quotactl, 131, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_llseek +TRACE_SYSCALL_TABLE(sys_llseek, sys_llseek, 140, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getdents +TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 141, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_select +TRACE_SYSCALL_TABLE(sys_select, sys_select, 142, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_readv +TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 145, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_writev +TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 146, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sysctl +TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 149, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_setparam +TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 154, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_getparam +TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 155, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_setscheduler +TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 156, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_rr_get_interval +TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 161, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_nanosleep +TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 162, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getresuid16 +TRACE_SYSCALL_TABLE(sys_getresuid16, sys_getresuid16, 165, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_poll +TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 168, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getresgid16 +TRACE_SYSCALL_TABLE(sys_getresgid16, sys_getresgid16, 171, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigaction +TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 174, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigprocmask +TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 175, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigpending +TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 176, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigtimedwait +TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 177, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 178, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_sigsuspend +TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 179, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_chown16 +TRACE_SYSCALL_TABLE(sys_chown16, sys_chown16, 182, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getcwd +TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 183, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sendfile +TRACE_SYSCALL_TABLE(sys_sendfile, sys_sendfile, 187, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getrlimit +TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 191, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_stat64 +TRACE_SYSCALL_TABLE(sys_stat64, sys_stat64, 195, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lstat64 +TRACE_SYSCALL_TABLE(sys_lstat64, sys_lstat64, 196, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fstat64 +TRACE_SYSCALL_TABLE(sys_fstat64, sys_fstat64, 197, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lchown +TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 198, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getgroups +TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 205, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setgroups +TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 206, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getresuid +TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 209, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getresgid +TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 211, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_chown +TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 212, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pivot_root +TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 217, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mincore +TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 218, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getdents64 +TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 220, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_setxattr +TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 226, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lsetxattr +TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 227, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fsetxattr +TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 228, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getxattr +TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 229, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lgetxattr +TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 230, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fgetxattr +TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 231, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_listxattr +TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 232, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_llistxattr +TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 233, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_flistxattr +TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 234, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_removexattr +TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 235, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_lremovexattr +TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 236, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fremovexattr +TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 237, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sendfile64 +TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 239, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_futex +TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 240, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_setaffinity +TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 241, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sched_getaffinity +TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 242, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_io_setup +TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 245, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_io_getevents +TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 247, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_io_submit +TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 248, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_io_cancel +TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 249, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_epoll_ctl +TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 255, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_epoll_wait +TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 256, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_set_tid_address +TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 258, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timer_create +TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 259, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timer_settime +TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 260, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timer_gettime +TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 261, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_clock_settime +TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 264, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_clock_gettime +TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 265, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_clock_getres +TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 266, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_clock_nanosleep +TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 267, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_statfs64 +TRACE_SYSCALL_TABLE(sys_statfs64, sys_statfs64, 268, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fstatfs64 +TRACE_SYSCALL_TABLE(sys_fstatfs64, sys_fstatfs64, 269, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_utimes +TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 271, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_open +TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 277, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_unlink +TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 278, 1) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_timedsend +TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 279, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_timedreceive +TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 280, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_notify +TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 281, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mq_getsetattr +TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 282, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_kexec_load +TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 283, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_waitid +TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 284, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_add_key +TRACE_SYSCALL_TABLE(sys_add_key, sys_add_key, 286, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_request_key +TRACE_SYSCALL_TABLE(sys_request_key, sys_request_key, 287, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_inotify_add_watch +TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 292, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_openat +TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 295, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mkdirat +TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 296, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_mknodat +TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 297, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchownat +TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 298, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_futimesat +TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 299, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fstatat64 +TRACE_SYSCALL_TABLE(sys_fstatat64, sys_fstatat64, 300, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_unlinkat +TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 301, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_renameat +TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 302, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_linkat +TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 303, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_symlinkat +TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 304, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_readlinkat +TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 305, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_fchmodat +TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 306, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_faccessat +TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 307, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pselect6 +TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 308, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_ppoll +TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 309, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_set_robust_list +TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 311, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_get_robust_list +TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 312, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_splice +TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 313, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_vmsplice +TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 316, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_getcpu +TRACE_SYSCALL_TABLE(sys_getcpu, sys_getcpu, 318, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_epoll_pwait +TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 319, 6) +#endif +#ifndef OVERRIDE_TABLE_32_sys_utimensat +TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 320, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_signalfd +TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 321, 3) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timerfd_settime +TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 325, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_timerfd_gettime +TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 326, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_signalfd4 +TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 327, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pipe2 +TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 331, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_preadv +TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 333, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_pwritev +TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 334, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_rt_tgsigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 335, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_perf_event_open +TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 336, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_recvmmsg +TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 337, 5) +#endif +#ifndef OVERRIDE_TABLE_32_sys_prlimit64 +TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 340, 4) +#endif +#ifndef OVERRIDE_TABLE_32_sys_clock_adjtime +TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 343, 2) +#endif +#ifndef OVERRIDE_TABLE_32_sys_sendmmsg +TRACE_SYSCALL_TABLE(sys_sendmmsg, sys_sendmmsg, 345, 4) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h new file mode 100644 index 0000000..d35657c --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-32-syscalls-3.1.0-rc6_pointers_override.h @@ -0,0 +1,17 @@ +#ifndef CONFIG_UID16 + +#define OVERRIDE_32_sys_getgroups16 +#define OVERRIDE_32_sys_setgroups16 +#define OVERRIDE_32_sys_lchown16 +#define OVERRIDE_32_sys_getresuid16 +#define OVERRIDE_32_sys_getresgid16 +#define OVERRIDE_32_sys_chown16 + +#define OVERRIDE_TABLE_32_sys_getgroups16 +#define OVERRIDE_TABLE_32_sys_setgroups16 +#define OVERRIDE_TABLE_32_sys_lchown16 +#define OVERRIDE_TABLE_32_sys_getresuid16 +#define OVERRIDE_TABLE_32_sys_getresgid16 +#define OVERRIDE_TABLE_32_sys_chown16 + +#endif diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h new file mode 100644 index 0000000..6d0dbb9 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers.h @@ -0,0 +1,1013 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_INTEGERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_INTEGERS_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> +#include "x86-64-syscalls-3.0.4_integers_override.h" +#include "syscalls_integers_override.h" + +SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs, + TP_STRUCT__entry(), + TP_fast_assign(), + TP_printk() +) +#ifndef OVERRIDE_64_sys_sched_yield +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sched_yield) +#endif +#ifndef OVERRIDE_64_sys_pause +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_pause) +#endif +#ifndef OVERRIDE_64_sys_getpid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpid) +#endif +#ifndef OVERRIDE_64_sys_getuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getuid) +#endif +#ifndef OVERRIDE_64_sys_getgid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getgid) +#endif +#ifndef OVERRIDE_64_sys_geteuid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_geteuid) +#endif +#ifndef OVERRIDE_64_sys_getegid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getegid) +#endif +#ifndef OVERRIDE_64_sys_getppid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getppid) +#endif +#ifndef OVERRIDE_64_sys_getpgrp +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_getpgrp) +#endif +#ifndef OVERRIDE_64_sys_setsid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_setsid) +#endif +#ifndef OVERRIDE_64_sys_munlockall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_munlockall) +#endif +#ifndef OVERRIDE_64_sys_vhangup +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_vhangup) +#endif +#ifndef OVERRIDE_64_sys_sync +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_sync) +#endif +#ifndef OVERRIDE_64_sys_gettid +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_gettid) +#endif +#ifndef OVERRIDE_64_sys_restart_syscall +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_restart_syscall) +#endif +#ifndef OVERRIDE_64_sys_inotify_init +SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_inotify_init) +#endif +#ifndef OVERRIDE_64_sys_close +SC_TRACE_EVENT(sys_close, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_brk +SC_TRACE_EVENT(sys_brk, + TP_PROTO(unsigned long brk), + TP_ARGS(brk), + TP_STRUCT__entry(__field(unsigned long, brk)), + TP_fast_assign(tp_assign(brk, brk)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_dup +SC_TRACE_EVENT(sys_dup, + TP_PROTO(unsigned int fildes), + TP_ARGS(fildes), + TP_STRUCT__entry(__field(unsigned int, fildes)), + TP_fast_assign(tp_assign(fildes, fildes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_alarm +SC_TRACE_EVENT(sys_alarm, + TP_PROTO(unsigned int seconds), + TP_ARGS(seconds), + TP_STRUCT__entry(__field(unsigned int, seconds)), + TP_fast_assign(tp_assign(seconds, seconds)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_exit +SC_TRACE_EVENT(sys_exit, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fsync +SC_TRACE_EVENT(sys_fsync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fdatasync +SC_TRACE_EVENT(sys_fdatasync, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchdir +SC_TRACE_EVENT(sys_fchdir, + TP_PROTO(unsigned int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(unsigned int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_umask +SC_TRACE_EVENT(sys_umask, + TP_PROTO(int mask), + TP_ARGS(mask), + TP_STRUCT__entry(__field(int, mask)), + TP_fast_assign(tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setuid +SC_TRACE_EVENT(sys_setuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setgid +SC_TRACE_EVENT(sys_setgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpgid +SC_TRACE_EVENT(sys_getpgid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setfsuid +SC_TRACE_EVENT(sys_setfsuid, + TP_PROTO(uid_t uid), + TP_ARGS(uid), + TP_STRUCT__entry(__field(uid_t, uid)), + TP_fast_assign(tp_assign(uid, uid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setfsgid +SC_TRACE_EVENT(sys_setfsgid, + TP_PROTO(gid_t gid), + TP_ARGS(gid), + TP_STRUCT__entry(__field(gid_t, gid)), + TP_fast_assign(tp_assign(gid, gid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsid +SC_TRACE_EVENT(sys_getsid, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_personality +SC_TRACE_EVENT(sys_personality, + TP_PROTO(unsigned int personality), + TP_ARGS(personality), + TP_STRUCT__entry(__field(unsigned int, personality)), + TP_fast_assign(tp_assign(personality, personality)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getscheduler +SC_TRACE_EVENT(sys_sched_getscheduler, + TP_PROTO(pid_t pid), + TP_ARGS(pid), + TP_STRUCT__entry(__field(pid_t, pid)), + TP_fast_assign(tp_assign(pid, pid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_get_priority_max +SC_TRACE_EVENT(sys_sched_get_priority_max, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_get_priority_min +SC_TRACE_EVENT(sys_sched_get_priority_min, + TP_PROTO(int policy), + TP_ARGS(policy), + TP_STRUCT__entry(__field(int, policy)), + TP_fast_assign(tp_assign(policy, policy)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mlockall +SC_TRACE_EVENT(sys_mlockall, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_destroy +SC_TRACE_EVENT(sys_io_destroy, + TP_PROTO(aio_context_t ctx), + TP_ARGS(ctx), + TP_STRUCT__entry(__field(aio_context_t, ctx)), + TP_fast_assign(tp_assign(ctx, ctx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_create +SC_TRACE_EVENT(sys_epoll_create, + TP_PROTO(int size), + TP_ARGS(size), + TP_STRUCT__entry(__field(int, size)), + TP_fast_assign(tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_getoverrun +SC_TRACE_EVENT(sys_timer_getoverrun, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_delete +SC_TRACE_EVENT(sys_timer_delete, + TP_PROTO(timer_t timer_id), + TP_ARGS(timer_id), + TP_STRUCT__entry(__field(timer_t, timer_id)), + TP_fast_assign(tp_assign(timer_id, timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_exit_group +SC_TRACE_EVENT(sys_exit_group, + TP_PROTO(int error_code), + TP_ARGS(error_code), + TP_STRUCT__entry(__field(int, error_code)), + TP_fast_assign(tp_assign(error_code, error_code)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_unshare +SC_TRACE_EVENT(sys_unshare, + TP_PROTO(unsigned long unshare_flags), + TP_ARGS(unshare_flags), + TP_STRUCT__entry(__field(unsigned long, unshare_flags)), + TP_fast_assign(tp_assign(unshare_flags, unshare_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_eventfd +SC_TRACE_EVENT(sys_eventfd, + TP_PROTO(unsigned int count), + TP_ARGS(count), + TP_STRUCT__entry(__field(unsigned int, count)), + TP_fast_assign(tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_create1 +SC_TRACE_EVENT(sys_epoll_create1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_init1 +SC_TRACE_EVENT(sys_inotify_init1, + TP_PROTO(int flags), + TP_ARGS(flags), + TP_STRUCT__entry(__field(int, flags)), + TP_fast_assign(tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_syncfs +SC_TRACE_EVENT(sys_syncfs, + TP_PROTO(int fd), + TP_ARGS(fd), + TP_STRUCT__entry(__field(int, fd)), + TP_fast_assign(tp_assign(fd, fd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_munmap +SC_TRACE_EVENT(sys_munmap, + TP_PROTO(unsigned long addr, size_t len), + TP_ARGS(addr, len), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(size_t, len)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_dup2 +SC_TRACE_EVENT(sys_dup2, + TP_PROTO(unsigned int oldfd, unsigned int newfd), + TP_ARGS(oldfd, newfd), + TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd)), + TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shutdown +SC_TRACE_EVENT(sys_shutdown, + TP_PROTO(int fd, int how), + TP_ARGS(fd, how), + TP_STRUCT__entry(__field(int, fd) __field(int, how)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(how, how)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_listen +SC_TRACE_EVENT(sys_listen, + TP_PROTO(int fd, int backlog), + TP_ARGS(fd, backlog), + TP_STRUCT__entry(__field(int, fd) __field(int, backlog)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(backlog, backlog)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_kill +SC_TRACE_EVENT(sys_kill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgget +SC_TRACE_EVENT(sys_msgget, + TP_PROTO(key_t key, int msgflg), + TP_ARGS(key, msgflg), + TP_STRUCT__entry(__field(key_t, key) __field(int, msgflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_flock +SC_TRACE_EVENT(sys_flock, + TP_PROTO(unsigned int fd, unsigned int cmd), + TP_ARGS(fd, cmd), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ftruncate +SC_TRACE_EVENT(sys_ftruncate, + TP_PROTO(unsigned int fd, unsigned long length), + TP_ARGS(fd, length), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned long, length)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchmod +SC_TRACE_EVENT(sys_fchmod, + TP_PROTO(unsigned int fd, mode_t mode), + TP_ARGS(fd, mode), + TP_STRUCT__entry(__field(unsigned int, fd) __field(mode_t, mode)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setpgid +SC_TRACE_EVENT(sys_setpgid, + TP_PROTO(pid_t pid, pid_t pgid), + TP_ARGS(pid, pgid), + TP_STRUCT__entry(__field(pid_t, pid) __field(pid_t, pgid)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(pgid, pgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setreuid +SC_TRACE_EVENT(sys_setreuid, + TP_PROTO(uid_t ruid, uid_t euid), + TP_ARGS(ruid, euid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setregid +SC_TRACE_EVENT(sys_setregid, + TP_PROTO(gid_t rgid, gid_t egid), + TP_ARGS(rgid, egid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpriority +SC_TRACE_EVENT(sys_getpriority, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mlock +SC_TRACE_EVENT(sys_mlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_munlock +SC_TRACE_EVENT(sys_munlock, + TP_PROTO(unsigned long start, size_t len), + TP_ARGS(start, len), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tkill +SC_TRACE_EVENT(sys_tkill, + TP_PROTO(pid_t pid, int sig), + TP_ARGS(pid, sig), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioprio_get +SC_TRACE_EVENT(sys_ioprio_get, + TP_PROTO(int which, int who), + TP_ARGS(which, who), + TP_STRUCT__entry(__field(int, which) __field(int, who)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_rm_watch +SC_TRACE_EVENT(sys_inotify_rm_watch, + TP_PROTO(int fd, __s32 wd), + TP_ARGS(fd, wd), + TP_STRUCT__entry(__field(int, fd) __field(__s32, wd)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(wd, wd)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_create +SC_TRACE_EVENT(sys_timerfd_create, + TP_PROTO(int clockid, int flags), + TP_ARGS(clockid, flags), + TP_STRUCT__entry(__field(int, clockid) __field(int, flags)), + TP_fast_assign(tp_assign(clockid, clockid) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_eventfd2 +SC_TRACE_EVENT(sys_eventfd2, + TP_PROTO(unsigned int count, int flags), + TP_ARGS(count, flags), + TP_STRUCT__entry(__field(unsigned int, count) __field(int, flags)), + TP_fast_assign(tp_assign(count, count) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setns +SC_TRACE_EVENT(sys_setns, + TP_PROTO(int fd, int nstype), + TP_ARGS(fd, nstype), + TP_STRUCT__entry(__field(int, fd) __field(int, nstype)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(nstype, nstype)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lseek +SC_TRACE_EVENT(sys_lseek, + TP_PROTO(unsigned int fd, off_t offset, unsigned int origin), + TP_ARGS(fd, offset, origin), + TP_STRUCT__entry(__field(unsigned int, fd) __field(off_t, offset) __field(unsigned int, origin)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(offset, offset) tp_assign(origin, origin)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mprotect +SC_TRACE_EVENT(sys_mprotect, + TP_PROTO(unsigned long start, size_t len, unsigned long prot), + TP_ARGS(start, len, prot), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(unsigned long, prot)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(prot, prot)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioctl +SC_TRACE_EVENT(sys_ioctl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msync +SC_TRACE_EVENT(sys_msync, + TP_PROTO(unsigned long start, size_t len, int flags), + TP_ARGS(start, len, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field(int, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_madvise +SC_TRACE_EVENT(sys_madvise, + TP_PROTO(unsigned long start, size_t len_in, int behavior), + TP_ARGS(start, len_in, behavior), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len_in) __field(int, behavior)), + TP_fast_assign(tp_assign(start, start) tp_assign(len_in, len_in) tp_assign(behavior, behavior)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmget +SC_TRACE_EVENT(sys_shmget, + TP_PROTO(key_t key, size_t size, int shmflg), + TP_ARGS(key, size, shmflg), + TP_STRUCT__entry(__field(key_t, key) __field(size_t, size) __field(int, shmflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(size, size) tp_assign(shmflg, shmflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_socket +SC_TRACE_EVENT(sys_socket, + TP_PROTO(int family, int type, int protocol), + TP_ARGS(family, type, protocol), + TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol)), + TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semget +SC_TRACE_EVENT(sys_semget, + TP_PROTO(key_t key, int nsems, int semflg), + TP_ARGS(key, nsems, semflg), + TP_STRUCT__entry(__field(key_t, key) __field(int, nsems) __field(int, semflg)), + TP_fast_assign(tp_assign(key, key) tp_assign(nsems, nsems) tp_assign(semflg, semflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fcntl +SC_TRACE_EVENT(sys_fcntl, + TP_PROTO(unsigned int fd, unsigned int cmd, unsigned long arg), + TP_ARGS(fd, cmd, arg), + TP_STRUCT__entry(__field(unsigned int, fd) __field(unsigned int, cmd) __field(unsigned long, arg)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchown +SC_TRACE_EVENT(sys_fchown, + TP_PROTO(unsigned int fd, uid_t user, gid_t group), + TP_ARGS(fd, user, group), + TP_STRUCT__entry(__field(unsigned int, fd) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setresuid +SC_TRACE_EVENT(sys_setresuid, + TP_PROTO(uid_t ruid, uid_t euid, uid_t suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field(uid_t, ruid) __field(uid_t, euid) __field(uid_t, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setresgid +SC_TRACE_EVENT(sys_setresgid, + TP_PROTO(gid_t rgid, gid_t egid, gid_t sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field(gid_t, rgid) __field(gid_t, egid) __field(gid_t, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sysfs +SC_TRACE_EVENT(sys_sysfs, + TP_PROTO(int option, unsigned long arg1, unsigned long arg2), + TP_ARGS(option, arg1, arg2), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg1) __field(unsigned long, arg2)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg1, arg1) tp_assign(arg2, arg2)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setpriority +SC_TRACE_EVENT(sys_setpriority, + TP_PROTO(int which, int who, int niceval), + TP_ARGS(which, who, niceval), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, niceval)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(niceval, niceval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tgkill +SC_TRACE_EVENT(sys_tgkill, + TP_PROTO(pid_t tgid, pid_t pid, int sig), + TP_ARGS(tgid, pid, sig), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ioprio_set +SC_TRACE_EVENT(sys_ioprio_set, + TP_PROTO(int which, int who, int ioprio), + TP_ARGS(which, who, ioprio), + TP_STRUCT__entry(__field(int, which) __field(int, who) __field(int, ioprio)), + TP_fast_assign(tp_assign(which, which) tp_assign(who, who) tp_assign(ioprio, ioprio)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_dup3 +SC_TRACE_EVENT(sys_dup3, + TP_PROTO(unsigned int oldfd, unsigned int newfd, int flags), + TP_ARGS(oldfd, newfd, flags), + TP_STRUCT__entry(__field(unsigned int, oldfd) __field(unsigned int, newfd) __field(int, flags)), + TP_fast_assign(tp_assign(oldfd, oldfd) tp_assign(newfd, newfd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ptrace +SC_TRACE_EVENT(sys_ptrace, + TP_PROTO(long request, long pid, unsigned long addr, unsigned long data), + TP_ARGS(request, pid, addr, data), + TP_STRUCT__entry(__field(long, request) __field(long, pid) __field_hex(unsigned long, addr) __field(unsigned long, data)), + TP_fast_assign(tp_assign(request, request) tp_assign(pid, pid) tp_assign(addr, addr) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_tee +SC_TRACE_EVENT(sys_tee, + TP_PROTO(int fdin, int fdout, size_t len, unsigned int flags), + TP_ARGS(fdin, fdout, len, flags), + TP_STRUCT__entry(__field(int, fdin) __field(int, fdout) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fdin, fdin) tp_assign(fdout, fdout) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mremap +SC_TRACE_EVENT(sys_mremap, + TP_PROTO(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr), + TP_ARGS(addr, old_len, new_len, flags, new_addr), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, old_len) __field(unsigned long, new_len) __field(unsigned long, flags) __field_hex(unsigned long, new_addr)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(old_len, old_len) tp_assign(new_len, new_len) tp_assign(flags, flags) tp_assign(new_addr, new_addr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_prctl +SC_TRACE_EVENT(sys_prctl, + TP_PROTO(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5), + TP_ARGS(option, arg2, arg3, arg4, arg5), + TP_STRUCT__entry(__field(int, option) __field(unsigned long, arg2) __field(unsigned long, arg3) __field(unsigned long, arg4) __field(unsigned long, arg5)), + TP_fast_assign(tp_assign(option, option) tp_assign(arg2, arg2) tp_assign(arg3, arg3) tp_assign(arg4, arg4) tp_assign(arg5, arg5)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_remap_file_pages +SC_TRACE_EVENT(sys_remap_file_pages, + TP_PROTO(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags), + TP_ARGS(start, size, prot, pgoff, flags), + TP_STRUCT__entry(__field(unsigned long, start) __field(unsigned long, size) __field(unsigned long, prot) __field(unsigned long, pgoff) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(start, start) tp_assign(size, size) tp_assign(prot, prot) tp_assign(pgoff, pgoff) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mmap +SC_TRACE_EVENT(sys_mmap, + TP_PROTO(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off), + TP_ARGS(addr, len, prot, flags, fd, off), + TP_STRUCT__entry(__field_hex(unsigned long, addr) __field(unsigned long, len) __field(unsigned long, prot) __field(unsigned long, flags) __field(unsigned long, fd) __field(unsigned long, off)), + TP_fast_assign(tp_assign(addr, addr) tp_assign(len, len) tp_assign(prot, prot) tp_assign(flags, flags) tp_assign(fd, fd) tp_assign(off, off)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_INTEGERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "x86-64-syscalls-3.0.4_integers_override.h" +#include "syscalls_integers_override.h" + +#ifndef OVERRIDE_TABLE_64_sys_sched_yield +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sched_yield, 24, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pause +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_pause, 34, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpid, 39, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getuid, 102, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getgid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getgid, 104, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_geteuid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_geteuid, 107, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getegid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getegid, 108, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getppid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getppid, 110, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpgrp +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_getpgrp, 111, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setsid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_setsid, 112, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munlockall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_munlockall, 152, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_vhangup +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_vhangup, 153, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sync +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_sync, 162, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_gettid +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_gettid, 186, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_restart_syscall +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_restart_syscall, 219, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_init +TRACE_SYSCALL_TABLE(syscalls_noargs, sys_inotify_init, 253, 0) +#endif +#ifndef OVERRIDE_TABLE_64_sys_close +TRACE_SYSCALL_TABLE(sys_close, sys_close, 3, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lseek +TRACE_SYSCALL_TABLE(sys_lseek, sys_lseek, 8, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mmap +TRACE_SYSCALL_TABLE(sys_mmap, sys_mmap, 9, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mprotect +TRACE_SYSCALL_TABLE(sys_mprotect, sys_mprotect, 10, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munmap +TRACE_SYSCALL_TABLE(sys_munmap, sys_munmap, 11, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_brk +TRACE_SYSCALL_TABLE(sys_brk, sys_brk, 12, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioctl +TRACE_SYSCALL_TABLE(sys_ioctl, sys_ioctl, 16, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mremap +TRACE_SYSCALL_TABLE(sys_mremap, sys_mremap, 25, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msync +TRACE_SYSCALL_TABLE(sys_msync, sys_msync, 26, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_madvise +TRACE_SYSCALL_TABLE(sys_madvise, sys_madvise, 28, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmget +TRACE_SYSCALL_TABLE(sys_shmget, sys_shmget, 29, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_dup +TRACE_SYSCALL_TABLE(sys_dup, sys_dup, 32, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_dup2 +TRACE_SYSCALL_TABLE(sys_dup2, sys_dup2, 33, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_alarm +TRACE_SYSCALL_TABLE(sys_alarm, sys_alarm, 37, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_socket +TRACE_SYSCALL_TABLE(sys_socket, sys_socket, 41, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shutdown +TRACE_SYSCALL_TABLE(sys_shutdown, sys_shutdown, 48, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_listen +TRACE_SYSCALL_TABLE(sys_listen, sys_listen, 50, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_exit +TRACE_SYSCALL_TABLE(sys_exit, sys_exit, 60, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_kill +TRACE_SYSCALL_TABLE(sys_kill, sys_kill, 62, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semget +TRACE_SYSCALL_TABLE(sys_semget, sys_semget, 64, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgget +TRACE_SYSCALL_TABLE(sys_msgget, sys_msgget, 68, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fcntl +TRACE_SYSCALL_TABLE(sys_fcntl, sys_fcntl, 72, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_flock +TRACE_SYSCALL_TABLE(sys_flock, sys_flock, 73, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fsync +TRACE_SYSCALL_TABLE(sys_fsync, sys_fsync, 74, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fdatasync +TRACE_SYSCALL_TABLE(sys_fdatasync, sys_fdatasync, 75, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ftruncate +TRACE_SYSCALL_TABLE(sys_ftruncate, sys_ftruncate, 77, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchdir +TRACE_SYSCALL_TABLE(sys_fchdir, sys_fchdir, 81, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchmod +TRACE_SYSCALL_TABLE(sys_fchmod, sys_fchmod, 91, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchown +TRACE_SYSCALL_TABLE(sys_fchown, sys_fchown, 93, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_umask +TRACE_SYSCALL_TABLE(sys_umask, sys_umask, 95, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ptrace +TRACE_SYSCALL_TABLE(sys_ptrace, sys_ptrace, 101, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setuid +TRACE_SYSCALL_TABLE(sys_setuid, sys_setuid, 105, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setgid +TRACE_SYSCALL_TABLE(sys_setgid, sys_setgid, 106, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setpgid +TRACE_SYSCALL_TABLE(sys_setpgid, sys_setpgid, 109, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setreuid +TRACE_SYSCALL_TABLE(sys_setreuid, sys_setreuid, 113, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setregid +TRACE_SYSCALL_TABLE(sys_setregid, sys_setregid, 114, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setresuid +TRACE_SYSCALL_TABLE(sys_setresuid, sys_setresuid, 117, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setresgid +TRACE_SYSCALL_TABLE(sys_setresgid, sys_setresgid, 119, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpgid +TRACE_SYSCALL_TABLE(sys_getpgid, sys_getpgid, 121, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setfsuid +TRACE_SYSCALL_TABLE(sys_setfsuid, sys_setfsuid, 122, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setfsgid +TRACE_SYSCALL_TABLE(sys_setfsgid, sys_setfsgid, 123, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsid +TRACE_SYSCALL_TABLE(sys_getsid, sys_getsid, 124, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_personality +TRACE_SYSCALL_TABLE(sys_personality, sys_personality, 135, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sysfs +TRACE_SYSCALL_TABLE(sys_sysfs, sys_sysfs, 139, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpriority +TRACE_SYSCALL_TABLE(sys_getpriority, sys_getpriority, 140, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setpriority +TRACE_SYSCALL_TABLE(sys_setpriority, sys_setpriority, 141, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getscheduler +TRACE_SYSCALL_TABLE(sys_sched_getscheduler, sys_sched_getscheduler, 145, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_max +TRACE_SYSCALL_TABLE(sys_sched_get_priority_max, sys_sched_get_priority_max, 146, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_get_priority_min +TRACE_SYSCALL_TABLE(sys_sched_get_priority_min, sys_sched_get_priority_min, 147, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mlock +TRACE_SYSCALL_TABLE(sys_mlock, sys_mlock, 149, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_munlock +TRACE_SYSCALL_TABLE(sys_munlock, sys_munlock, 150, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mlockall +TRACE_SYSCALL_TABLE(sys_mlockall, sys_mlockall, 151, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_prctl +TRACE_SYSCALL_TABLE(sys_prctl, sys_prctl, 157, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tkill +TRACE_SYSCALL_TABLE(sys_tkill, sys_tkill, 200, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_destroy +TRACE_SYSCALL_TABLE(sys_io_destroy, sys_io_destroy, 207, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_create +TRACE_SYSCALL_TABLE(sys_epoll_create, sys_epoll_create, 213, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_remap_file_pages +TRACE_SYSCALL_TABLE(sys_remap_file_pages, sys_remap_file_pages, 216, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_getoverrun +TRACE_SYSCALL_TABLE(sys_timer_getoverrun, sys_timer_getoverrun, 225, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_delete +TRACE_SYSCALL_TABLE(sys_timer_delete, sys_timer_delete, 226, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_exit_group +TRACE_SYSCALL_TABLE(sys_exit_group, sys_exit_group, 231, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tgkill +TRACE_SYSCALL_TABLE(sys_tgkill, sys_tgkill, 234, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioprio_set +TRACE_SYSCALL_TABLE(sys_ioprio_set, sys_ioprio_set, 251, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ioprio_get +TRACE_SYSCALL_TABLE(sys_ioprio_get, sys_ioprio_get, 252, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_rm_watch +TRACE_SYSCALL_TABLE(sys_inotify_rm_watch, sys_inotify_rm_watch, 255, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_unshare +TRACE_SYSCALL_TABLE(sys_unshare, sys_unshare, 272, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_tee +TRACE_SYSCALL_TABLE(sys_tee, sys_tee, 276, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_create +TRACE_SYSCALL_TABLE(sys_timerfd_create, sys_timerfd_create, 283, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_eventfd +TRACE_SYSCALL_TABLE(sys_eventfd, sys_eventfd, 284, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_eventfd2 +TRACE_SYSCALL_TABLE(sys_eventfd2, sys_eventfd2, 290, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_create1 +TRACE_SYSCALL_TABLE(sys_epoll_create1, sys_epoll_create1, 291, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_dup3 +TRACE_SYSCALL_TABLE(sys_dup3, sys_dup3, 292, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_init1 +TRACE_SYSCALL_TABLE(sys_inotify_init1, sys_inotify_init1, 294, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_syncfs +TRACE_SYSCALL_TABLE(sys_syncfs, sys_syncfs, 306, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setns +TRACE_SYSCALL_TABLE(sys_setns, sys_setns, 308, 2) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h new file mode 100644 index 0000000..3d400f7 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_integers_override.h @@ -0,0 +1,3 @@ +/* + * this is a place-holder for x86_64 interger syscall definition override. + */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h new file mode 100644 index 0000000..e926a60 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers.h @@ -0,0 +1,2076 @@ +/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */ +#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_POINTERS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_POINTERS_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> +#include "x86-64-syscalls-3.0.4_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_64_sys_pipe +SC_TRACE_EVENT(sys_pipe, + TP_PROTO(int * fildes), + TP_ARGS(fildes), + TP_STRUCT__entry(__field_hex(int *, fildes)), + TP_fast_assign(tp_assign(fildes, fildes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newuname +SC_TRACE_EVENT(sys_newuname, + TP_PROTO(struct new_utsname * name), + TP_ARGS(name), + TP_STRUCT__entry(__field_hex(struct new_utsname *, name)), + TP_fast_assign(tp_assign(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmdt +SC_TRACE_EVENT(sys_shmdt, + TP_PROTO(char * shmaddr), + TP_ARGS(shmaddr), + TP_STRUCT__entry(__field_hex(char *, shmaddr)), + TP_fast_assign(tp_assign(shmaddr, shmaddr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_chdir +SC_TRACE_EVENT(sys_chdir, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rmdir +SC_TRACE_EVENT(sys_rmdir, + TP_PROTO(const char * pathname), + TP_ARGS(pathname), + TP_STRUCT__entry(__string_from_user(pathname, pathname)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_unlink +SC_TRACE_EVENT(sys_unlink, + TP_PROTO(const char * pathname), + TP_ARGS(pathname), + TP_STRUCT__entry(__string_from_user(pathname, pathname)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sysinfo +SC_TRACE_EVENT(sys_sysinfo, + TP_PROTO(struct sysinfo * info), + TP_ARGS(info), + TP_STRUCT__entry(__field_hex(struct sysinfo *, info)), + TP_fast_assign(tp_assign(info, info)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_times +SC_TRACE_EVENT(sys_times, + TP_PROTO(struct tms * tbuf), + TP_ARGS(tbuf), + TP_STRUCT__entry(__field_hex(struct tms *, tbuf)), + TP_fast_assign(tp_assign(tbuf, tbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sysctl +SC_TRACE_EVENT(sys_sysctl, + TP_PROTO(struct __sysctl_args * args), + TP_ARGS(args), + TP_STRUCT__entry(__field_hex(struct __sysctl_args *, args)), + TP_fast_assign(tp_assign(args, args)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_adjtimex +SC_TRACE_EVENT(sys_adjtimex, + TP_PROTO(struct timex * txc_p), + TP_ARGS(txc_p), + TP_STRUCT__entry(__field_hex(struct timex *, txc_p)), + TP_fast_assign(tp_assign(txc_p, txc_p)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_chroot +SC_TRACE_EVENT(sys_chroot, + TP_PROTO(const char * filename), + TP_ARGS(filename), + TP_STRUCT__entry(__string_from_user(filename, filename)), + TP_fast_assign(tp_copy_string_from_user(filename, filename)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_swapoff +SC_TRACE_EVENT(sys_swapoff, + TP_PROTO(const char * specialfile), + TP_ARGS(specialfile), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_time +SC_TRACE_EVENT(sys_time, + TP_PROTO(time_t * tloc), + TP_ARGS(tloc), + TP_STRUCT__entry(__field_hex(time_t *, tloc)), + TP_fast_assign(tp_assign(tloc, tloc)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_tid_address +SC_TRACE_EVENT(sys_set_tid_address, + TP_PROTO(int * tidptr), + TP_ARGS(tidptr), + TP_STRUCT__entry(__field_hex(int *, tidptr)), + TP_fast_assign(tp_assign(tidptr, tidptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_unlink +SC_TRACE_EVENT(sys_mq_unlink, + TP_PROTO(const char * u_name), + TP_ARGS(u_name), + TP_STRUCT__entry(__string_from_user(u_name, u_name)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newstat +SC_TRACE_EVENT(sys_newstat, + TP_PROTO(const char * filename, struct stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newfstat +SC_TRACE_EVENT(sys_newfstat, + TP_PROTO(unsigned int fd, struct stat * statbuf), + TP_ARGS(fd, statbuf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newlstat +SC_TRACE_EVENT(sys_newlstat, + TP_PROTO(const char * filename, struct stat * statbuf), + TP_ARGS(filename, statbuf), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct stat *, statbuf)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_access +SC_TRACE_EVENT(sys_access, + TP_PROTO(const char * filename, int mode), + TP_ARGS(filename, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_nanosleep +SC_TRACE_EVENT(sys_nanosleep, + TP_PROTO(struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(rqtp, rmtp), + TP_STRUCT__entry(__field_hex(struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getitimer +SC_TRACE_EVENT(sys_getitimer, + TP_PROTO(int which, struct itimerval * value), + TP_ARGS(which, value), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_truncate +SC_TRACE_EVENT(sys_truncate, + TP_PROTO(const char * path, long length), + TP_ARGS(path, length), + TP_STRUCT__entry(__string_from_user(path, path) __field(long, length)), + TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(length, length)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getcwd +SC_TRACE_EVENT(sys_getcwd, + TP_PROTO(char * buf, unsigned long size), + TP_ARGS(buf, size), + TP_STRUCT__entry(__field_hex(char *, buf) __field(unsigned long, size)), + TP_fast_assign(tp_assign(buf, buf) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rename +SC_TRACE_EVENT(sys_rename, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mkdir +SC_TRACE_EVENT(sys_mkdir, + TP_PROTO(const char * pathname, int mode), + TP_ARGS(pathname, mode), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_creat +SC_TRACE_EVENT(sys_creat, + TP_PROTO(const char * pathname, int mode), + TP_ARGS(pathname, mode), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_link +SC_TRACE_EVENT(sys_link, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_symlink +SC_TRACE_EVENT(sys_symlink, + TP_PROTO(const char * oldname, const char * newname), + TP_ARGS(oldname, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_chmod +SC_TRACE_EVENT(sys_chmod, + TP_PROTO(const char * filename, mode_t mode), + TP_ARGS(filename, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(mode_t, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_gettimeofday +SC_TRACE_EVENT(sys_gettimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getrlimit +SC_TRACE_EVENT(sys_getrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getrusage +SC_TRACE_EVENT(sys_getrusage, + TP_PROTO(int who, struct rusage * ru), + TP_ARGS(who, ru), + TP_STRUCT__entry(__field(int, who) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(who, who) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getgroups +SC_TRACE_EVENT(sys_getgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setgroups +SC_TRACE_EVENT(sys_setgroups, + TP_PROTO(int gidsetsize, gid_t * grouplist), + TP_ARGS(gidsetsize, grouplist), + TP_STRUCT__entry(__field(int, gidsetsize) __field_hex(gid_t *, grouplist)), + TP_fast_assign(tp_assign(gidsetsize, gidsetsize) tp_assign(grouplist, grouplist)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigpending +SC_TRACE_EVENT(sys_rt_sigpending, + TP_PROTO(sigset_t * set, size_t sigsetsize), + TP_ARGS(set, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, set) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(set, set) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigsuspend +SC_TRACE_EVENT(sys_rt_sigsuspend, + TP_PROTO(sigset_t * unewset, size_t sigsetsize), + TP_ARGS(unewset, sigsetsize), + TP_STRUCT__entry(__field_hex(sigset_t *, unewset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(unewset, unewset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_utime +SC_TRACE_EVENT(sys_utime, + TP_PROTO(char * filename, struct utimbuf * times), + TP_ARGS(filename, times), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct utimbuf *, times)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(times, times)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ustat +SC_TRACE_EVENT(sys_ustat, + TP_PROTO(unsigned dev, struct ustat * ubuf), + TP_ARGS(dev, ubuf), + TP_STRUCT__entry(__field(unsigned, dev) __field_hex(struct ustat *, ubuf)), + TP_fast_assign(tp_assign(dev, dev) tp_assign(ubuf, ubuf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_statfs +SC_TRACE_EVENT(sys_statfs, + TP_PROTO(const char * pathname, struct statfs * buf), + TP_ARGS(pathname, buf), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fstatfs +SC_TRACE_EVENT(sys_fstatfs, + TP_PROTO(unsigned int fd, struct statfs * buf), + TP_ARGS(fd, buf), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct statfs *, buf)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setparam +SC_TRACE_EVENT(sys_sched_setparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getparam +SC_TRACE_EVENT(sys_sched_getparam, + TP_PROTO(pid_t pid, struct sched_param * param), + TP_ARGS(pid, param), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_rr_get_interval +SC_TRACE_EVENT(sys_sched_rr_get_interval, + TP_PROTO(pid_t pid, struct timespec * interval), + TP_ARGS(pid, interval), + TP_STRUCT__entry(__field(pid_t, pid) __field_hex(struct timespec *, interval)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(interval, interval)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pivot_root +SC_TRACE_EVENT(sys_pivot_root, + TP_PROTO(const char * new_root, const char * put_old), + TP_ARGS(new_root, put_old), + TP_STRUCT__entry(__string_from_user(new_root, new_root) __string_from_user(put_old, put_old)), + TP_fast_assign(tp_copy_string_from_user(new_root, new_root) tp_copy_string_from_user(put_old, put_old)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setrlimit +SC_TRACE_EVENT(sys_setrlimit, + TP_PROTO(unsigned int resource, struct rlimit * rlim), + TP_ARGS(resource, rlim), + TP_STRUCT__entry(__field(unsigned int, resource) __field_hex(struct rlimit *, rlim)), + TP_fast_assign(tp_assign(resource, resource) tp_assign(rlim, rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_settimeofday +SC_TRACE_EVENT(sys_settimeofday, + TP_PROTO(struct timeval * tv, struct timezone * tz), + TP_ARGS(tv, tz), + TP_STRUCT__entry(__field_hex(struct timeval *, tv) __field_hex(struct timezone *, tz)), + TP_fast_assign(tp_assign(tv, tv) tp_assign(tz, tz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_umount +SC_TRACE_EVENT(sys_umount, + TP_PROTO(char * name, int flags), + TP_ARGS(name, flags), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_swapon +SC_TRACE_EVENT(sys_swapon, + TP_PROTO(const char * specialfile, int swap_flags), + TP_ARGS(specialfile, swap_flags), + TP_STRUCT__entry(__string_from_user(specialfile, specialfile) __field(int, swap_flags)), + TP_fast_assign(tp_copy_string_from_user(specialfile, specialfile) tp_assign(swap_flags, swap_flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sethostname +SC_TRACE_EVENT(sys_sethostname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setdomainname +SC_TRACE_EVENT(sys_setdomainname, + TP_PROTO(char * name, int len), + TP_ARGS(name, len), + TP_STRUCT__entry(__string_from_user(name, name) __field(int, len)), + TP_fast_assign(tp_copy_string_from_user(name, name) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_delete_module +SC_TRACE_EVENT(sys_delete_module, + TP_PROTO(const char * name_user, unsigned int flags), + TP_ARGS(name_user, flags), + TP_STRUCT__entry(__string_from_user(name_user, name_user) __field(unsigned int, flags)), + TP_fast_assign(tp_copy_string_from_user(name_user, name_user) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_removexattr +SC_TRACE_EVENT(sys_removexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lremovexattr +SC_TRACE_EVENT(sys_lremovexattr, + TP_PROTO(const char * pathname, const char * name), + TP_ARGS(pathname, name), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fremovexattr +SC_TRACE_EVENT(sys_fremovexattr, + TP_PROTO(int fd, const char * name), + TP_ARGS(fd, name), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_setup +SC_TRACE_EVENT(sys_io_setup, + TP_PROTO(unsigned nr_events, aio_context_t * ctxp), + TP_ARGS(nr_events, ctxp), + TP_STRUCT__entry(__field(unsigned, nr_events) __field_hex(aio_context_t *, ctxp)), + TP_fast_assign(tp_assign(nr_events, nr_events) tp_assign(ctxp, ctxp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_gettime +SC_TRACE_EVENT(sys_timer_gettime, + TP_PROTO(timer_t timer_id, struct itimerspec * setting), + TP_ARGS(timer_id, setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field_hex(struct itimerspec *, setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(setting, setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_settime +SC_TRACE_EVENT(sys_clock_settime, + TP_PROTO(const clockid_t which_clock, const struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(const struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_gettime +SC_TRACE_EVENT(sys_clock_gettime, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_getres +SC_TRACE_EVENT(sys_clock_getres, + TP_PROTO(const clockid_t which_clock, struct timespec * tp), + TP_ARGS(which_clock, tp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timespec *, tp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(tp, tp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_utimes +SC_TRACE_EVENT(sys_utimes, + TP_PROTO(char * filename, struct timeval * utimes), + TP_ARGS(filename, utimes), + TP_STRUCT__entry(__string_from_user(filename, filename) __field_hex(struct timeval *, utimes)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_notify +SC_TRACE_EVENT(sys_mq_notify, + TP_PROTO(mqd_t mqdes, const struct sigevent * u_notification), + TP_ARGS(mqdes, u_notification), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct sigevent *, u_notification)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_notification, u_notification)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_set_robust_list +SC_TRACE_EVENT(sys_set_robust_list, + TP_PROTO(struct robust_list_head * head, size_t len), + TP_ARGS(head, len), + TP_STRUCT__entry(__field_hex(struct robust_list_head *, head) __field(size_t, len)), + TP_fast_assign(tp_assign(head, head) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_gettime +SC_TRACE_EVENT(sys_timerfd_gettime, + TP_PROTO(int ufd, struct itimerspec * otmr), + TP_ARGS(ufd, otmr), + TP_STRUCT__entry(__field(int, ufd) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pipe2 +SC_TRACE_EVENT(sys_pipe2, + TP_PROTO(int * fildes, int flags), + TP_ARGS(fildes, flags), + TP_STRUCT__entry(__field_hex(int *, fildes) __field(int, flags)), + TP_fast_assign(tp_assign(fildes, fildes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_adjtime +SC_TRACE_EVENT(sys_clock_adjtime, + TP_PROTO(const clockid_t which_clock, struct timex * utx), + TP_ARGS(which_clock, utx), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct timex *, utx)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(utx, utx)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_read +SC_TRACE_EVENT(sys_read, + TP_PROTO(unsigned int fd, char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_write +SC_TRACE_EVENT(sys_write, + TP_PROTO(unsigned int fd, const char * buf, size_t count), + TP_ARGS(fd, buf, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(const char *, buf) __field(size_t, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buf, buf) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_open +SC_TRACE_EVENT(sys_open, + TP_PROTO(const char * filename, int flags, int mode), + TP_ARGS(filename, flags, mode), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, flags) __field(int, mode)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_poll +SC_TRACE_EVENT(sys_poll, + TP_PROTO(struct pollfd * ufds, unsigned int nfds, long timeout_msecs), + TP_ARGS(ufds, nfds, timeout_msecs), + TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field(long, timeout_msecs)), + TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(timeout_msecs, timeout_msecs)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_readv +SC_TRACE_EVENT(sys_readv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_writev +SC_TRACE_EVENT(sys_writev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen), + TP_ARGS(fd, vec, vlen), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mincore +SC_TRACE_EVENT(sys_mincore, + TP_PROTO(unsigned long start, size_t len, unsigned char * vec), + TP_ARGS(start, len, vec), + TP_STRUCT__entry(__field(unsigned long, start) __field(size_t, len) __field_hex(unsigned char *, vec)), + TP_fast_assign(tp_assign(start, start) tp_assign(len, len) tp_assign(vec, vec)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmat +SC_TRACE_EVENT(sys_shmat, + TP_PROTO(int shmid, char * shmaddr, int shmflg), + TP_ARGS(shmid, shmaddr, shmflg), + TP_STRUCT__entry(__field(int, shmid) __field_hex(char *, shmaddr) __field(int, shmflg)), + TP_fast_assign(tp_assign(shmid, shmid) tp_assign(shmaddr, shmaddr) tp_assign(shmflg, shmflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_shmctl +SC_TRACE_EVENT(sys_shmctl, + TP_PROTO(int shmid, int cmd, struct shmid_ds * buf), + TP_ARGS(shmid, cmd, buf), + TP_STRUCT__entry(__field(int, shmid) __field(int, cmd) __field_hex(struct shmid_ds *, buf)), + TP_fast_assign(tp_assign(shmid, shmid) tp_assign(cmd, cmd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setitimer +SC_TRACE_EVENT(sys_setitimer, + TP_PROTO(int which, struct itimerval * value, struct itimerval * ovalue), + TP_ARGS(which, value, ovalue), + TP_STRUCT__entry(__field(int, which) __field_hex(struct itimerval *, value) __field_hex(struct itimerval *, ovalue)), + TP_fast_assign(tp_assign(which, which) tp_assign(value, value) tp_assign(ovalue, ovalue)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_connect +SC_TRACE_EVENT(sys_connect, + TP_PROTO(int fd, struct sockaddr * uservaddr, int addrlen), + TP_ARGS(fd, uservaddr, addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, uservaddr) __field_hex(int, addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(uservaddr, uservaddr) tp_assign(addrlen, addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_accept +SC_TRACE_EVENT(sys_accept, + TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen), + TP_ARGS(fd, upeer_sockaddr, upeer_addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendmsg +SC_TRACE_EVENT(sys_sendmsg, + TP_PROTO(int fd, struct msghdr * msg, unsigned flags), + TP_ARGS(fd, msg, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvmsg +SC_TRACE_EVENT(sys_recvmsg, + TP_PROTO(int fd, struct msghdr * msg, unsigned int flags), + TP_ARGS(fd, msg, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct msghdr *, msg) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(msg, msg) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_bind +SC_TRACE_EVENT(sys_bind, + TP_PROTO(int fd, struct sockaddr * umyaddr, int addrlen), + TP_ARGS(fd, umyaddr, addrlen), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, umyaddr) __field_hex(int, addrlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(umyaddr, umyaddr) tp_assign(addrlen, addrlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsockname +SC_TRACE_EVENT(sys_getsockname, + TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len), + TP_ARGS(fd, usockaddr, usockaddr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getpeername +SC_TRACE_EVENT(sys_getpeername, + TP_PROTO(int fd, struct sockaddr * usockaddr, int * usockaddr_len), + TP_ARGS(fd, usockaddr, usockaddr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, usockaddr) __field_hex(int *, usockaddr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(usockaddr, usockaddr) tp_assign(usockaddr_len, usockaddr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semop +SC_TRACE_EVENT(sys_semop, + TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops), + TP_ARGS(semid, tsops, nsops), + TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops)), + TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgctl +SC_TRACE_EVENT(sys_msgctl, + TP_PROTO(int msqid, int cmd, struct msqid_ds * buf), + TP_ARGS(msqid, cmd, buf), + TP_STRUCT__entry(__field(int, msqid) __field(int, cmd) __field_hex(struct msqid_ds *, buf)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(cmd, cmd) tp_assign(buf, buf)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getdents +SC_TRACE_EVENT(sys_getdents, + TP_PROTO(unsigned int fd, struct linux_dirent * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_readlink +SC_TRACE_EVENT(sys_readlink, + TP_PROTO(const char * path, char * buf, int bufsiz), + TP_ARGS(path, buf, bufsiz), + TP_STRUCT__entry(__string_from_user(path, path) __field_hex(char *, buf) __field(int, bufsiz)), + TP_fast_assign(tp_copy_string_from_user(path, path) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_chown +SC_TRACE_EVENT(sys_chown, + TP_PROTO(const char * filename, uid_t user, gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lchown +SC_TRACE_EVENT(sys_lchown, + TP_PROTO(const char * filename, uid_t user, gid_t group), + TP_ARGS(filename, user, group), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_syslog +SC_TRACE_EVENT(sys_syslog, + TP_PROTO(int type, char * buf, int len), + TP_ARGS(type, buf, len), + TP_STRUCT__entry(__field(int, type) __field_hex(char *, buf) __field(int, len)), + TP_fast_assign(tp_assign(type, type) tp_assign(buf, buf) tp_assign(len, len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getresuid +SC_TRACE_EVENT(sys_getresuid, + TP_PROTO(uid_t * ruid, uid_t * euid, uid_t * suid), + TP_ARGS(ruid, euid, suid), + TP_STRUCT__entry(__field_hex(uid_t *, ruid) __field_hex(uid_t *, euid) __field_hex(uid_t *, suid)), + TP_fast_assign(tp_assign(ruid, ruid) tp_assign(euid, euid) tp_assign(suid, suid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getresgid +SC_TRACE_EVENT(sys_getresgid, + TP_PROTO(gid_t * rgid, gid_t * egid, gid_t * sgid), + TP_ARGS(rgid, egid, sgid), + TP_STRUCT__entry(__field_hex(gid_t *, rgid) __field_hex(gid_t *, egid) __field_hex(gid_t *, sgid)), + TP_fast_assign(tp_assign(rgid, rgid) tp_assign(egid, egid) tp_assign(sgid, sgid)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigqueueinfo +SC_TRACE_EVENT(sys_rt_sigqueueinfo, + TP_PROTO(pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mknod +SC_TRACE_EVENT(sys_mknod, + TP_PROTO(const char * filename, int mode, unsigned dev), + TP_ARGS(filename, mode, dev), + TP_STRUCT__entry(__string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)), + TP_fast_assign(tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setscheduler +SC_TRACE_EVENT(sys_sched_setscheduler, + TP_PROTO(pid_t pid, int policy, struct sched_param * param), + TP_ARGS(pid, policy, param), + TP_STRUCT__entry(__field(pid_t, pid) __field(int, policy) __field_hex(struct sched_param *, param)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(policy, policy) tp_assign(param, param)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_init_module +SC_TRACE_EVENT(sys_init_module, + TP_PROTO(void * umod, unsigned long len, const char * uargs), + TP_ARGS(umod, len, uargs), + TP_STRUCT__entry(__field_hex(void *, umod) __field(unsigned long, len) __field_hex(const char *, uargs)), + TP_fast_assign(tp_assign(umod, umod) tp_assign(len, len) tp_assign(uargs, uargs)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_nfsservctl +SC_TRACE_EVENT(sys_nfsservctl, + TP_PROTO(int cmd, struct nfsctl_arg * arg, void * res), + TP_ARGS(cmd, arg, res), + TP_STRUCT__entry(__field(int, cmd) __field_hex(struct nfsctl_arg *, arg) __field_hex(void *, res)), + TP_fast_assign(tp_assign(cmd, cmd) tp_assign(arg, arg) tp_assign(res, res)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_listxattr +SC_TRACE_EVENT(sys_listxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_llistxattr +SC_TRACE_EVENT(sys_llistxattr, + TP_PROTO(const char * pathname, char * list, size_t size), + TP_ARGS(pathname, list, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_flistxattr +SC_TRACE_EVENT(sys_flistxattr, + TP_PROTO(int fd, char * list, size_t size), + TP_ARGS(fd, list, size), + TP_STRUCT__entry(__field(int, fd) __field_hex(char *, list) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(list, list) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_setaffinity +SC_TRACE_EVENT(sys_sched_setaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sched_getaffinity +SC_TRACE_EVENT(sys_sched_getaffinity, + TP_PROTO(pid_t pid, unsigned int len, unsigned long * user_mask_ptr), + TP_ARGS(pid, len, user_mask_ptr), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, len) __field_hex(unsigned long *, user_mask_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(len, len) tp_assign(user_mask_ptr, user_mask_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_submit +SC_TRACE_EVENT(sys_io_submit, + TP_PROTO(aio_context_t ctx_id, long nr, struct iocb * * iocbpp), + TP_ARGS(ctx_id, nr, iocbpp), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, nr) __field_hex(struct iocb * *, iocbpp)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(nr, nr) tp_assign(iocbpp, iocbpp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_cancel +SC_TRACE_EVENT(sys_io_cancel, + TP_PROTO(aio_context_t ctx_id, struct iocb * iocb, struct io_event * result), + TP_ARGS(ctx_id, iocb, result), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field_hex(struct iocb *, iocb) __field_hex(struct io_event *, result)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(iocb, iocb) tp_assign(result, result)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getdents64 +SC_TRACE_EVENT(sys_getdents64, + TP_PROTO(unsigned int fd, struct linux_dirent64 * dirent, unsigned int count), + TP_ARGS(fd, dirent, count), + TP_STRUCT__entry(__field(unsigned int, fd) __field_hex(struct linux_dirent64 *, dirent) __field(unsigned int, count)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(dirent, dirent) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_create +SC_TRACE_EVENT(sys_timer_create, + TP_PROTO(const clockid_t which_clock, struct sigevent * timer_event_spec, timer_t * created_timer_id), + TP_ARGS(which_clock, timer_event_spec, created_timer_id), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field_hex(struct sigevent *, timer_event_spec) __field_hex(timer_t *, created_timer_id)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(timer_event_spec, timer_event_spec) tp_assign(created_timer_id, created_timer_id)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_getsetattr +SC_TRACE_EVENT(sys_mq_getsetattr, + TP_PROTO(mqd_t mqdes, const struct mq_attr * u_mqstat, struct mq_attr * u_omqstat), + TP_ARGS(mqdes, u_mqstat, u_omqstat), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const struct mq_attr *, u_mqstat) __field_hex(struct mq_attr *, u_omqstat)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_mqstat, u_mqstat) tp_assign(u_omqstat, u_omqstat)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_inotify_add_watch +SC_TRACE_EVENT(sys_inotify_add_watch, + TP_PROTO(int fd, const char * pathname, u32 mask), + TP_ARGS(fd, pathname, mask), + TP_STRUCT__entry(__field(int, fd) __string_from_user(pathname, pathname) __field(u32, mask)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(pathname, pathname) tp_assign(mask, mask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mkdirat +SC_TRACE_EVENT(sys_mkdirat, + TP_PROTO(int dfd, const char * pathname, int mode), + TP_ARGS(dfd, pathname, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_futimesat +SC_TRACE_EVENT(sys_futimesat, + TP_PROTO(int dfd, const char * filename, struct timeval * utimes), + TP_ARGS(dfd, filename, utimes), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timeval *, utimes)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_unlinkat +SC_TRACE_EVENT(sys_unlinkat, + TP_PROTO(int dfd, const char * pathname, int flag), + TP_ARGS(dfd, pathname, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_symlinkat +SC_TRACE_EVENT(sys_symlinkat, + TP_PROTO(const char * oldname, int newdfd, const char * newname), + TP_ARGS(oldname, newdfd, newname), + TP_STRUCT__entry(__string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchmodat +SC_TRACE_EVENT(sys_fchmodat, + TP_PROTO(int dfd, const char * filename, mode_t mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(mode_t, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_faccessat +SC_TRACE_EVENT(sys_faccessat, + TP_PROTO(int dfd, const char * filename, int mode), + TP_ARGS(dfd, filename, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_get_robust_list +SC_TRACE_EVENT(sys_get_robust_list, + TP_PROTO(int pid, struct robust_list_head * * head_ptr, size_t * len_ptr), + TP_ARGS(pid, head_ptr, len_ptr), + TP_STRUCT__entry(__field(int, pid) __field_hex(struct robust_list_head * *, head_ptr) __field_hex(size_t *, len_ptr)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(head_ptr, head_ptr) tp_assign(len_ptr, len_ptr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_signalfd +SC_TRACE_EVENT(sys_signalfd, + TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask), + TP_ARGS(ufd, user_mask, sizemask), + TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigaction +SC_TRACE_EVENT(sys_rt_sigaction, + TP_PROTO(int sig, const struct sigaction * act, struct sigaction * oact, size_t sigsetsize), + TP_ARGS(sig, act, oact, sigsetsize), + TP_STRUCT__entry(__field(int, sig) __field_hex(const struct sigaction *, act) __field_hex(struct sigaction *, oact) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(sig, sig) tp_assign(act, act) tp_assign(oact, oact) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigprocmask +SC_TRACE_EVENT(sys_rt_sigprocmask, + TP_PROTO(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize), + TP_ARGS(how, nset, oset, sigsetsize), + TP_STRUCT__entry(__field(int, how) __field_hex(sigset_t *, nset) __field_hex(sigset_t *, oset) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(how, how) tp_assign(nset, nset) tp_assign(oset, oset) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendfile64 +SC_TRACE_EVENT(sys_sendfile64, + TP_PROTO(int out_fd, int in_fd, loff_t * offset, size_t count), + TP_ARGS(out_fd, in_fd, offset, count), + TP_STRUCT__entry(__field(int, out_fd) __field(int, in_fd) __field_hex(loff_t *, offset) __field(size_t, count)), + TP_fast_assign(tp_assign(out_fd, out_fd) tp_assign(in_fd, in_fd) tp_assign(offset, offset) tp_assign(count, count)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_socketpair +SC_TRACE_EVENT(sys_socketpair, + TP_PROTO(int family, int type, int protocol, int * usockvec), + TP_ARGS(family, type, protocol, usockvec), + TP_STRUCT__entry(__field(int, family) __field(int, type) __field(int, protocol) __field_hex(int *, usockvec)), + TP_fast_assign(tp_assign(family, family) tp_assign(type, type) tp_assign(protocol, protocol) tp_assign(usockvec, usockvec)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_wait4 +SC_TRACE_EVENT(sys_wait4, + TP_PROTO(pid_t upid, int * stat_addr, int options, struct rusage * ru), + TP_ARGS(upid, stat_addr, options, ru), + TP_STRUCT__entry(__field(pid_t, upid) __field_hex(int *, stat_addr) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(upid, upid) tp_assign(stat_addr, stat_addr) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgsnd +SC_TRACE_EVENT(sys_msgsnd, + TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, int msgflg), + TP_ARGS(msqid, msgp, msgsz, msgflg), + TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(int, msgflg)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_sigtimedwait +SC_TRACE_EVENT(sys_rt_sigtimedwait, + TP_PROTO(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec * uts, size_t sigsetsize), + TP_ARGS(uthese, uinfo, uts, sigsetsize), + TP_STRUCT__entry(__field_hex(const sigset_t *, uthese) __field_hex(siginfo_t *, uinfo) __field_hex(const struct timespec *, uts) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(uthese, uthese) tp_assign(uinfo, uinfo) tp_assign(uts, uts) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_reboot +SC_TRACE_EVENT(sys_reboot, + TP_PROTO(int magic1, int magic2, unsigned int cmd, void * arg), + TP_ARGS(magic1, magic2, cmd, arg), + TP_STRUCT__entry(__field(int, magic1) __field(int, magic2) __field(unsigned int, cmd) __field_hex(void *, arg)), + TP_fast_assign(tp_assign(magic1, magic1) tp_assign(magic2, magic2) tp_assign(cmd, cmd) tp_assign(arg, arg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getxattr +SC_TRACE_EVENT(sys_getxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lgetxattr +SC_TRACE_EVENT(sys_lgetxattr, + TP_PROTO(const char * pathname, const char * name, void * value, size_t size), + TP_ARGS(pathname, name, value, size), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fgetxattr +SC_TRACE_EVENT(sys_fgetxattr, + TP_PROTO(int fd, const char * name, void * value, size_t size), + TP_ARGS(fd, name, value, size), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(void *, value) __field(size_t, size)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_semtimedop +SC_TRACE_EVENT(sys_semtimedop, + TP_PROTO(int semid, struct sembuf * tsops, unsigned nsops, const struct timespec * timeout), + TP_ARGS(semid, tsops, nsops, timeout), + TP_STRUCT__entry(__field(int, semid) __field_hex(struct sembuf *, tsops) __field(unsigned, nsops) __field_hex(const struct timespec *, timeout)), + TP_fast_assign(tp_assign(semid, semid) tp_assign(tsops, tsops) tp_assign(nsops, nsops) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timer_settime +SC_TRACE_EVENT(sys_timer_settime, + TP_PROTO(timer_t timer_id, int flags, const struct itimerspec * new_setting, struct itimerspec * old_setting), + TP_ARGS(timer_id, flags, new_setting, old_setting), + TP_STRUCT__entry(__field(timer_t, timer_id) __field(int, flags) __field_hex(const struct itimerspec *, new_setting) __field_hex(struct itimerspec *, old_setting)), + TP_fast_assign(tp_assign(timer_id, timer_id) tp_assign(flags, flags) tp_assign(new_setting, new_setting) tp_assign(old_setting, old_setting)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_clock_nanosleep +SC_TRACE_EVENT(sys_clock_nanosleep, + TP_PROTO(const clockid_t which_clock, int flags, const struct timespec * rqtp, struct timespec * rmtp), + TP_ARGS(which_clock, flags, rqtp, rmtp), + TP_STRUCT__entry(__field(const clockid_t, which_clock) __field(int, flags) __field_hex(const struct timespec *, rqtp) __field_hex(struct timespec *, rmtp)), + TP_fast_assign(tp_assign(which_clock, which_clock) tp_assign(flags, flags) tp_assign(rqtp, rqtp) tp_assign(rmtp, rmtp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_wait +SC_TRACE_EVENT(sys_epoll_wait, + TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout), + TP_ARGS(epfd, events, maxevents, timeout), + TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_ctl +SC_TRACE_EVENT(sys_epoll_ctl, + TP_PROTO(int epfd, int op, int fd, struct epoll_event * event), + TP_ARGS(epfd, op, fd, event), + TP_STRUCT__entry(__field(int, epfd) __field(int, op) __field(int, fd) __field_hex(struct epoll_event *, event)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(op, op) tp_assign(fd, fd) tp_assign(event, event)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_open +SC_TRACE_EVENT(sys_mq_open, + TP_PROTO(const char * u_name, int oflag, mode_t mode, struct mq_attr * u_attr), + TP_ARGS(u_name, oflag, mode, u_attr), + TP_STRUCT__entry(__string_from_user(u_name, u_name) __field(int, oflag) __field(mode_t, mode) __field_hex(struct mq_attr *, u_attr)), + TP_fast_assign(tp_copy_string_from_user(u_name, u_name) tp_assign(oflag, oflag) tp_assign(mode, mode) tp_assign(u_attr, u_attr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_kexec_load +SC_TRACE_EVENT(sys_kexec_load, + TP_PROTO(unsigned long entry, unsigned long nr_segments, struct kexec_segment * segments, unsigned long flags), + TP_ARGS(entry, nr_segments, segments, flags), + TP_STRUCT__entry(__field(unsigned long, entry) __field(unsigned long, nr_segments) __field_hex(struct kexec_segment *, segments) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(entry, entry) tp_assign(nr_segments, nr_segments) tp_assign(segments, segments) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_openat +SC_TRACE_EVENT(sys_openat, + TP_PROTO(int dfd, const char * filename, int flags, int mode), + TP_ARGS(dfd, filename, flags, mode), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, flags) __field(int, mode)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(flags, flags) tp_assign(mode, mode)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mknodat +SC_TRACE_EVENT(sys_mknodat, + TP_PROTO(int dfd, const char * filename, int mode, unsigned dev), + TP_ARGS(dfd, filename, mode, dev), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(int, mode) __field(unsigned, dev)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(mode, mode) tp_assign(dev, dev)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_newfstatat +SC_TRACE_EVENT(sys_newfstatat, + TP_PROTO(int dfd, const char * filename, struct stat * statbuf, int flag), + TP_ARGS(dfd, filename, statbuf, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct stat *, statbuf) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(statbuf, statbuf) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_renameat +SC_TRACE_EVENT(sys_renameat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname), + TP_ARGS(olddfd, oldname, newdfd, newname), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_readlinkat +SC_TRACE_EVENT(sys_readlinkat, + TP_PROTO(int dfd, const char * pathname, char * buf, int bufsiz), + TP_ARGS(dfd, pathname, buf, bufsiz), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(pathname, pathname) __field_hex(char *, buf) __field(int, bufsiz)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(pathname, pathname) tp_assign(buf, buf) tp_assign(bufsiz, bufsiz)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_vmsplice +SC_TRACE_EVENT(sys_vmsplice, + TP_PROTO(int fd, const struct iovec * iov, unsigned long nr_segs, unsigned int flags), + TP_ARGS(fd, iov, nr_segs, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(const struct iovec *, iov) __field(unsigned long, nr_segs) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(iov, iov) tp_assign(nr_segs, nr_segs) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_utimensat +SC_TRACE_EVENT(sys_utimensat, + TP_PROTO(int dfd, const char * filename, struct timespec * utimes, int flags), + TP_ARGS(dfd, filename, utimes, flags), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field_hex(struct timespec *, utimes) __field(int, flags)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(utimes, utimes) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_timerfd_settime +SC_TRACE_EVENT(sys_timerfd_settime, + TP_PROTO(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr), + TP_ARGS(ufd, flags, utmr, otmr), + TP_STRUCT__entry(__field(int, ufd) __field(int, flags) __field_hex(const struct itimerspec *, utmr) __field_hex(struct itimerspec *, otmr)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(flags, flags) tp_assign(utmr, utmr) tp_assign(otmr, otmr)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_accept4 +SC_TRACE_EVENT(sys_accept4, + TP_PROTO(int fd, struct sockaddr * upeer_sockaddr, int * upeer_addrlen, int flags), + TP_ARGS(fd, upeer_sockaddr, upeer_addrlen, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct sockaddr *, upeer_sockaddr) __field_hex(int *, upeer_addrlen) __field(int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(upeer_sockaddr, upeer_sockaddr) tp_assign(upeer_addrlen, upeer_addrlen) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_signalfd4 +SC_TRACE_EVENT(sys_signalfd4, + TP_PROTO(int ufd, sigset_t * user_mask, size_t sizemask, int flags), + TP_ARGS(ufd, user_mask, sizemask, flags), + TP_STRUCT__entry(__field(int, ufd) __field_hex(sigset_t *, user_mask) __field(size_t, sizemask) __field(int, flags)), + TP_fast_assign(tp_assign(ufd, ufd) tp_assign(user_mask, user_mask) tp_assign(sizemask, sizemask) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_rt_tgsigqueueinfo +SC_TRACE_EVENT(sys_rt_tgsigqueueinfo, + TP_PROTO(pid_t tgid, pid_t pid, int sig, siginfo_t * uinfo), + TP_ARGS(tgid, pid, sig, uinfo), + TP_STRUCT__entry(__field(pid_t, tgid) __field(pid_t, pid) __field(int, sig) __field_hex(siginfo_t *, uinfo)), + TP_fast_assign(tp_assign(tgid, tgid) tp_assign(pid, pid) tp_assign(sig, sig) tp_assign(uinfo, uinfo)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_prlimit64 +SC_TRACE_EVENT(sys_prlimit64, + TP_PROTO(pid_t pid, unsigned int resource, const struct rlimit64 * new_rlim, struct rlimit64 * old_rlim), + TP_ARGS(pid, resource, new_rlim, old_rlim), + TP_STRUCT__entry(__field(pid_t, pid) __field(unsigned int, resource) __field_hex(const struct rlimit64 *, new_rlim) __field_hex(struct rlimit64 *, old_rlim)), + TP_fast_assign(tp_assign(pid, pid) tp_assign(resource, resource) tp_assign(new_rlim, new_rlim) tp_assign(old_rlim, old_rlim)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendmmsg +SC_TRACE_EVENT(sys_sendmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags), + TP_ARGS(fd, mmsg, vlen, flags), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_select +SC_TRACE_EVENT(sys_select, + TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timeval * tvp), + TP_ARGS(n, inp, outp, exp, tvp), + TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timeval *, tvp)), + TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tvp, tvp)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setsockopt +SC_TRACE_EVENT(sys_setsockopt, + TP_PROTO(int fd, int level, int optname, char * optval, int optlen), + TP_ARGS(fd, level, optname, optval, optlen), + TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field(int, optlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_getsockopt +SC_TRACE_EVENT(sys_getsockopt, + TP_PROTO(int fd, int level, int optname, char * optval, int * optlen), + TP_ARGS(fd, level, optname, optval, optlen), + TP_STRUCT__entry(__field(int, fd) __field(int, level) __field(int, optname) __field_hex(char *, optval) __field_hex(int *, optlen)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(level, level) tp_assign(optname, optname) tp_assign(optval, optval) tp_assign(optlen, optlen)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_msgrcv +SC_TRACE_EVENT(sys_msgrcv, + TP_PROTO(int msqid, struct msgbuf * msgp, size_t msgsz, long msgtyp, int msgflg), + TP_ARGS(msqid, msgp, msgsz, msgtyp, msgflg), + TP_STRUCT__entry(__field(int, msqid) __field_hex(struct msgbuf *, msgp) __field(size_t, msgsz) __field(long, msgtyp) __field(int, msgflg)), + TP_fast_assign(tp_assign(msqid, msqid) tp_assign(msgp, msgp) tp_assign(msgsz, msgsz) tp_assign(msgtyp, msgtyp) tp_assign(msgflg, msgflg)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mount +SC_TRACE_EVENT(sys_mount, + TP_PROTO(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data), + TP_ARGS(dev_name, dir_name, type, flags, data), + TP_STRUCT__entry(__string_from_user(dev_name, dev_name) __string_from_user(dir_name, dir_name) __string_from_user(type, type) __field(unsigned long, flags) __field_hex(void *, data)), + TP_fast_assign(tp_copy_string_from_user(dev_name, dev_name) tp_copy_string_from_user(dir_name, dir_name) tp_copy_string_from_user(type, type) tp_assign(flags, flags) tp_assign(data, data)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_setxattr +SC_TRACE_EVENT(sys_setxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_lsetxattr +SC_TRACE_EVENT(sys_lsetxattr, + TP_PROTO(const char * pathname, const char * name, const void * value, size_t size, int flags), + TP_ARGS(pathname, name, value, size, flags), + TP_STRUCT__entry(__string_from_user(pathname, pathname) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_copy_string_from_user(pathname, pathname) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fsetxattr +SC_TRACE_EVENT(sys_fsetxattr, + TP_PROTO(int fd, const char * name, const void * value, size_t size, int flags), + TP_ARGS(fd, name, value, size, flags), + TP_STRUCT__entry(__field(int, fd) __string_from_user(name, name) __field_hex(const void *, value) __field(size_t, size) __field(int, flags)), + TP_fast_assign(tp_assign(fd, fd) tp_copy_string_from_user(name, name) tp_assign(value, value) tp_assign(size, size) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_io_getevents +SC_TRACE_EVENT(sys_io_getevents, + TP_PROTO(aio_context_t ctx_id, long min_nr, long nr, struct io_event * events, struct timespec * timeout), + TP_ARGS(ctx_id, min_nr, nr, events, timeout), + TP_STRUCT__entry(__field(aio_context_t, ctx_id) __field(long, min_nr) __field(long, nr) __field_hex(struct io_event *, events) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(ctx_id, ctx_id) tp_assign(min_nr, min_nr) tp_assign(nr, nr) tp_assign(events, events) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_timedsend +SC_TRACE_EVENT(sys_mq_timedsend, + TP_PROTO(mqd_t mqdes, const char * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(const char *, u_msg_ptr) __field(size_t, msg_len) __field(unsigned int, msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(msg_prio, msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_mq_timedreceive +SC_TRACE_EVENT(sys_mq_timedreceive, + TP_PROTO(mqd_t mqdes, char * u_msg_ptr, size_t msg_len, unsigned int * u_msg_prio, const struct timespec * u_abs_timeout), + TP_ARGS(mqdes, u_msg_ptr, msg_len, u_msg_prio, u_abs_timeout), + TP_STRUCT__entry(__field(mqd_t, mqdes) __field_hex(char *, u_msg_ptr) __field(size_t, msg_len) __field_hex(unsigned int *, u_msg_prio) __field_hex(const struct timespec *, u_abs_timeout)), + TP_fast_assign(tp_assign(mqdes, mqdes) tp_assign(u_msg_ptr, u_msg_ptr) tp_assign(msg_len, msg_len) tp_assign(u_msg_prio, u_msg_prio) tp_assign(u_abs_timeout, u_abs_timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_waitid +SC_TRACE_EVENT(sys_waitid, + TP_PROTO(int which, pid_t upid, struct siginfo * infop, int options, struct rusage * ru), + TP_ARGS(which, upid, infop, options, ru), + TP_STRUCT__entry(__field(int, which) __field(pid_t, upid) __field_hex(struct siginfo *, infop) __field(int, options) __field_hex(struct rusage *, ru)), + TP_fast_assign(tp_assign(which, which) tp_assign(upid, upid) tp_assign(infop, infop) tp_assign(options, options) tp_assign(ru, ru)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_fchownat +SC_TRACE_EVENT(sys_fchownat, + TP_PROTO(int dfd, const char * filename, uid_t user, gid_t group, int flag), + TP_ARGS(dfd, filename, user, group, flag), + TP_STRUCT__entry(__field(int, dfd) __string_from_user(filename, filename) __field(uid_t, user) __field(gid_t, group) __field(int, flag)), + TP_fast_assign(tp_assign(dfd, dfd) tp_copy_string_from_user(filename, filename) tp_assign(user, user) tp_assign(group, group) tp_assign(flag, flag)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_linkat +SC_TRACE_EVENT(sys_linkat, + TP_PROTO(int olddfd, const char * oldname, int newdfd, const char * newname, int flags), + TP_ARGS(olddfd, oldname, newdfd, newname, flags), + TP_STRUCT__entry(__field(int, olddfd) __string_from_user(oldname, oldname) __field(int, newdfd) __string_from_user(newname, newname) __field(int, flags)), + TP_fast_assign(tp_assign(olddfd, olddfd) tp_copy_string_from_user(oldname, oldname) tp_assign(newdfd, newdfd) tp_copy_string_from_user(newname, newname) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_ppoll +SC_TRACE_EVENT(sys_ppoll, + TP_PROTO(struct pollfd * ufds, unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(ufds, nfds, tsp, sigmask, sigsetsize), + TP_STRUCT__entry(__field_hex(struct pollfd *, ufds) __field(unsigned int, nfds) __field_hex(struct timespec *, tsp) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(ufds, ufds) tp_assign(nfds, nfds) tp_assign(tsp, tsp) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_preadv +SC_TRACE_EVENT(sys_preadv, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pwritev +SC_TRACE_EVENT(sys_pwritev, + TP_PROTO(unsigned long fd, const struct iovec * vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h), + TP_ARGS(fd, vec, vlen, pos_l, pos_h), + TP_STRUCT__entry(__field(unsigned long, fd) __field_hex(const struct iovec *, vec) __field(unsigned long, vlen) __field(unsigned long, pos_l) __field(unsigned long, pos_h)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(vec, vec) tp_assign(vlen, vlen) tp_assign(pos_l, pos_l) tp_assign(pos_h, pos_h)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_perf_event_open +SC_TRACE_EVENT(sys_perf_event_open, + TP_PROTO(struct perf_event_attr * attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags), + TP_ARGS(attr_uptr, pid, cpu, group_fd, flags), + TP_STRUCT__entry(__field_hex(struct perf_event_attr *, attr_uptr) __field(pid_t, pid) __field(int, cpu) __field(int, group_fd) __field(unsigned long, flags)), + TP_fast_assign(tp_assign(attr_uptr, attr_uptr) tp_assign(pid, pid) tp_assign(cpu, cpu) tp_assign(group_fd, group_fd) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvmmsg +SC_TRACE_EVENT(sys_recvmmsg, + TP_PROTO(int fd, struct mmsghdr * mmsg, unsigned int vlen, unsigned int flags, struct timespec * timeout), + TP_ARGS(fd, mmsg, vlen, flags, timeout), + TP_STRUCT__entry(__field(int, fd) __field_hex(struct mmsghdr *, mmsg) __field(unsigned int, vlen) __field(unsigned int, flags) __field_hex(struct timespec *, timeout)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(mmsg, mmsg) tp_assign(vlen, vlen) tp_assign(flags, flags) tp_assign(timeout, timeout)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_sendto +SC_TRACE_EVENT(sys_sendto, + TP_PROTO(int fd, void * buff, size_t len, unsigned flags, struct sockaddr * addr, int addr_len), + TP_ARGS(fd, buff, len, flags, addr, addr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(void *, buff) __field(size_t, len) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int, addr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(buff, buff) tp_assign(len, len) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_recvfrom +SC_TRACE_EVENT(sys_recvfrom, + TP_PROTO(int fd, void * ubuf, size_t size, unsigned flags, struct sockaddr * addr, int * addr_len), + TP_ARGS(fd, ubuf, size, flags, addr, addr_len), + TP_STRUCT__entry(__field(int, fd) __field_hex(void *, ubuf) __field(size_t, size) __field(unsigned, flags) __field_hex(struct sockaddr *, addr) __field_hex(int *, addr_len)), + TP_fast_assign(tp_assign(fd, fd) tp_assign(ubuf, ubuf) tp_assign(size, size) tp_assign(flags, flags) tp_assign(addr, addr) tp_assign(addr_len, addr_len)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_futex +SC_TRACE_EVENT(sys_futex, + TP_PROTO(u32 * uaddr, int op, u32 val, struct timespec * utime, u32 * uaddr2, u32 val3), + TP_ARGS(uaddr, op, val, utime, uaddr2, val3), + TP_STRUCT__entry(__field_hex(u32 *, uaddr) __field(int, op) __field(u32, val) __field_hex(struct timespec *, utime) __field_hex(u32 *, uaddr2) __field(u32, val3)), + TP_fast_assign(tp_assign(uaddr, uaddr) tp_assign(op, op) tp_assign(val, val) tp_assign(utime, utime) tp_assign(uaddr2, uaddr2) tp_assign(val3, val3)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_pselect6 +SC_TRACE_EVENT(sys_pselect6, + TP_PROTO(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timespec * tsp, void * sig), + TP_ARGS(n, inp, outp, exp, tsp, sig), + TP_STRUCT__entry(__field(int, n) __field_hex(fd_set *, inp) __field_hex(fd_set *, outp) __field_hex(fd_set *, exp) __field_hex(struct timespec *, tsp) __field_hex(void *, sig)), + TP_fast_assign(tp_assign(n, n) tp_assign(inp, inp) tp_assign(outp, outp) tp_assign(exp, exp) tp_assign(tsp, tsp) tp_assign(sig, sig)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_splice +SC_TRACE_EVENT(sys_splice, + TP_PROTO(int fd_in, loff_t * off_in, int fd_out, loff_t * off_out, size_t len, unsigned int flags), + TP_ARGS(fd_in, off_in, fd_out, off_out, len, flags), + TP_STRUCT__entry(__field(int, fd_in) __field_hex(loff_t *, off_in) __field(int, fd_out) __field_hex(loff_t *, off_out) __field(size_t, len) __field(unsigned int, flags)), + TP_fast_assign(tp_assign(fd_in, fd_in) tp_assign(off_in, off_in) tp_assign(fd_out, fd_out) tp_assign(off_out, off_out) tp_assign(len, len) tp_assign(flags, flags)), + TP_printk() +) +#endif +#ifndef OVERRIDE_64_sys_epoll_pwait +SC_TRACE_EVENT(sys_epoll_pwait, + TP_PROTO(int epfd, struct epoll_event * events, int maxevents, int timeout, const sigset_t * sigmask, size_t sigsetsize), + TP_ARGS(epfd, events, maxevents, timeout, sigmask, sigsetsize), + TP_STRUCT__entry(__field(int, epfd) __field_hex(struct epoll_event *, events) __field(int, maxevents) __field(int, timeout) __field_hex(const sigset_t *, sigmask) __field(size_t, sigsetsize)), + TP_fast_assign(tp_assign(epfd, epfd) tp_assign(events, events) tp_assign(maxevents, maxevents) tp_assign(timeout, timeout) tp_assign(sigmask, sigmask) tp_assign(sigsetsize, sigsetsize)), + TP_printk() +) +#endif + +#endif /* _TRACE_SYSCALLS_POINTERS_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" + +#else /* CREATE_SYSCALL_TABLE */ + +#include "x86-64-syscalls-3.0.4_pointers_override.h" +#include "syscalls_pointers_override.h" + +#ifndef OVERRIDE_TABLE_64_sys_read +TRACE_SYSCALL_TABLE(sys_read, sys_read, 0, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_write +TRACE_SYSCALL_TABLE(sys_write, sys_write, 1, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_open +TRACE_SYSCALL_TABLE(sys_open, sys_open, 2, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newstat +TRACE_SYSCALL_TABLE(sys_newstat, sys_newstat, 4, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newfstat +TRACE_SYSCALL_TABLE(sys_newfstat, sys_newfstat, 5, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newlstat +TRACE_SYSCALL_TABLE(sys_newlstat, sys_newlstat, 6, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_poll +TRACE_SYSCALL_TABLE(sys_poll, sys_poll, 7, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigaction +TRACE_SYSCALL_TABLE(sys_rt_sigaction, sys_rt_sigaction, 13, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigprocmask +TRACE_SYSCALL_TABLE(sys_rt_sigprocmask, sys_rt_sigprocmask, 14, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_readv +TRACE_SYSCALL_TABLE(sys_readv, sys_readv, 19, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_writev +TRACE_SYSCALL_TABLE(sys_writev, sys_writev, 20, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_access +TRACE_SYSCALL_TABLE(sys_access, sys_access, 21, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pipe +TRACE_SYSCALL_TABLE(sys_pipe, sys_pipe, 22, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_select +TRACE_SYSCALL_TABLE(sys_select, sys_select, 23, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mincore +TRACE_SYSCALL_TABLE(sys_mincore, sys_mincore, 27, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmat +TRACE_SYSCALL_TABLE(sys_shmat, sys_shmat, 30, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmctl +TRACE_SYSCALL_TABLE(sys_shmctl, sys_shmctl, 31, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_nanosleep +TRACE_SYSCALL_TABLE(sys_nanosleep, sys_nanosleep, 35, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getitimer +TRACE_SYSCALL_TABLE(sys_getitimer, sys_getitimer, 36, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setitimer +TRACE_SYSCALL_TABLE(sys_setitimer, sys_setitimer, 38, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendfile64 +TRACE_SYSCALL_TABLE(sys_sendfile64, sys_sendfile64, 40, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_connect +TRACE_SYSCALL_TABLE(sys_connect, sys_connect, 42, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_accept +TRACE_SYSCALL_TABLE(sys_accept, sys_accept, 43, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendto +TRACE_SYSCALL_TABLE(sys_sendto, sys_sendto, 44, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvfrom +TRACE_SYSCALL_TABLE(sys_recvfrom, sys_recvfrom, 45, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendmsg +TRACE_SYSCALL_TABLE(sys_sendmsg, sys_sendmsg, 46, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvmsg +TRACE_SYSCALL_TABLE(sys_recvmsg, sys_recvmsg, 47, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_bind +TRACE_SYSCALL_TABLE(sys_bind, sys_bind, 49, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsockname +TRACE_SYSCALL_TABLE(sys_getsockname, sys_getsockname, 51, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getpeername +TRACE_SYSCALL_TABLE(sys_getpeername, sys_getpeername, 52, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_socketpair +TRACE_SYSCALL_TABLE(sys_socketpair, sys_socketpair, 53, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setsockopt +TRACE_SYSCALL_TABLE(sys_setsockopt, sys_setsockopt, 54, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getsockopt +TRACE_SYSCALL_TABLE(sys_getsockopt, sys_getsockopt, 55, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_wait4 +TRACE_SYSCALL_TABLE(sys_wait4, sys_wait4, 61, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newuname +TRACE_SYSCALL_TABLE(sys_newuname, sys_newuname, 63, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semop +TRACE_SYSCALL_TABLE(sys_semop, sys_semop, 65, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_shmdt +TRACE_SYSCALL_TABLE(sys_shmdt, sys_shmdt, 67, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgsnd +TRACE_SYSCALL_TABLE(sys_msgsnd, sys_msgsnd, 69, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgrcv +TRACE_SYSCALL_TABLE(sys_msgrcv, sys_msgrcv, 70, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_msgctl +TRACE_SYSCALL_TABLE(sys_msgctl, sys_msgctl, 71, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_truncate +TRACE_SYSCALL_TABLE(sys_truncate, sys_truncate, 76, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getdents +TRACE_SYSCALL_TABLE(sys_getdents, sys_getdents, 78, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getcwd +TRACE_SYSCALL_TABLE(sys_getcwd, sys_getcwd, 79, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chdir +TRACE_SYSCALL_TABLE(sys_chdir, sys_chdir, 80, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rename +TRACE_SYSCALL_TABLE(sys_rename, sys_rename, 82, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mkdir +TRACE_SYSCALL_TABLE(sys_mkdir, sys_mkdir, 83, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rmdir +TRACE_SYSCALL_TABLE(sys_rmdir, sys_rmdir, 84, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_creat +TRACE_SYSCALL_TABLE(sys_creat, sys_creat, 85, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_link +TRACE_SYSCALL_TABLE(sys_link, sys_link, 86, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_unlink +TRACE_SYSCALL_TABLE(sys_unlink, sys_unlink, 87, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_symlink +TRACE_SYSCALL_TABLE(sys_symlink, sys_symlink, 88, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_readlink +TRACE_SYSCALL_TABLE(sys_readlink, sys_readlink, 89, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chmod +TRACE_SYSCALL_TABLE(sys_chmod, sys_chmod, 90, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chown +TRACE_SYSCALL_TABLE(sys_chown, sys_chown, 92, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lchown +TRACE_SYSCALL_TABLE(sys_lchown, sys_lchown, 94, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_gettimeofday +TRACE_SYSCALL_TABLE(sys_gettimeofday, sys_gettimeofday, 96, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getrlimit +TRACE_SYSCALL_TABLE(sys_getrlimit, sys_getrlimit, 97, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getrusage +TRACE_SYSCALL_TABLE(sys_getrusage, sys_getrusage, 98, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sysinfo +TRACE_SYSCALL_TABLE(sys_sysinfo, sys_sysinfo, 99, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_times +TRACE_SYSCALL_TABLE(sys_times, sys_times, 100, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_syslog +TRACE_SYSCALL_TABLE(sys_syslog, sys_syslog, 103, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getgroups +TRACE_SYSCALL_TABLE(sys_getgroups, sys_getgroups, 115, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setgroups +TRACE_SYSCALL_TABLE(sys_setgroups, sys_setgroups, 116, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getresuid +TRACE_SYSCALL_TABLE(sys_getresuid, sys_getresuid, 118, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getresgid +TRACE_SYSCALL_TABLE(sys_getresgid, sys_getresgid, 120, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigpending +TRACE_SYSCALL_TABLE(sys_rt_sigpending, sys_rt_sigpending, 127, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigtimedwait +TRACE_SYSCALL_TABLE(sys_rt_sigtimedwait, sys_rt_sigtimedwait, 128, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_sigqueueinfo, sys_rt_sigqueueinfo, 129, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_sigsuspend +TRACE_SYSCALL_TABLE(sys_rt_sigsuspend, sys_rt_sigsuspend, 130, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_utime +TRACE_SYSCALL_TABLE(sys_utime, sys_utime, 132, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mknod +TRACE_SYSCALL_TABLE(sys_mknod, sys_mknod, 133, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ustat +TRACE_SYSCALL_TABLE(sys_ustat, sys_ustat, 136, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_statfs +TRACE_SYSCALL_TABLE(sys_statfs, sys_statfs, 137, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fstatfs +TRACE_SYSCALL_TABLE(sys_fstatfs, sys_fstatfs, 138, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setparam +TRACE_SYSCALL_TABLE(sys_sched_setparam, sys_sched_setparam, 142, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getparam +TRACE_SYSCALL_TABLE(sys_sched_getparam, sys_sched_getparam, 143, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setscheduler +TRACE_SYSCALL_TABLE(sys_sched_setscheduler, sys_sched_setscheduler, 144, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_rr_get_interval +TRACE_SYSCALL_TABLE(sys_sched_rr_get_interval, sys_sched_rr_get_interval, 148, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pivot_root +TRACE_SYSCALL_TABLE(sys_pivot_root, sys_pivot_root, 155, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sysctl +TRACE_SYSCALL_TABLE(sys_sysctl, sys_sysctl, 156, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_adjtimex +TRACE_SYSCALL_TABLE(sys_adjtimex, sys_adjtimex, 159, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setrlimit +TRACE_SYSCALL_TABLE(sys_setrlimit, sys_setrlimit, 160, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_chroot +TRACE_SYSCALL_TABLE(sys_chroot, sys_chroot, 161, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_settimeofday +TRACE_SYSCALL_TABLE(sys_settimeofday, sys_settimeofday, 164, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mount +TRACE_SYSCALL_TABLE(sys_mount, sys_mount, 165, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_umount +TRACE_SYSCALL_TABLE(sys_umount, sys_umount, 166, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_swapon +TRACE_SYSCALL_TABLE(sys_swapon, sys_swapon, 167, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_swapoff +TRACE_SYSCALL_TABLE(sys_swapoff, sys_swapoff, 168, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_reboot +TRACE_SYSCALL_TABLE(sys_reboot, sys_reboot, 169, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sethostname +TRACE_SYSCALL_TABLE(sys_sethostname, sys_sethostname, 170, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setdomainname +TRACE_SYSCALL_TABLE(sys_setdomainname, sys_setdomainname, 171, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_init_module +TRACE_SYSCALL_TABLE(sys_init_module, sys_init_module, 175, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_delete_module +TRACE_SYSCALL_TABLE(sys_delete_module, sys_delete_module, 176, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_nfsservctl +TRACE_SYSCALL_TABLE(sys_nfsservctl, sys_nfsservctl, 180, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_setxattr +TRACE_SYSCALL_TABLE(sys_setxattr, sys_setxattr, 188, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lsetxattr +TRACE_SYSCALL_TABLE(sys_lsetxattr, sys_lsetxattr, 189, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fsetxattr +TRACE_SYSCALL_TABLE(sys_fsetxattr, sys_fsetxattr, 190, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getxattr +TRACE_SYSCALL_TABLE(sys_getxattr, sys_getxattr, 191, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lgetxattr +TRACE_SYSCALL_TABLE(sys_lgetxattr, sys_lgetxattr, 192, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fgetxattr +TRACE_SYSCALL_TABLE(sys_fgetxattr, sys_fgetxattr, 193, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_listxattr +TRACE_SYSCALL_TABLE(sys_listxattr, sys_listxattr, 194, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_llistxattr +TRACE_SYSCALL_TABLE(sys_llistxattr, sys_llistxattr, 195, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_flistxattr +TRACE_SYSCALL_TABLE(sys_flistxattr, sys_flistxattr, 196, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_removexattr +TRACE_SYSCALL_TABLE(sys_removexattr, sys_removexattr, 197, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_lremovexattr +TRACE_SYSCALL_TABLE(sys_lremovexattr, sys_lremovexattr, 198, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fremovexattr +TRACE_SYSCALL_TABLE(sys_fremovexattr, sys_fremovexattr, 199, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_time +TRACE_SYSCALL_TABLE(sys_time, sys_time, 201, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_futex +TRACE_SYSCALL_TABLE(sys_futex, sys_futex, 202, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_setaffinity +TRACE_SYSCALL_TABLE(sys_sched_setaffinity, sys_sched_setaffinity, 203, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sched_getaffinity +TRACE_SYSCALL_TABLE(sys_sched_getaffinity, sys_sched_getaffinity, 204, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_setup +TRACE_SYSCALL_TABLE(sys_io_setup, sys_io_setup, 206, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_getevents +TRACE_SYSCALL_TABLE(sys_io_getevents, sys_io_getevents, 208, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_submit +TRACE_SYSCALL_TABLE(sys_io_submit, sys_io_submit, 209, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_io_cancel +TRACE_SYSCALL_TABLE(sys_io_cancel, sys_io_cancel, 210, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_getdents64 +TRACE_SYSCALL_TABLE(sys_getdents64, sys_getdents64, 217, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_tid_address +TRACE_SYSCALL_TABLE(sys_set_tid_address, sys_set_tid_address, 218, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_semtimedop +TRACE_SYSCALL_TABLE(sys_semtimedop, sys_semtimedop, 220, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_create +TRACE_SYSCALL_TABLE(sys_timer_create, sys_timer_create, 222, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_settime +TRACE_SYSCALL_TABLE(sys_timer_settime, sys_timer_settime, 223, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timer_gettime +TRACE_SYSCALL_TABLE(sys_timer_gettime, sys_timer_gettime, 224, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_settime +TRACE_SYSCALL_TABLE(sys_clock_settime, sys_clock_settime, 227, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_gettime +TRACE_SYSCALL_TABLE(sys_clock_gettime, sys_clock_gettime, 228, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_getres +TRACE_SYSCALL_TABLE(sys_clock_getres, sys_clock_getres, 229, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_nanosleep +TRACE_SYSCALL_TABLE(sys_clock_nanosleep, sys_clock_nanosleep, 230, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_wait +TRACE_SYSCALL_TABLE(sys_epoll_wait, sys_epoll_wait, 232, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_ctl +TRACE_SYSCALL_TABLE(sys_epoll_ctl, sys_epoll_ctl, 233, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_utimes +TRACE_SYSCALL_TABLE(sys_utimes, sys_utimes, 235, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_open +TRACE_SYSCALL_TABLE(sys_mq_open, sys_mq_open, 240, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_unlink +TRACE_SYSCALL_TABLE(sys_mq_unlink, sys_mq_unlink, 241, 1) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_timedsend +TRACE_SYSCALL_TABLE(sys_mq_timedsend, sys_mq_timedsend, 242, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_timedreceive +TRACE_SYSCALL_TABLE(sys_mq_timedreceive, sys_mq_timedreceive, 243, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_notify +TRACE_SYSCALL_TABLE(sys_mq_notify, sys_mq_notify, 244, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mq_getsetattr +TRACE_SYSCALL_TABLE(sys_mq_getsetattr, sys_mq_getsetattr, 245, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_kexec_load +TRACE_SYSCALL_TABLE(sys_kexec_load, sys_kexec_load, 246, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_waitid +TRACE_SYSCALL_TABLE(sys_waitid, sys_waitid, 247, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_inotify_add_watch +TRACE_SYSCALL_TABLE(sys_inotify_add_watch, sys_inotify_add_watch, 254, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_openat +TRACE_SYSCALL_TABLE(sys_openat, sys_openat, 257, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mkdirat +TRACE_SYSCALL_TABLE(sys_mkdirat, sys_mkdirat, 258, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_mknodat +TRACE_SYSCALL_TABLE(sys_mknodat, sys_mknodat, 259, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchownat +TRACE_SYSCALL_TABLE(sys_fchownat, sys_fchownat, 260, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_futimesat +TRACE_SYSCALL_TABLE(sys_futimesat, sys_futimesat, 261, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_newfstatat +TRACE_SYSCALL_TABLE(sys_newfstatat, sys_newfstatat, 262, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_unlinkat +TRACE_SYSCALL_TABLE(sys_unlinkat, sys_unlinkat, 263, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_renameat +TRACE_SYSCALL_TABLE(sys_renameat, sys_renameat, 264, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_linkat +TRACE_SYSCALL_TABLE(sys_linkat, sys_linkat, 265, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_symlinkat +TRACE_SYSCALL_TABLE(sys_symlinkat, sys_symlinkat, 266, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_readlinkat +TRACE_SYSCALL_TABLE(sys_readlinkat, sys_readlinkat, 267, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_fchmodat +TRACE_SYSCALL_TABLE(sys_fchmodat, sys_fchmodat, 268, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_faccessat +TRACE_SYSCALL_TABLE(sys_faccessat, sys_faccessat, 269, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pselect6 +TRACE_SYSCALL_TABLE(sys_pselect6, sys_pselect6, 270, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_ppoll +TRACE_SYSCALL_TABLE(sys_ppoll, sys_ppoll, 271, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_set_robust_list +TRACE_SYSCALL_TABLE(sys_set_robust_list, sys_set_robust_list, 273, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_get_robust_list +TRACE_SYSCALL_TABLE(sys_get_robust_list, sys_get_robust_list, 274, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_splice +TRACE_SYSCALL_TABLE(sys_splice, sys_splice, 275, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_vmsplice +TRACE_SYSCALL_TABLE(sys_vmsplice, sys_vmsplice, 278, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_utimensat +TRACE_SYSCALL_TABLE(sys_utimensat, sys_utimensat, 280, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_epoll_pwait +TRACE_SYSCALL_TABLE(sys_epoll_pwait, sys_epoll_pwait, 281, 6) +#endif +#ifndef OVERRIDE_TABLE_64_sys_signalfd +TRACE_SYSCALL_TABLE(sys_signalfd, sys_signalfd, 282, 3) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_settime +TRACE_SYSCALL_TABLE(sys_timerfd_settime, sys_timerfd_settime, 286, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_timerfd_gettime +TRACE_SYSCALL_TABLE(sys_timerfd_gettime, sys_timerfd_gettime, 287, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_accept4 +TRACE_SYSCALL_TABLE(sys_accept4, sys_accept4, 288, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_signalfd4 +TRACE_SYSCALL_TABLE(sys_signalfd4, sys_signalfd4, 289, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pipe2 +TRACE_SYSCALL_TABLE(sys_pipe2, sys_pipe2, 293, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_preadv +TRACE_SYSCALL_TABLE(sys_preadv, sys_preadv, 295, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_pwritev +TRACE_SYSCALL_TABLE(sys_pwritev, sys_pwritev, 296, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_rt_tgsigqueueinfo +TRACE_SYSCALL_TABLE(sys_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, 297, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_perf_event_open +TRACE_SYSCALL_TABLE(sys_perf_event_open, sys_perf_event_open, 298, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_recvmmsg +TRACE_SYSCALL_TABLE(sys_recvmmsg, sys_recvmmsg, 299, 5) +#endif +#ifndef OVERRIDE_TABLE_64_sys_prlimit64 +TRACE_SYSCALL_TABLE(sys_prlimit64, sys_prlimit64, 302, 4) +#endif +#ifndef OVERRIDE_TABLE_64_sys_clock_adjtime +TRACE_SYSCALL_TABLE(sys_clock_adjtime, sys_clock_adjtime, 305, 2) +#endif +#ifndef OVERRIDE_TABLE_64_sys_sendmmsg +TRACE_SYSCALL_TABLE(sys_sendmmsg, sys_sendmmsg, 307, 4) +#endif + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h new file mode 100644 index 0000000..0cdb32a --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/headers/x86-64-syscalls-3.0.4_pointers_override.h @@ -0,0 +1,5 @@ +#ifndef CREATE_SYSCALL_TABLE + +#else /* CREATE_SYSCALL_TABLE */ + +#endif /* CREATE_SYSCALL_TABLE */ diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile new file mode 100644 index 0000000..4beb88c --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/Makefile @@ -0,0 +1 @@ +obj-m += lttng-syscalls-extractor.o diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c new file mode 100644 index 0000000..06c0da1 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c @@ -0,0 +1,85 @@ +/* + * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * Copyright 2011 - Julien Desfossez <julien.desfossez at polymtl.ca> + * + * Dump syscall metadata to console. + * + * GPLv2 license. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/list.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/kallsyms.h> +#include <linux/dcache.h> +#include <linux/ftrace_event.h> +#include <trace/syscall.h> + +#ifndef CONFIG_FTRACE_SYSCALLS +#error "You need to set CONFIG_FTRACE_SYSCALLS=y" +#endif + +#ifndef CONFIG_KALLSYMS_ALL +#error "You need to set CONFIG_KALLSYMS_ALL=y" +#endif + +static struct syscall_metadata **__start_syscalls_metadata; +static struct syscall_metadata **__stop_syscalls_metadata; + +static __init +struct syscall_metadata *find_syscall_meta(unsigned long syscall) +{ + struct syscall_metadata **iter; + + for (iter = __start_syscalls_metadata; + iter < __stop_syscalls_metadata; iter++) { + if ((*iter)->syscall_nr == syscall) + return (*iter); + } + return NULL; +} + +int init_module(void) +{ + struct syscall_metadata *meta; + int i; + + __start_syscalls_metadata = (void *) kallsyms_lookup_name("__start_syscalls_metadata"); + __stop_syscalls_metadata = (void *) kallsyms_lookup_name("__stop_syscalls_metadata"); + + for (i = 0; i < NR_syscalls; i++) { + int j; + + meta = find_syscall_meta(i); + if (!meta) + continue; + printk("syscall %s nr %d nbargs %d ", + meta->name, meta->syscall_nr, meta->nb_args); + printk("types: ("); + for (j = 0; j < meta->nb_args; j++) { + if (j > 0) + printk(", "); + printk("%s", meta->types[j]); + } + printk(") "); + printk("args: ("); + for (j = 0; j < meta->nb_args; j++) { + if (j > 0) + printk(", "); + printk("%s", meta->args[j]); + } + printk(")\n"); + } + printk("SUCCESS\n"); + + return -1; +} + +void cleanup_module(void) +{ +} + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh new file mode 100644 index 0000000..5eddb27 --- /dev/null +++ b/drivers/staging/lttng/instrumentation/syscalls/lttng-syscalls-generate-headers.sh @@ -0,0 +1,275 @@ +#!/bin/sh + +# Generate system call probe description macros from syscall metadata dump file. +# example usage: +# +# lttng-syscalls-generate-headers.sh integers 3.0.4 x86-64-syscalls-3.0.4 64 +# lttng-syscalls-generate-headers.sh pointers 3.0.4 x86-64-syscalls-3.0.4 64 + +CLASS=$1 +INPUTDIR=$2 +INPUTFILE=$3 +BITNESS=$4 +INPUT=${INPUTDIR}/${INPUTFILE} +SRCFILE=gen.tmp.0 +TMPFILE=gen.tmp.1 +HEADER=headers/${INPUTFILE}_${CLASS}.h + +cp ${INPUT} ${SRCFILE} + +#Cleanup +perl -p -e 's/^\[.*\] //g' ${SRCFILE} > ${TMPFILE} +mv ${TMPFILE} ${SRCFILE} + +perl -p -e 's/^syscall sys_([^ ]*)/syscall $1/g' ${SRCFILE} > ${TMPFILE} +mv ${TMPFILE} ${SRCFILE} + +#Filter + +if [ "$CLASS" = integers ]; then + #select integers and no-args. + CLASSCAP=INTEGERS + grep -v "\\*\|cap_user_header_t" ${SRCFILE} > ${TMPFILE} + mv ${TMPFILE} ${SRCFILE} +fi + + +if [ "$CLASS" = pointers ]; then + #select system calls using pointers. + CLASSCAP=POINTERS + grep "\\*\|cap_#user_header_t" ${SRCFILE} > ${TMPFILE} + mv ${TMPFILE} ${SRCFILE} +fi + +echo "/* THIS FILE IS AUTO-GENERATED. DO NOT EDIT */" > ${HEADER} + +echo \ +"#ifndef CREATE_SYSCALL_TABLE + +#if !defined(_TRACE_SYSCALLS_${CLASSCAP}_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SYSCALLS_${CLASSCAP}_H + +#include <linux/tracepoint.h> +#include <linux/syscalls.h> +#include \"${INPUTFILE}_${CLASS}_override.h\" +#include \"syscalls_${CLASS}_override.h\" +" >> ${HEADER} + +if [ "$CLASS" = integers ]; then + +NRARGS=0 + +echo \ +'SC_DECLARE_EVENT_CLASS_NOARGS(syscalls_noargs,\n'\ +' TP_STRUCT__entry(),\n'\ +' TP_fast_assign(),\n'\ +' TP_printk()\n'\ +')'\ + >> ${HEADER} + +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^)]*)\) '\ +'args: \(([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_DEFINE_EVENT_NOARGS(syscalls_noargs, sys_$1)\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +fi + + +# types: 4 +# args 5 + +NRARGS=1 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^)]*)\) '\ +'args: \(([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $5),\n'\ +' TP_ARGS($5),\n'\ +' TP_STRUCT__entry(__field($4, $5)),\n'\ +' TP_fast_assign(tp_assign($4, $5, $5)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +# types: 4 5 +# args 6 7 + +NRARGS=2 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^,]*), ([^)]*)\) '\ +'args: \(([^,]*), ([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $6, $5 $7),\n'\ +' TP_ARGS($6, $7),\n'\ +' TP_STRUCT__entry(__field($4, $6) __field($5, $7)),\n'\ +' TP_fast_assign(tp_assign($4, $6, $6) tp_assign($5, $7, $7)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +# types: 4 5 6 +# args 7 8 9 + +NRARGS=3 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^,]*), ([^,]*), ([^)]*)\) '\ +'args: \(([^,]*), ([^,]*), ([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $7, $5 $8, $6 $9),\n'\ +' TP_ARGS($7, $8, $9),\n'\ +' TP_STRUCT__entry(__field($4, $7) __field($5, $8) __field($6, $9)),\n'\ +' TP_fast_assign(tp_assign($4, $7, $7) tp_assign($5, $8, $8) tp_assign($6, $9, $9)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + + +# types: 4 5 6 7 +# args 8 9 10 11 + +NRARGS=4 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^,]*), ([^,]*), ([^,]*), ([^)]*)\) '\ +'args: \(([^,]*), ([^,]*), ([^,]*), ([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $8, $5 $9, $6 $10, $7 $11),\n'\ +' TP_ARGS($8, $9, $10, $11),\n'\ +' TP_STRUCT__entry(__field($4, $8) __field($5, $9) __field($6, $10) __field($7, $11)),\n'\ +' TP_fast_assign(tp_assign($4, $8, $8) tp_assign($5, $9, $9) tp_assign($6, $10, $10) tp_assign($7, $11, $11)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +# types: 4 5 6 7 8 +# args 9 10 11 12 13 + +NRARGS=5 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^)]*)\) '\ +'args: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $9, $5 $10, $6 $11, $7 $12, $8 $13),\n'\ +' TP_ARGS($9, $10, $11, $12, $13),\n'\ +' TP_STRUCT__entry(__field($4, $9) __field($5, $10) __field($6, $11) __field($7, $12) __field($8, $13)),\n'\ +' TP_fast_assign(tp_assign($4, $9, $9) tp_assign($5, $10, $10) tp_assign($6, $11, $11) tp_assign($7, $12, $12) tp_assign($8, $13, $13)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + + +# types: 4 5 6 7 8 9 +# args 10 11 12 13 14 15 + +NRARGS=6 +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) '\ +'types: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^\)]*)\) '\ +'args: \(([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^\)]*)\)/'\ +'#ifndef OVERRIDE_'"${BITNESS}"'_sys_$1\n'\ +'SC_TRACE_EVENT(sys_$1,\n'\ +' TP_PROTO($4 $10, $5 $11, $6 $12, $7 $13, $8 $14, $9 $15),\n'\ +' TP_ARGS($10, $11, $12, $13, $14, $15),\n'\ +' TP_STRUCT__entry(__field($4, $10) __field($5, $11) __field($6, $12) __field($7, $13) __field($8, $14) __field($9, $15)),\n'\ +' TP_fast_assign(tp_assign($4, $10, $10) tp_assign($5, $11, $11) tp_assign($6, $12, $12) tp_assign($7, $13, $13) tp_assign($8, $14, $14) tp_assign($9, $15, $15)),\n'\ +' TP_printk()\n'\ +')\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +# Macro for tracing syscall table + +rm -f ${TMPFILE} +for NRARGS in $(seq 0 6); do + grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} >> ${TMPFILE} +done + +echo \ +" +#endif /* _TRACE_SYSCALLS_${CLASSCAP}_H */ + +/* This part must be outside protection */ +#include \"../../../probes/define_trace.h\" + +#else /* CREATE_SYSCALL_TABLE */ + +#include \"${INPUTFILE}_${CLASS}_override.h\" +#include \"syscalls_${CLASS}_override.h\" +" >> ${HEADER} + +NRARGS=0 + +if [ "$CLASS" = integers ]; then +#noargs +grep "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) .*$/'\ +'#ifndef OVERRIDE_TABLE_'"${BITNESS}"'_sys_$1\n'\ +'TRACE_SYSCALL_TABLE\(syscalls_noargs, sys_$1, $2, $3\)\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} +fi + +#others. +grep -v "^syscall [^ ]* nr [^ ]* nbargs ${NRARGS} " ${SRCFILE} > ${TMPFILE} +perl -p -e 's/^syscall ([^ ]*) nr ([^ ]*) nbargs ([^ ]*) .*$/'\ +'#ifndef OVERRIDE_TABLE_'"${BITNESS}"'_sys_$1\n'\ +'TRACE_SYSCALL_TABLE(sys_$1, sys_$1, $2, $3)\n'\ +'#endif/g'\ + ${TMPFILE} >> ${HEADER} + +echo -n \ +" +#endif /* CREATE_SYSCALL_TABLE */ +" >> ${HEADER} + +#fields names: ...char * type with *name* or *file* or *path* or *root* +# or *put_old* or *type* +cp -f ${HEADER} ${TMPFILE} +rm -f ${HEADER} +perl -p -e 's/__field\(([^,)]*char \*), ([^\)]*)(name|file|path|root|put_old|type)([^\)]*)\)/__string_from_user($2$3$4, $2$3$4)/g'\ + ${TMPFILE} >> ${HEADER} +cp -f ${HEADER} ${TMPFILE} +rm -f ${HEADER} +perl -p -e 's/tp_assign\(([^,)]*char \*), ([^,]*)(name|file|path|root|put_old|type)([^,]*), ([^\)]*)\)/tp_copy_string_from_user($2$3$4, $5)/g'\ + ${TMPFILE} >> ${HEADER} + +#prettify addresses heuristics. +#field names with addr or ptr +cp -f ${HEADER} ${TMPFILE} +rm -f ${HEADER} +perl -p -e 's/__field\(([^,)]*), ([^,)]*addr|[^,)]*ptr)([^),]*)\)/__field_hex($1, $2$3)/g'\ + ${TMPFILE} >> ${HEADER} + +#field types ending with '*' +cp -f ${HEADER} ${TMPFILE} +rm -f ${HEADER} +perl -p -e 's/__field\(([^,)]*\*), ([^),]*)\)/__field_hex($1, $2)/g'\ + ${TMPFILE} >> ${HEADER} + +#strip the extra type information from tp_assign. +cp -f ${HEADER} ${TMPFILE} +rm -f ${HEADER} +perl -p -e 's/tp_assign\(([^,)]*), ([^,]*), ([^\)]*)\)/tp_assign($2, $3)/g'\ + ${TMPFILE} >> ${HEADER} + +rm -f ${INPUTFILE}.tmp +rm -f ${TMPFILE} +rm -f ${SRCFILE} -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 10/20] lttng: lib ring buffer clients 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (8 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 09/20] lttng: syscall instrumentation Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 11/20] lttng: tracer control and core structures Mathieu Desnoyers ` (10 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Each lttng buffer configuration (discard mode, overwrite mode, mmap support, splice support, per-cpu buffers, global buffer for metadata) is a lib ring buffer client. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- .../staging/lttng/ltt-ring-buffer-client-discard.c | 21 + .../lttng/ltt-ring-buffer-client-mmap-discard.c | 21 + .../lttng/ltt-ring-buffer-client-mmap-overwrite.c | 21 + .../lttng/ltt-ring-buffer-client-overwrite.c | 21 + drivers/staging/lttng/ltt-ring-buffer-client.h | 569 ++++++++++++++++++++ .../lttng/ltt-ring-buffer-metadata-client.c | 21 + .../lttng/ltt-ring-buffer-metadata-client.h | 330 ++++++++++++ .../lttng/ltt-ring-buffer-metadata-mmap-client.c | 21 + 8 files changed, 1025 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-discard.c create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c create mode 100644 drivers/staging/lttng/ltt-ring-buffer-client.h create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-client.c create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-client.h create mode 100644 drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-discard.c b/drivers/staging/lttng/ltt-ring-buffer-client-discard.c new file mode 100644 index 0000000..eafcf45 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-client-discard.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-client-discard.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client (discard mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "discard" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "ltt-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c new file mode 100644 index 0000000..29819a7 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-discard.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-client-discard.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client (discard mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "discard-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "ltt-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Discard Mode"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c new file mode 100644 index 0000000..741aa7b --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-client-mmap-overwrite.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-client-overwrite.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client (overwrite mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE +#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "ltt-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c b/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c new file mode 100644 index 0000000..9811941 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-client-overwrite.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-client-overwrite.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client (overwrite mode). + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_OVERWRITE +#define RING_BUFFER_MODE_TEMPLATE_STRING "overwrite" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "ltt-ring-buffer-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Client Overwrite Mode"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-client.h b/drivers/staging/lttng/ltt-ring-buffer-client.h new file mode 100644 index 0000000..8df3790 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-client.h @@ -0,0 +1,569 @@ +/* + * ltt-ring-buffer-client.h + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client template. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include "lib/bitfield.h" +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "wrapper/trace-clock.h" +#include "ltt-events.h" +#include "ltt-tracer.h" +#include "wrapper/ringbuffer/frontend_types.h" + +/* + * Keep the natural field alignment for _each field_ within this structure if + * you ever add/remove a field from this header. Packed attribute is not used + * because gcc generates poor code on at least powerpc and mips. Don't ever + * let gcc add padding between the structure elements. + * + * The guarantee we have with timestamps is that all the events in a + * packet are included (inclusive) within the begin/end timestamps of + * the packet. Another guarantee we have is that the "timestamp begin", + * as well as the event timestamps, are monotonically increasing (never + * decrease) when moving forward in a stream (physically). But this + * guarantee does not apply to "timestamp end", because it is sampled at + * commit time, which is not ordered with respect to space reservation. + */ + +struct packet_header { + /* Trace packet header */ + uint32_t magic; /* + * Trace magic number. + * contains endianness information. + */ + uint8_t uuid[16]; + uint32_t stream_id; + + struct { + /* Stream packet context */ + uint64_t timestamp_begin; /* Cycle count at subbuffer start */ + uint64_t timestamp_end; /* Cycle count at subbuffer end */ + uint32_t events_discarded; /* + * Events lost in this subbuffer since + * the beginning of the trace. + * (may overflow) + */ + uint32_t content_size; /* Size of data in subbuffer */ + uint32_t packet_size; /* Subbuffer size (include padding) */ + uint32_t cpu_id; /* CPU id associated with stream */ + uint8_t header_end; /* End of header */ + } ctx; +}; + + +static inline notrace u64 lib_ring_buffer_clock_read(struct channel *chan) +{ + return trace_clock_read64(); +} + +static inline +size_t ctx_get_size(size_t offset, struct lttng_ctx *ctx) +{ + int i; + size_t orig_offset = offset; + + if (likely(!ctx)) + return 0; + for (i = 0; i < ctx->nr_fields; i++) + offset += ctx->fields[i].get_size(offset); + return offset - orig_offset; +} + +static inline +void ctx_record(struct lib_ring_buffer_ctx *bufctx, + struct ltt_channel *chan, + struct lttng_ctx *ctx) +{ + int i; + + if (likely(!ctx)) + return; + for (i = 0; i < ctx->nr_fields; i++) + ctx->fields[i].record(&ctx->fields[i], bufctx, chan); +} + +/* + * record_header_size - Calculate the header size and padding necessary. + * @config: ring buffer instance configuration + * @chan: channel + * @offset: offset in the write buffer + * @pre_header_padding: padding to add before the header (output) + * @ctx: reservation context + * + * Returns the event header size (including padding). + * + * The payload must itself determine its own alignment from the biggest type it + * contains. + */ +static __inline__ +unsigned char record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + struct ltt_channel *ltt_chan = channel_get_private(chan); + struct ltt_event *event = ctx->priv; + size_t orig_offset = offset; + size_t padding; + + switch (ltt_chan->header_type) { + case 1: /* compact */ + padding = lib_ring_buffer_align(offset, ltt_alignof(uint32_t)); + offset += padding; + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { + offset += sizeof(uint32_t); /* id and timestamp */ + } else { + /* Minimum space taken by 5-bit id */ + offset += sizeof(uint8_t); + /* Align extended struct on largest member */ + offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + offset += sizeof(uint32_t); /* id */ + offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + offset += sizeof(uint64_t); /* timestamp */ + } + break; + case 2: /* large */ + padding = lib_ring_buffer_align(offset, ltt_alignof(uint16_t)); + offset += padding; + offset += sizeof(uint16_t); + if (!(ctx->rflags & (RING_BUFFER_RFLAG_FULL_TSC | LTT_RFLAG_EXTENDED))) { + offset += lib_ring_buffer_align(offset, ltt_alignof(uint32_t)); + offset += sizeof(uint32_t); /* timestamp */ + } else { + /* Align extended struct on largest member */ + offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + offset += sizeof(uint32_t); /* id */ + offset += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + offset += sizeof(uint64_t); /* timestamp */ + } + break; + default: + padding = 0; + WARN_ON_ONCE(1); + } + offset += ctx_get_size(offset, event->ctx); + offset += ctx_get_size(offset, ltt_chan->ctx); + + *pre_header_padding = padding; + return offset - orig_offset; +} + +#include "wrapper/ringbuffer/api.h" + +static +void ltt_write_event_header_slow(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + uint32_t event_id); + +/* + * ltt_write_event_header + * + * Writes the event header to the offset (already aligned on 32-bits). + * + * @config: ring buffer instance configuration + * @ctx: reservation context + * @event_id: event ID + */ +static __inline__ +void ltt_write_event_header(const struct lib_ring_buffer_config *config, + struct lib_ring_buffer_ctx *ctx, + uint32_t event_id) +{ + struct ltt_channel *ltt_chan = channel_get_private(ctx->chan); + struct ltt_event *event = ctx->priv; + + if (unlikely(ctx->rflags)) + goto slow_path; + + switch (ltt_chan->header_type) { + case 1: /* compact */ + { + uint32_t id_time = 0; + + bt_bitfield_write(&id_time, uint32_t, 0, 5, event_id); + bt_bitfield_write(&id_time, uint32_t, 5, 27, ctx->tsc); + lib_ring_buffer_write(config, ctx, &id_time, sizeof(id_time)); + break; + } + case 2: /* large */ + { + uint32_t timestamp = (uint32_t) ctx->tsc; + uint16_t id = event_id; + + lib_ring_buffer_write(config, ctx, &id, sizeof(id)); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(uint32_t)); + lib_ring_buffer_write(config, ctx, ×tamp, 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, ×tamp, 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, ×tamp, 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, ×tamp, 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(<t_relay_transport); + return 0; +} + +module_init(ltt_ring_buffer_client_init); + +static void __exit ltt_ring_buffer_client_exit(void) +{ + ltt_transport_unregister(<t_relay_transport); +} + +module_exit(ltt_ring_buffer_client_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING + " client"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c new file mode 100644 index 0000000..ac6fe78 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-metadata-client.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer metadta client. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_SPLICE +#include "ltt-ring-buffer-metadata-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h new file mode 100644 index 0000000..529bbb1 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-client.h @@ -0,0 +1,330 @@ +/* + * ltt-ring-buffer-client.h + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer client template. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "ltt-events.h" +#include "ltt-tracer.h" + +struct metadata_packet_header { + uint32_t magic; /* 0x75D11D57 */ + uint8_t uuid[16]; /* Unique Universal Identifier */ + uint32_t checksum; /* 0 if unused */ + uint32_t content_size; /* in bits */ + uint32_t packet_size; /* in bits */ + uint8_t compression_scheme; /* 0 if unused */ + uint8_t encryption_scheme; /* 0 if unused */ + uint8_t checksum_scheme; /* 0 if unused */ + uint8_t major; /* CTF spec major version number */ + uint8_t minor; /* CTF spec minor version number */ + uint8_t header_end[0]; +}; + +struct metadata_record_header { + uint8_t header_end[0]; /* End of header */ +}; + +static const struct lib_ring_buffer_config client_config; + +static inline +u64 lib_ring_buffer_clock_read(struct channel *chan) +{ + return 0; +} + +static inline +unsigned char record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + return 0; +} + +#include "wrapper/ringbuffer/api.h" + +static u64 client_ring_buffer_clock_read(struct channel *chan) +{ + return 0; +} + +static +size_t client_record_header_size(const struct lib_ring_buffer_config *config, + struct channel *chan, size_t offset, + size_t *pre_header_padding, + struct lib_ring_buffer_ctx *ctx) +{ + return 0; +} + +/** + * client_packet_header_size - called on buffer-switch to a new sub-buffer + * + * Return header size without padding after the structure. Don't use packed + * structure because gcc generates inefficient code on some architectures + * (powerpc, mips..) + */ +static size_t client_packet_header_size(void) +{ + return offsetof(struct metadata_packet_header, header_end); +} + +static void client_buffer_begin(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx) +{ + struct channel *chan = buf->backend.chan; + struct metadata_packet_header *header = + (struct metadata_packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + struct ltt_channel *ltt_chan = channel_get_private(chan); + struct ltt_session *session = ltt_chan->session; + + header->magic = TSDL_MAGIC_NUMBER; + memcpy(header->uuid, session->uuid.b, sizeof(session->uuid)); + header->checksum = 0; /* 0 if unused */ + header->content_size = 0xFFFFFFFF; /* in bits, for debugging */ + header->packet_size = 0xFFFFFFFF; /* in bits, for debugging */ + header->compression_scheme = 0; /* 0 if unused */ + header->encryption_scheme = 0; /* 0 if unused */ + header->checksum_scheme = 0; /* 0 if unused */ + header->major = CTF_SPEC_MAJOR; + header->minor = CTF_SPEC_MINOR; +} + +/* + * offset is assumed to never be 0 here : never deliver a completely empty + * subbuffer. data_size is between 1 and subbuf_size. + */ +static void client_buffer_end(struct lib_ring_buffer *buf, u64 tsc, + unsigned int subbuf_idx, unsigned long data_size) +{ + struct channel *chan = buf->backend.chan; + struct metadata_packet_header *header = + (struct metadata_packet_header *) + lib_ring_buffer_offset_address(&buf->backend, + subbuf_idx * chan->backend.subbuf_size); + unsigned long records_lost = 0; + + header->content_size = data_size * CHAR_BIT; /* in bits */ + header->packet_size = PAGE_ALIGN(data_size) * CHAR_BIT; /* in bits */ + /* + * We do not care about the records lost count, because the metadata + * channel waits and retry. + */ + (void) lib_ring_buffer_get_records_lost_full(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_wrap(&client_config, buf); + records_lost += lib_ring_buffer_get_records_lost_big(&client_config, buf); + WARN_ON_ONCE(records_lost != 0); +} + +static int client_buffer_create(struct lib_ring_buffer *buf, void *priv, + int cpu, const char *name) +{ + return 0; +} + +static void client_buffer_finalize(struct lib_ring_buffer *buf, void *priv, int cpu) +{ +} + +static const struct lib_ring_buffer_config client_config = { + .cb.ring_buffer_clock_read = client_ring_buffer_clock_read, + .cb.record_header_size = client_record_header_size, + .cb.subbuffer_header_size = client_packet_header_size, + .cb.buffer_begin = client_buffer_begin, + .cb.buffer_end = client_buffer_end, + .cb.buffer_create = client_buffer_create, + .cb.buffer_finalize = client_buffer_finalize, + + .tsc_bits = 0, + .alloc = RING_BUFFER_ALLOC_GLOBAL, + .sync = RING_BUFFER_SYNC_GLOBAL, + .mode = RING_BUFFER_MODE_TEMPLATE, + .backend = RING_BUFFER_PAGE, + .output = RING_BUFFER_OUTPUT_TEMPLATE, + .oops = RING_BUFFER_OOPS_CONSISTENCY, + .ipi = RING_BUFFER_IPI_BARRIER, + .wakeup = RING_BUFFER_WAKEUP_BY_TIMER, +}; + +static +struct channel *_channel_create(const char *name, + struct ltt_channel *ltt_chan, void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval) +{ + return channel_create(&client_config, name, ltt_chan, buf_addr, + subbuf_size, num_subbuf, switch_timer_interval, + read_timer_interval); +} + +static +void ltt_channel_destroy(struct channel *chan) +{ + channel_destroy(chan); +} + +static +struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan) +{ + struct lib_ring_buffer *buf; + + buf = channel_get_ring_buffer(&client_config, chan, 0); + if (!lib_ring_buffer_open_read(buf)) + return buf; + return NULL; +} + +static +int ltt_buffer_has_read_closed_stream(struct channel *chan) +{ + struct lib_ring_buffer *buf; + int cpu; + + for_each_channel_cpu(cpu, chan) { + buf = channel_get_ring_buffer(&client_config, chan, cpu); + if (!atomic_long_read(&buf->active_readers)) + return 1; + } + return 0; +} + +static +void ltt_buffer_read_close(struct lib_ring_buffer *buf) +{ + lib_ring_buffer_release_read(buf); +} + +static +int ltt_event_reserve(struct lib_ring_buffer_ctx *ctx, uint32_t event_id) +{ + return lib_ring_buffer_reserve(&client_config, ctx); +} + +static +void ltt_event_commit(struct lib_ring_buffer_ctx *ctx) +{ + lib_ring_buffer_commit(&client_config, ctx); +} + +static +void ltt_event_write(struct lib_ring_buffer_ctx *ctx, const void *src, + size_t len) +{ + lib_ring_buffer_write(&client_config, ctx, src, len); +} + +static +void ltt_event_write_from_user(struct lib_ring_buffer_ctx *ctx, + const void __user *src, size_t len) +{ + lib_ring_buffer_copy_from_user(&client_config, ctx, src, len); +} + +static +void ltt_event_memset(struct lib_ring_buffer_ctx *ctx, + int c, size_t len) +{ + lib_ring_buffer_memset(&client_config, ctx, c, len); +} + +static +size_t ltt_packet_avail_size(struct channel *chan) + +{ + unsigned long o_begin; + struct lib_ring_buffer *buf; + + buf = chan->backend.buf; /* Only for global buffer ! */ + o_begin = v_read(&client_config, &buf->offset); + if (subbuf_offset(o_begin, chan) != 0) { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan); + } else { + return chan->backend.subbuf_size - subbuf_offset(o_begin, chan) + - sizeof(struct metadata_packet_header); + } +} + +static +wait_queue_head_t *ltt_get_writer_buf_wait_queue(struct channel *chan, int cpu) +{ + struct lib_ring_buffer *buf = channel_get_ring_buffer(&client_config, + chan, cpu); + return &buf->write_wait; +} + +static +wait_queue_head_t *ltt_get_hp_wait_queue(struct channel *chan) +{ + return &chan->hp_wait; +} + +static +int ltt_is_finalized(struct channel *chan) +{ + return lib_ring_buffer_channel_is_finalized(chan); +} + +static +int ltt_is_disabled(struct channel *chan) +{ + return lib_ring_buffer_channel_is_disabled(chan); +} + +static struct ltt_transport ltt_relay_transport = { + .name = "relay-" RING_BUFFER_MODE_TEMPLATE_STRING, + .owner = THIS_MODULE, + .ops = { + .channel_create = _channel_create, + .channel_destroy = ltt_channel_destroy, + .buffer_read_open = ltt_buffer_read_open, + .buffer_has_read_closed_stream = + ltt_buffer_has_read_closed_stream, + .buffer_read_close = ltt_buffer_read_close, + .event_reserve = ltt_event_reserve, + .event_commit = ltt_event_commit, + .event_write_from_user = ltt_event_write_from_user, + .event_memset = ltt_event_memset, + .event_write = ltt_event_write, + .packet_avail_size = ltt_packet_avail_size, + .get_writer_buf_wait_queue = ltt_get_writer_buf_wait_queue, + .get_hp_wait_queue = ltt_get_hp_wait_queue, + .is_finalized = ltt_is_finalized, + .is_disabled = ltt_is_disabled, + }, +}; + +static int __init ltt_ring_buffer_client_init(void) +{ + /* + * This vmalloc sync all also takes care of the lib ring buffer + * vmalloc'd module pages when it is built as a module into LTTng. + */ + wrapper_vmalloc_sync_all(); + ltt_transport_register(<t_relay_transport); + return 0; +} + +module_init(ltt_ring_buffer_client_init); + +static void __exit ltt_ring_buffer_client_exit(void) +{ + ltt_transport_unregister(<t_relay_transport); +} + +module_exit(ltt_ring_buffer_client_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng ring buffer " RING_BUFFER_MODE_TEMPLATE_STRING + " client"); diff --git a/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c b/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c new file mode 100644 index 0000000..5cad3f9 --- /dev/null +++ b/drivers/staging/lttng/ltt-ring-buffer-metadata-mmap-client.c @@ -0,0 +1,21 @@ +/* + * ltt-ring-buffer-metadata-client.c + * + * Copyright (C) 2010 - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng lib ring buffer metadta client. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include "ltt-tracer.h" + +#define RING_BUFFER_MODE_TEMPLATE RING_BUFFER_DISCARD +#define RING_BUFFER_MODE_TEMPLATE_STRING "metadata-mmap" +#define RING_BUFFER_OUTPUT_TEMPLATE RING_BUFFER_MMAP +#include "ltt-ring-buffer-metadata-client.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("LTTng Ring Buffer Metadata Client"); -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 11/20] lttng: tracer control and core structures 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (9 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 10/20] lttng: lib ring buffer clients Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 12/20] lttng: dynamically selectable context information Mathieu Desnoyers ` (9 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/ltt-endian.h | 31 + drivers/staging/lttng/ltt-events.c | 1009 +++++++++++++++++++++++++++++++ drivers/staging/lttng/ltt-events.h | 452 ++++++++++++++ drivers/staging/lttng/ltt-probes.c | 164 +++++ drivers/staging/lttng/ltt-tracer-core.h | 28 + drivers/staging/lttng/ltt-tracer.h | 67 ++ 6 files changed, 1751 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/ltt-endian.h create mode 100644 drivers/staging/lttng/ltt-events.c create mode 100644 drivers/staging/lttng/ltt-events.h create mode 100644 drivers/staging/lttng/ltt-probes.c create mode 100644 drivers/staging/lttng/ltt-tracer-core.h create mode 100644 drivers/staging/lttng/ltt-tracer.h diff --git a/drivers/staging/lttng/ltt-endian.h b/drivers/staging/lttng/ltt-endian.h new file mode 100644 index 0000000..9a0512d --- /dev/null +++ b/drivers/staging/lttng/ltt-endian.h @@ -0,0 +1,31 @@ +#ifndef _LTT_ENDIAN_H +#define _LTT_ENDIAN_H + +/* + * ltt-endian.h + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#ifdef __KERNEL__ +# include <asm/byteorder.h> +# ifdef __BIG_ENDIAN +# define __BYTE_ORDER __BIG_ENDIAN +# elif defined(__LITTLE_ENDIAN) +# define __BYTE_ORDER __LITTLE_ENDIAN +# else +# error "unknown endianness" +# endif +#ifndef __BIG_ENDIAN +# define __BIG_ENDIAN 4321 +#endif +#ifndef __LITTLE_ENDIAN +# define __LITTLE_ENDIAN 1234 +#endif +#else +# include <endian.h> +#endif + +#endif /* _LTT_ENDIAN_H */ diff --git a/drivers/staging/lttng/ltt-events.c b/drivers/staging/lttng/ltt-events.c new file mode 100644 index 0000000..4229914 --- /dev/null +++ b/drivers/staging/lttng/ltt-events.c @@ -0,0 +1,1009 @@ +/* + * ltt-events.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Holds LTTng per-session event registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include "wrapper/uuid.h" +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "ltt-events.h" +#include "ltt-tracer.h" + +static LIST_HEAD(sessions); +static LIST_HEAD(ltt_transport_list); +static DEFINE_MUTEX(sessions_mutex); +static struct kmem_cache *event_cache; + +static void _ltt_event_destroy(struct ltt_event *event); +static void _ltt_channel_destroy(struct ltt_channel *chan); +static int _ltt_event_unregister(struct ltt_event *event); +static +int _ltt_event_metadata_statedump(struct ltt_session *session, + struct ltt_channel *chan, + struct ltt_event *event); +static +int _ltt_session_metadata_statedump(struct ltt_session *session); + +void synchronize_trace(void) +{ + synchronize_sched(); +#ifdef CONFIG_PREEMPT_RT + synchronize_rcu(); +#endif +} + +struct ltt_session *ltt_session_create(void) +{ + struct ltt_session *session; + + mutex_lock(&sessions_mutex); + session = kzalloc(sizeof(struct ltt_session), GFP_KERNEL); + if (!session) + return NULL; + INIT_LIST_HEAD(&session->chan); + INIT_LIST_HEAD(&session->events); + uuid_le_gen(&session->uuid); + list_add(&session->list, &sessions); + mutex_unlock(&sessions_mutex); + return session; +} + +void ltt_session_destroy(struct ltt_session *session) +{ + struct ltt_channel *chan, *tmpchan; + struct ltt_event *event, *tmpevent; + int ret; + + mutex_lock(&sessions_mutex); + ACCESS_ONCE(session->active) = 0; + list_for_each_entry(chan, &session->chan, list) { + ret = lttng_syscalls_unregister(chan); + WARN_ON(ret); + } + list_for_each_entry(event, &session->events, list) { + ret = _ltt_event_unregister(event); + WARN_ON(ret); + } + synchronize_trace(); /* Wait for in-flight events to complete */ + list_for_each_entry_safe(event, tmpevent, &session->events, list) + _ltt_event_destroy(event); + list_for_each_entry_safe(chan, tmpchan, &session->chan, list) + _ltt_channel_destroy(chan); + list_del(&session->list); + mutex_unlock(&sessions_mutex); + kfree(session); +} + +int ltt_session_enable(struct ltt_session *session) +{ + int ret = 0; + struct ltt_channel *chan; + + mutex_lock(&sessions_mutex); + if (session->active) { + ret = -EBUSY; + goto end; + } + + /* + * Snapshot the number of events per channel to know the type of header + * we need to use. + */ + list_for_each_entry(chan, &session->chan, list) { + if (chan->header_type) + continue; /* don't change it if session stop/restart */ + if (chan->free_event_id < 31) + chan->header_type = 1; /* compact */ + else + chan->header_type = 2; /* large */ + } + + ACCESS_ONCE(session->active) = 1; + ACCESS_ONCE(session->been_active) = 1; + ret = _ltt_session_metadata_statedump(session); + if (ret) + ACCESS_ONCE(session->active) = 0; +end: + mutex_unlock(&sessions_mutex); + return ret; +} + +int ltt_session_disable(struct ltt_session *session) +{ + int ret = 0; + + mutex_lock(&sessions_mutex); + if (!session->active) { + ret = -EBUSY; + goto end; + } + ACCESS_ONCE(session->active) = 0; +end: + mutex_unlock(&sessions_mutex); + return ret; +} + +int ltt_channel_enable(struct ltt_channel *channel) +{ + int old; + + if (channel == channel->session->metadata) + return -EPERM; + old = xchg(&channel->enabled, 1); + if (old) + return -EEXIST; + return 0; +} + +int ltt_channel_disable(struct ltt_channel *channel) +{ + int old; + + if (channel == channel->session->metadata) + return -EPERM; + old = xchg(&channel->enabled, 0); + if (!old) + return -EEXIST; + return 0; +} + +int ltt_event_enable(struct ltt_event *event) +{ + int old; + + if (event->chan == event->chan->session->metadata) + return -EPERM; + old = xchg(&event->enabled, 1); + if (old) + return -EEXIST; + return 0; +} + +int ltt_event_disable(struct ltt_event *event) +{ + int old; + + if (event->chan == event->chan->session->metadata) + return -EPERM; + old = xchg(&event->enabled, 0); + if (!old) + return -EEXIST; + return 0; +} + +static struct ltt_transport *ltt_transport_find(const char *name) +{ + struct ltt_transport *transport; + + list_for_each_entry(transport, <t_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, <t_transport_list); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(ltt_transport_register); + +/** + * ltt_transport_unregister - LTT transport unregistration + * @transport: transport structure + */ +void ltt_transport_unregister(struct ltt_transport *transport) +{ + mutex_lock(&sessions_mutex); + list_del(&transport->node); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(ltt_transport_unregister); + +static int __init ltt_events_init(void) +{ + int ret; + + event_cache = KMEM_CACHE(ltt_event, 0); + if (!event_cache) + return -ENOMEM; + ret = ltt_debugfs_abi_init(); + if (ret) + goto error_abi; + return 0; +error_abi: + kmem_cache_destroy(event_cache); + return ret; +} + +module_init(ltt_events_init); + +static void __exit ltt_events_exit(void) +{ + struct ltt_session *session, *tmpsession; + + ltt_debugfs_abi_exit(); + list_for_each_entry_safe(session, tmpsession, &sessions, list) + ltt_session_destroy(session); + kmem_cache_destroy(event_cache); +} + +module_exit(ltt_events_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng Events"); diff --git a/drivers/staging/lttng/ltt-events.h b/drivers/staging/lttng/ltt-events.h new file mode 100644 index 0000000..36b281a --- /dev/null +++ b/drivers/staging/lttng/ltt-events.h @@ -0,0 +1,452 @@ +#ifndef _LTT_EVENTS_H +#define _LTT_EVENTS_H + +/* + * ltt-events.h + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Holds LTTng per-session event registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/list.h> +#include <linux/kprobes.h> +#include "wrapper/uuid.h" +#include "ltt-debugfs-abi.h" + +#undef is_signed_type +#define is_signed_type(type) (((type)(-1)) < 0) + +struct ltt_channel; +struct ltt_session; +struct lib_ring_buffer_ctx; +struct perf_event; +struct perf_event_attr; + +/* Type description */ + +/* Update the astract_types name table in lttng-types.c along with this enum */ +enum abstract_types { + atype_integer, + atype_enum, + atype_array, + atype_sequence, + atype_string, + NR_ABSTRACT_TYPES, +}; + +/* Update the string_encodings name table in lttng-types.c along with this enum */ +enum lttng_string_encodings { + lttng_encode_none = 0, + lttng_encode_UTF8 = 1, + lttng_encode_ASCII = 2, + NR_STRING_ENCODINGS, +}; + +struct lttng_enum_entry { + unsigned long long start, end; /* start and end are inclusive */ + const char *string; +}; + +#define __type_integer(_type, _byte_order, _base, _encoding) \ + { \ + .atype = atype_integer, \ + .u.basic.integer = \ + { \ + .size = sizeof(_type) * CHAR_BIT, \ + .alignment = ltt_alignof(_type) * CHAR_BIT, \ + .signedness = is_signed_type(_type), \ + .reverse_byte_order = _byte_order != __BYTE_ORDER, \ + .base = _base, \ + .encoding = lttng_encode_##_encoding, \ + }, \ + } \ + +struct lttng_integer_type { + unsigned int size; /* in bits */ + unsigned short alignment; /* in bits */ + unsigned int signedness:1; + unsigned int reverse_byte_order:1; + unsigned int base; /* 2, 8, 10, 16, for pretty print */ + enum lttng_string_encodings encoding; +}; + +union _lttng_basic_type { + struct lttng_integer_type integer; + struct { + const char *name; + } enumeration; + struct { + enum lttng_string_encodings encoding; + } string; +}; + +struct lttng_basic_type { + enum abstract_types atype; + union { + union _lttng_basic_type basic; + } u; +}; + +struct lttng_type { + enum abstract_types atype; + union { + union _lttng_basic_type basic; + struct { + struct lttng_basic_type elem_type; + unsigned int length; /* num. elems. */ + } array; + struct { + struct lttng_basic_type length_type; + struct lttng_basic_type elem_type; + } sequence; + } u; +}; + +struct lttng_enum { + const char *name; + struct lttng_type container_type; + const struct lttng_enum_entry *entries; + unsigned int len; +}; + +/* Event field description */ + +struct lttng_event_field { + const char *name; + struct lttng_type type; +}; + +/* + * We need to keep this perf counter field separately from struct + * lttng_ctx_field because cpu hotplug needs fixed-location addresses. + */ +struct lttng_perf_counter_field { + struct notifier_block nb; + int hp_enable; + struct perf_event_attr *attr; + struct perf_event **e; /* per-cpu array */ +}; + +struct lttng_ctx_field { + struct lttng_event_field event_field; + size_t (*get_size)(size_t offset); + void (*record)(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan); + union { + struct lttng_perf_counter_field *perf_counter; + } u; + void (*destroy)(struct lttng_ctx_field *field); +}; + +struct lttng_ctx { + struct lttng_ctx_field *fields; + unsigned int nr_fields; + unsigned int allocated_fields; +}; + +struct lttng_event_desc { + const char *name; + void *probe_callback; + const struct lttng_event_ctx *ctx; /* context */ + const struct lttng_event_field *fields; /* event payload */ + unsigned int nr_fields; + struct module *owner; +}; + +struct lttng_probe_desc { + const struct lttng_event_desc **event_desc; + unsigned int nr_events; + struct list_head head; /* chain registered probes */ +}; + +struct lttng_krp; /* Kretprobe handling */ + +/* + * ltt_event structure is referred to by the tracing fast path. It must be + * kept small. + */ +struct ltt_event { + unsigned int id; + struct ltt_channel *chan; + int enabled; + const struct lttng_event_desc *desc; + void *filter; + struct lttng_ctx *ctx; + enum lttng_kernel_instrumentation instrumentation; + union { + struct { + struct kprobe kp; + char *symbol_name; + } kprobe; + struct { + struct lttng_krp *lttng_krp; + char *symbol_name; + } kretprobe; + struct { + char *symbol_name; + } ftrace; + } u; + struct list_head list; /* Event list */ + int metadata_dumped:1; +}; + +struct ltt_channel_ops { + struct channel *(*channel_create)(const char *name, + struct ltt_channel *ltt_chan, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); + void (*channel_destroy)(struct channel *chan); + struct lib_ring_buffer *(*buffer_read_open)(struct channel *chan); + int (*buffer_has_read_closed_stream)(struct channel *chan); + void (*buffer_read_close)(struct lib_ring_buffer *buf); + int (*event_reserve)(struct lib_ring_buffer_ctx *ctx, + uint32_t event_id); + void (*event_commit)(struct lib_ring_buffer_ctx *ctx); + void (*event_write)(struct lib_ring_buffer_ctx *ctx, const void *src, + size_t len); + void (*event_write_from_user)(struct lib_ring_buffer_ctx *ctx, + const void *src, size_t len); + void (*event_memset)(struct lib_ring_buffer_ctx *ctx, + int c, size_t len); + /* + * packet_avail_size returns the available size in the current + * packet. Note that the size returned is only a hint, since it + * may change due to concurrent writes. + */ + size_t (*packet_avail_size)(struct channel *chan); + wait_queue_head_t *(*get_writer_buf_wait_queue)(struct channel *chan, int cpu); + wait_queue_head_t *(*get_hp_wait_queue)(struct channel *chan); + int (*is_finalized)(struct channel *chan); + int (*is_disabled)(struct channel *chan); +}; + +struct ltt_transport { + char *name; + struct module *owner; + struct list_head node; + struct ltt_channel_ops ops; +}; + +struct ltt_channel { + unsigned int id; + struct channel *chan; /* Channel buffers */ + int enabled; + struct lttng_ctx *ctx; + /* Event ID management */ + struct ltt_session *session; + struct file *file; /* File associated to channel */ + unsigned int free_event_id; /* Next event ID to allocate */ + struct list_head list; /* Channel list */ + struct ltt_channel_ops *ops; + struct ltt_transport *transport; + struct ltt_event **sc_table; /* for syscall tracing */ + struct ltt_event **compat_sc_table; + struct ltt_event *sc_unknown; /* for unknown syscalls */ + struct ltt_event *sc_compat_unknown; + struct ltt_event *sc_exit; /* for syscall exit */ + int header_type; /* 0: unset, 1: compact, 2: large */ + int metadata_dumped:1; +}; + +struct ltt_session { + int active; /* Is trace session active ? */ + int been_active; /* Has trace session been active ? */ + struct file *file; /* File associated to session */ + struct ltt_channel *metadata; /* Metadata channel */ + struct list_head chan; /* Channel list head */ + struct list_head events; /* Event list head */ + struct list_head list; /* Session list */ + unsigned int free_chan_id; /* Next chan ID to allocate */ + uuid_le uuid; /* Trace session unique ID */ + int metadata_dumped:1; +}; + +struct ltt_session *ltt_session_create(void); +int ltt_session_enable(struct ltt_session *session); +int ltt_session_disable(struct ltt_session *session); +void ltt_session_destroy(struct ltt_session *session); + +struct ltt_channel *ltt_channel_create(struct ltt_session *session, + const char *transport_name, + void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); +struct ltt_channel *ltt_global_channel_create(struct ltt_session *session, + int overwrite, void *buf_addr, + size_t subbuf_size, size_t num_subbuf, + unsigned int switch_timer_interval, + unsigned int read_timer_interval); + +struct ltt_event *ltt_event_create(struct ltt_channel *chan, + struct lttng_kernel_event *event_param, + void *filter, + const struct lttng_event_desc *internal_desc); + +int ltt_channel_enable(struct ltt_channel *channel); +int ltt_channel_disable(struct ltt_channel *channel); +int ltt_event_enable(struct ltt_event *event); +int ltt_event_disable(struct ltt_event *event); + +void ltt_transport_register(struct ltt_transport *transport); +void ltt_transport_unregister(struct ltt_transport *transport); + +void synchronize_trace(void); +int ltt_debugfs_abi_init(void); +void ltt_debugfs_abi_exit(void); + +int ltt_probe_register(struct lttng_probe_desc *desc); +void ltt_probe_unregister(struct lttng_probe_desc *desc); +const struct lttng_event_desc *ltt_event_get(const char *name); +void ltt_event_put(const struct lttng_event_desc *desc); +int ltt_probes_init(void); +void ltt_probes_exit(void); + +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS +int lttng_syscalls_register(struct ltt_channel *chan, void *filter); +int lttng_syscalls_unregister(struct ltt_channel *chan); +#else +static inline int lttng_syscalls_register(struct ltt_channel *chan, void *filter) +{ + return -ENOSYS; +} + +static inline int lttng_syscalls_unregister(struct ltt_channel *chan) +{ + return 0; +} +#endif + +struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx); +int lttng_find_context(struct lttng_ctx *ctx, const char *name); +void lttng_remove_context_field(struct lttng_ctx **ctx, + struct lttng_ctx_field *field); +void lttng_destroy_context(struct lttng_ctx *ctx); +int lttng_add_pid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_procname_to_ctx(struct lttng_ctx **ctx); +int lttng_add_prio_to_ctx(struct lttng_ctx **ctx); +int lttng_add_nice_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_tid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx); +int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx); +#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) +int lttng_add_perf_counter_to_ctx(uint32_t type, + uint64_t config, + const char *name, + struct lttng_ctx **ctx); +#else +static inline +int lttng_add_perf_counter_to_ctx(uint32_t type, + uint64_t config, + const char *name, + struct lttng_ctx **ctx) +{ + return -ENOSYS; +} +#endif + +#ifdef CONFIG_KPROBES +int lttng_kprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event); +void lttng_kprobes_unregister(struct ltt_event *event); +void lttng_kprobes_destroy_private(struct ltt_event *event); +#else +static inline +int lttng_kprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event) +{ + return -ENOSYS; +} + +static inline +void lttng_kprobes_unregister(struct ltt_event *event) +{ +} + +static inline +void lttng_kprobes_destroy_private(struct ltt_event *event) +{ +} +#endif + +#ifdef CONFIG_KRETPROBES +int lttng_kretprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event_entry, + struct ltt_event *event_exit); +void lttng_kretprobes_unregister(struct ltt_event *event); +void lttng_kretprobes_destroy_private(struct ltt_event *event); +#else +static inline +int lttng_kretprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event_entry, + struct ltt_event *event_exit) +{ + return -ENOSYS; +} + +static inline +void lttng_kretprobes_unregister(struct ltt_event *event) +{ +} + +static inline +void lttng_kretprobes_destroy_private(struct ltt_event *event) +{ +} +#endif + +#ifdef CONFIG_DYNAMIC_FTRACE +int lttng_ftrace_register(const char *name, + const char *symbol_name, + struct ltt_event *event); +void lttng_ftrace_unregister(struct ltt_event *event); +void lttng_ftrace_destroy_private(struct ltt_event *event); +#else +static inline +int lttng_ftrace_register(const char *name, + const char *symbol_name, + struct ltt_event *event) +{ + return -ENOSYS; +} + +static inline +void lttng_ftrace_unregister(struct ltt_event *event) +{ +} + +static inline +void lttng_ftrace_destroy_private(struct ltt_event *event) +{ +} +#endif + +int lttng_calibrate(struct lttng_kernel_calibrate *calibrate); + +extern const struct file_operations lttng_tracepoint_list_fops; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) +#define TRACEPOINT_HAS_DATA_ARG +#endif + +#endif /* _LTT_EVENTS_H */ diff --git a/drivers/staging/lttng/ltt-probes.c b/drivers/staging/lttng/ltt-probes.c new file mode 100644 index 0000000..81dcbd7 --- /dev/null +++ b/drivers/staging/lttng/ltt-probes.c @@ -0,0 +1,164 @@ +/* + * ltt-probes.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Holds LTTng probes registry. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/seq_file.h> + +#include "ltt-events.h" + +static LIST_HEAD(probe_list); +static DEFINE_MUTEX(probe_mutex); + +static +const struct lttng_event_desc *find_event(const char *name) +{ + struct lttng_probe_desc *probe_desc; + int i; + + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (!strcmp(probe_desc->event_desc[i]->name, name)) + return probe_desc->event_desc[i]; + } + } + return NULL; +} + +int ltt_probe_register(struct lttng_probe_desc *desc) +{ + int ret = 0; + int i; + + mutex_lock(&probe_mutex); + /* + * TODO: This is O(N^2). Turn into a hash table when probe registration + * overhead becomes an issue. + */ + for (i = 0; i < desc->nr_events; i++) { + if (find_event(desc->event_desc[i]->name)) { + ret = -EEXIST; + goto end; + } + } + list_add(&desc->head, &probe_list); +end: + mutex_unlock(&probe_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(ltt_probe_register); + +void ltt_probe_unregister(struct lttng_probe_desc *desc) +{ + mutex_lock(&probe_mutex); + list_del(&desc->head); + mutex_unlock(&probe_mutex); +} +EXPORT_SYMBOL_GPL(ltt_probe_unregister); + +const struct lttng_event_desc *ltt_event_get(const char *name) +{ + const struct lttng_event_desc *event; + int ret; + + mutex_lock(&probe_mutex); + event = find_event(name); + mutex_unlock(&probe_mutex); + if (!event) + return NULL; + ret = try_module_get(event->owner); + WARN_ON_ONCE(!ret); + return event; +} +EXPORT_SYMBOL_GPL(ltt_event_get); + +void ltt_event_put(const struct lttng_event_desc *event) +{ + module_put(event->owner); +} +EXPORT_SYMBOL_GPL(ltt_event_put); + +static +void *tp_list_start(struct seq_file *m, loff_t *pos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + mutex_lock(&probe_mutex); + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *pos) + return (void *) probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) +{ + struct lttng_probe_desc *probe_desc; + int iter = 0, i; + + (*ppos)++; + list_for_each_entry(probe_desc, &probe_list, head) { + for (i = 0; i < probe_desc->nr_events; i++) { + if (iter++ >= *ppos) + return (void *) probe_desc->event_desc[i]; + } + } + /* End of list */ + return NULL; +} + +static +void tp_list_stop(struct seq_file *m, void *p) +{ + mutex_unlock(&probe_mutex); +} + +static +int tp_list_show(struct seq_file *m, void *p) +{ + const struct lttng_event_desc *probe_desc = p; + + /* + * Don't export lttng internal events (metadata). + */ + if (!strncmp(probe_desc->name, "lttng_", sizeof("lttng_") - 1)) + return 0; + seq_printf(m, "event { name = %s; };\n", + probe_desc->name); + return 0; +} + +static +const struct seq_operations lttng_tracepoint_list_seq_ops = { + .start = tp_list_start, + .next = tp_list_next, + .stop = tp_list_stop, + .show = tp_list_show, +}; + +static +int lttng_tracepoint_list_open(struct inode *inode, struct file *file) +{ + return seq_open(file, <tng_tracepoint_list_seq_ops); +} + +const struct file_operations lttng_tracepoint_list_fops = { + .owner = THIS_MODULE, + .open = lttng_tracepoint_list_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; diff --git a/drivers/staging/lttng/ltt-tracer-core.h b/drivers/staging/lttng/ltt-tracer-core.h new file mode 100644 index 0000000..5abc432 --- /dev/null +++ b/drivers/staging/lttng/ltt-tracer-core.h @@ -0,0 +1,28 @@ +#ifndef LTT_TRACER_CORE_H +#define LTT_TRACER_CORE_H + +/* + * ltt-tracer-core.h + * + * Copyright (C) 2005-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * This contains the core definitions for the Linux Trace Toolkit. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/list.h> +#include <linux/percpu.h> + +#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS +/* Align data on its natural alignment */ +#define RING_BUFFER_ALIGN +#endif + +#include "wrapper/ringbuffer/config.h" + +struct ltt_session; +struct ltt_channel; +struct ltt_event; + +#endif /* LTT_TRACER_CORE_H */ diff --git a/drivers/staging/lttng/ltt-tracer.h b/drivers/staging/lttng/ltt-tracer.h new file mode 100644 index 0000000..a21c38c --- /dev/null +++ b/drivers/staging/lttng/ltt-tracer.h @@ -0,0 +1,67 @@ +#ifndef _LTT_TRACER_H +#define _LTT_TRACER_H + +/* + * ltt-tracer.h + * + * Copyright (C) 2005-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * This contains the definitions for the Linux Trace Toolkit tracer. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <stdarg.h> +#include <linux/types.h> +#include <linux/limits.h> +#include <linux/list.h> +#include <linux/cache.h> +#include <linux/timex.h> +#include <linux/wait.h> +#include <asm/atomic.h> +#include <asm/local.h> + +#include "wrapper/trace-clock.h" +#include "ltt-tracer-core.h" +#include "ltt-events.h" + +#define LTTNG_VERSION 0 +#define LTTNG_PATCHLEVEL 9 +#define LTTNG_SUBLEVEL 1 + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +/* Number of bytes to log with a read/write event */ +#define LTT_LOG_RW_SIZE 32L +#define LTT_MAX_SMALL_SIZE 0xFFFFU + +#ifdef RING_BUFFER_ALIGN +#define ltt_alignof(type) __alignof__(type) +#else +#define ltt_alignof(type) 1 +#endif + +/* Tracer properties */ +#define CTF_MAGIC_NUMBER 0xC1FC1FC1 +#define TSDL_MAGIC_NUMBER 0x75D11D57 + +/* CTF specification version followed */ +#define CTF_SPEC_MAJOR 1 +#define CTF_SPEC_MINOR 8 + +/* Tracer major/minor versions */ +#define CTF_VERSION_MAJOR 0 +#define CTF_VERSION_MINOR 1 + +/* + * Number of milliseconds to retry before failing metadata writes on buffer full + * condition. (10 seconds) + */ +#define LTTNG_METADATA_TIMEOUT_MSEC 10000 + +#define LTT_RFLAG_EXTENDED RING_BUFFER_RFLAG_END +#define LTT_RFLAG_END (LTT_RFLAG_EXTENDED << 1) + +#endif /* _LTT_TRACER_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 12/20] lttng: dynamically selectable context information 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (10 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 11/20] lttng: tracer control and core structures Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 13/20] lttng: timing calibration feature Mathieu Desnoyers ` (8 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Events can be augmented with context information. This is dynamically configurable from the command line. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/ltt-context.c | 93 +++++++ drivers/staging/lttng/lttng-context-nice.c | 68 +++++ .../staging/lttng/lttng-context-perf-counters.c | 271 ++++++++++++++++++++ drivers/staging/lttng/lttng-context-pid.c | 68 +++++ drivers/staging/lttng/lttng-context-ppid.c | 71 +++++ drivers/staging/lttng/lttng-context-prio.c | 89 +++++++ drivers/staging/lttng/lttng-context-procname.c | 72 +++++ drivers/staging/lttng/lttng-context-tid.c | 68 +++++ drivers/staging/lttng/lttng-context-vpid.c | 74 ++++++ drivers/staging/lttng/lttng-context-vppid.c | 79 ++++++ drivers/staging/lttng/lttng-context-vtid.c | 74 ++++++ 11 files changed, 1027 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/ltt-context.c create mode 100644 drivers/staging/lttng/lttng-context-nice.c create mode 100644 drivers/staging/lttng/lttng-context-perf-counters.c create mode 100644 drivers/staging/lttng/lttng-context-pid.c create mode 100644 drivers/staging/lttng/lttng-context-ppid.c create mode 100644 drivers/staging/lttng/lttng-context-prio.c create mode 100644 drivers/staging/lttng/lttng-context-procname.c create mode 100644 drivers/staging/lttng/lttng-context-tid.c create mode 100644 drivers/staging/lttng/lttng-context-vpid.c create mode 100644 drivers/staging/lttng/lttng-context-vppid.c create mode 100644 drivers/staging/lttng/lttng-context-vtid.c diff --git a/drivers/staging/lttng/ltt-context.c b/drivers/staging/lttng/ltt-context.c new file mode 100644 index 0000000..60ea525 --- /dev/null +++ b/drivers/staging/lttng/ltt-context.c @@ -0,0 +1,93 @@ +/* + * ltt-context.c + * + * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng trace/channel/event context management. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "ltt-events.h" +#include "ltt-tracer.h" + +int lttng_find_context(struct lttng_ctx *ctx, const char *name) +{ + unsigned int i; + + for (i = 0; i < ctx->nr_fields; i++) { + /* Skip allocated (but non-initialized) contexts */ + if (!ctx->fields[i].event_field.name) + continue; + if (!strcmp(ctx->fields[i].event_field.name, name)) + return 1; + } + return 0; +} +EXPORT_SYMBOL_GPL(lttng_find_context); + +/* + * Note: as we append context information, the pointer location may change. + */ +struct lttng_ctx_field *lttng_append_context(struct lttng_ctx **ctx_p) +{ + struct lttng_ctx_field *field; + struct lttng_ctx *ctx; + + if (!*ctx_p) { + *ctx_p = kzalloc(sizeof(struct lttng_ctx), GFP_KERNEL); + if (!*ctx_p) + return NULL; + } + ctx = *ctx_p; + if (ctx->nr_fields + 1 > ctx->allocated_fields) { + struct lttng_ctx_field *new_fields; + + ctx->allocated_fields = max_t(size_t, 1, 2 * ctx->allocated_fields); + new_fields = kzalloc(ctx->allocated_fields * sizeof(struct lttng_ctx_field), GFP_KERNEL); + if (!new_fields) + return NULL; + if (ctx->fields) + memcpy(new_fields, ctx->fields, sizeof(*ctx->fields) * ctx->nr_fields); + kfree(ctx->fields); + ctx->fields = new_fields; + } + field = &ctx->fields[ctx->nr_fields]; + ctx->nr_fields++; + return field; +} +EXPORT_SYMBOL_GPL(lttng_append_context); + +/* + * Remove last context field. + */ +void lttng_remove_context_field(struct lttng_ctx **ctx_p, + struct lttng_ctx_field *field) +{ + struct lttng_ctx *ctx; + + ctx = *ctx_p; + ctx->nr_fields--; + WARN_ON_ONCE(&ctx->fields[ctx->nr_fields] != field); + memset(&ctx->fields[ctx->nr_fields], 0, sizeof(struct lttng_ctx_field)); +} +EXPORT_SYMBOL_GPL(lttng_remove_context_field); + +void lttng_destroy_context(struct lttng_ctx *ctx) +{ + int i; + + if (!ctx) + return; + for (i = 0; i < ctx->nr_fields; i++) { + if (ctx->fields[i].destroy) + ctx->fields[i].destroy(&ctx->fields[i]); + } + kfree(ctx->fields); + kfree(ctx); +} diff --git a/drivers/staging/lttng/lttng-context-nice.c b/drivers/staging/lttng/lttng-context-nice.c new file mode 100644 index 0000000..9b99b54 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-nice.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng nice context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t nice_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(int)); + size += sizeof(int); + return size; +} + +static +void nice_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + int nice; + + nice = task_nice(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(nice)); + chan->ops->event_write(ctx, &nice, sizeof(nice)); +} + +int lttng_add_nice_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "nice")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "nice"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(int); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = nice_get_size; + field->record = nice_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_nice_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Nice Context"); diff --git a/drivers/staging/lttng/lttng-context-perf-counters.c b/drivers/staging/lttng/lttng-context-perf-counters.c new file mode 100644 index 0000000..3ae2266 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-perf-counters.c @@ -0,0 +1,271 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng performance monitoring counters (perf-counters) integration module. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/perf_event.h> +#include <linux/list.h> +#include <linux/string.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "wrapper/perf.h" +#include "ltt-tracer.h" + +static +size_t perf_counter_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(uint64_t)); + size += sizeof(uint64_t); + return size; +} + +static +void perf_counter_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + struct perf_event *event; + uint64_t value; + + event = field->u.perf_counter->e[ctx->cpu]; + if (likely(event)) { + if (unlikely(event->state == PERF_EVENT_STATE_ERROR)) { + value = 0; + } else { + event->pmu->read(event); + value = local64_read(&event->count); + } + } else { + /* + * Perf chooses not to be clever and not to support enabling a + * perf counter before the cpu is brought up. Therefore, we need + * to support having events coming (e.g. scheduler events) + * before the counter is setup. Write an arbitrary 0 in this + * case. + */ + value = 0; + } + lib_ring_buffer_align_ctx(ctx, ltt_alignof(value)); + chan->ops->event_write(ctx, &value, sizeof(value)); +} + +#if defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99)) +static +void overflow_callback(struct perf_event *event, + struct perf_sample_data *data, + struct pt_regs *regs) +{ +} +#else +static +void overflow_callback(struct perf_event *event, int nmi, + struct perf_sample_data *data, + struct pt_regs *regs) +{ +} +#endif + +static +void lttng_destroy_perf_counter_field(struct lttng_ctx_field *field) +{ + struct perf_event **events = field->u.perf_counter->e; + int cpu; + + get_online_cpus(); + for_each_online_cpu(cpu) + perf_event_release_kernel(events[cpu]); + put_online_cpus(); +#ifdef CONFIG_HOTPLUG_CPU + unregister_cpu_notifier(&field->u.perf_counter->nb); +#endif + kfree(field->event_field.name); + kfree(field->u.perf_counter->attr); + kfree(events); + kfree(field->u.perf_counter); +} + +#ifdef CONFIG_HOTPLUG_CPU + +/** + * lttng_perf_counter_hp_callback - CPU hotplug callback + * @nb: notifier block + * @action: hotplug action to take + * @hcpu: CPU number + * + * Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD) + * + * We can setup perf counters when the cpu is online (up prepare seems to be too + * soon). + */ +static +int __cpuinit lttng_perf_counter_cpu_hp_callback(struct notifier_block *nb, + unsigned long action, + void *hcpu) +{ + unsigned int cpu = (unsigned long) hcpu; + struct lttng_perf_counter_field *perf_field = + container_of(nb, struct lttng_perf_counter_field, nb); + struct perf_event **events = perf_field->e; + struct perf_event_attr *attr = perf_field->attr; + struct perf_event *pevent; + + if (!perf_field->hp_enable) + return NOTIFY_OK; + + switch (action) { + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + pevent = wrapper_perf_event_create_kernel_counter(attr, + cpu, NULL, overflow_callback); + if (!pevent || IS_ERR(pevent)) + return NOTIFY_BAD; + if (pevent->state == PERF_EVENT_STATE_ERROR) { + perf_event_release_kernel(pevent); + return NOTIFY_BAD; + } + barrier(); /* Create perf counter before setting event */ + events[cpu] = pevent; + break; + case CPU_UP_CANCELED: + case CPU_UP_CANCELED_FROZEN: + case CPU_DEAD: + case CPU_DEAD_FROZEN: + pevent = events[cpu]; + events[cpu] = NULL; + barrier(); /* NULLify event before perf counter teardown */ + perf_event_release_kernel(pevent); + break; + } + return NOTIFY_OK; +} + +#endif + +int lttng_add_perf_counter_to_ctx(uint32_t type, + uint64_t config, + const char *name, + struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + struct lttng_perf_counter_field *perf_field; + struct perf_event **events; + struct perf_event_attr *attr; + int ret; + int cpu; + char *name_alloc; + + events = kzalloc(num_possible_cpus() * sizeof(*events), GFP_KERNEL); + if (!events) + return -ENOMEM; + + attr = kzalloc(sizeof(struct perf_event_attr), GFP_KERNEL); + if (!attr) { + ret = -ENOMEM; + goto error_attr; + } + + attr->type = type; + attr->config = config; + attr->size = sizeof(struct perf_event_attr); + attr->pinned = 1; + attr->disabled = 0; + + perf_field = kzalloc(sizeof(struct lttng_perf_counter_field), GFP_KERNEL); + if (!perf_field) { + ret = -ENOMEM; + goto error_alloc_perf_field; + } + perf_field->e = events; + perf_field->attr = attr; + + name_alloc = kstrdup(name, GFP_KERNEL); + if (!name_alloc) { + ret = -ENOMEM; + goto name_alloc_error; + } + + field = lttng_append_context(ctx); + if (!field) { + ret = -ENOMEM; + goto append_context_error; + } + if (lttng_find_context(*ctx, name_alloc)) { + ret = -EEXIST; + goto find_error; + } + +#ifdef CONFIG_HOTPLUG_CPU + perf_field->nb.notifier_call = + lttng_perf_counter_cpu_hp_callback; + perf_field->nb.priority = 0; + register_cpu_notifier(&perf_field->nb); +#endif + + get_online_cpus(); + for_each_online_cpu(cpu) { + events[cpu] = wrapper_perf_event_create_kernel_counter(attr, + cpu, NULL, overflow_callback); + if (!events[cpu] || IS_ERR(events[cpu])) { + ret = -EINVAL; + goto counter_error; + } + if (events[cpu]->state == PERF_EVENT_STATE_ERROR) { + ret = -EBUSY; + goto counter_busy; + } + } + put_online_cpus(); + + field->destroy = lttng_destroy_perf_counter_field; + + field->event_field.name = name_alloc; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(uint64_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(uint64_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(uint64_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = perf_counter_get_size; + field->record = perf_counter_record; + field->u.perf_counter = perf_field; + perf_field->hp_enable = 1; + + wrapper_vmalloc_sync_all(); + return 0; + +counter_busy: +counter_error: + for_each_online_cpu(cpu) { + if (events[cpu] && !IS_ERR(events[cpu])) + perf_event_release_kernel(events[cpu]); + } + put_online_cpus(); +#ifdef CONFIG_HOTPLUG_CPU + unregister_cpu_notifier(&perf_field->nb); +#endif +find_error: + lttng_remove_context_field(ctx, field); +append_context_error: + kfree(name_alloc); +name_alloc_error: + kfree(perf_field); +error_alloc_perf_field: + kfree(attr); +error_attr: + kfree(events); + return ret; +} + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Perf Support"); diff --git a/drivers/staging/lttng/lttng-context-pid.c b/drivers/staging/lttng/lttng-context-pid.c new file mode 100644 index 0000000..698b242 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-pid.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng PID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t pid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void pid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + pid_t pid; + + pid = task_tgid_nr(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(pid)); + chan->ops->event_write(ctx, &pid, sizeof(pid)); +} + +int lttng_add_pid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "pid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "pid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = pid_get_size; + field->record = pid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_pid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit PID Context"); diff --git a/drivers/staging/lttng/lttng-context-ppid.c b/drivers/staging/lttng/lttng-context-ppid.c new file mode 100644 index 0000000..738f7e6 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-ppid.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng PPID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/syscalls.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t ppid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void ppid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + pid_t ppid; + + rcu_read_lock(); + ppid = task_tgid_nr(current->real_parent); + rcu_read_unlock(); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(ppid)); + chan->ops->event_write(ctx, &ppid, sizeof(ppid)); +} + +int lttng_add_ppid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "ppid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "ppid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = ppid_get_size; + field->record = ppid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_ppid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit PPID Context"); diff --git a/drivers/staging/lttng/lttng-context-prio.c b/drivers/staging/lttng/lttng-context-prio.c new file mode 100644 index 0000000..1ee3a54 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-prio.c @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng priority context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "wrapper/kallsyms.h" +#include "ltt-tracer.h" + +static +int (*wrapper_task_prio_sym)(struct task_struct *t); + +int wrapper_task_prio_init(void) +{ + wrapper_task_prio_sym = (void *) kallsyms_lookup_funcptr("task_prio"); + if (!wrapper_task_prio_sym) { + printk(KERN_WARNING "LTTng: task_prio symbol lookup failed.\n"); + return -EINVAL; + } + return 0; +} + +static +size_t prio_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(int)); + size += sizeof(int); + return size; +} + +static +void prio_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + int prio; + + prio = wrapper_task_prio_sym(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(prio)); + chan->ops->event_write(ctx, &prio, sizeof(prio)); +} + +int lttng_add_prio_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + int ret; + + if (!wrapper_task_prio_sym) { + ret = wrapper_task_prio_init(); + if (ret) + return ret; + } + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "prio")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "prio"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(int) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(int); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = prio_get_size; + field->record = prio_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_prio_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Priority Context"); diff --git a/drivers/staging/lttng/lttng-context-procname.c b/drivers/staging/lttng/lttng-context-procname.c new file mode 100644 index 0000000..c6bc646 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-procname.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng procname context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t procname_get_size(size_t offset) +{ + size_t size = 0; + + size += sizeof(current->comm); + return size; +} + +/* + * Racy read of procname. We simply copy its whole array size. + * Races with /proc/<task>/procname write only. + * Otherwise having to take a mutex for each event is cumbersome and + * could lead to crash in IRQ context and deadlock of the lockdep tracer. + */ +static +void procname_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + chan->ops->event_write(ctx, current->comm, sizeof(current->comm)); +} + +int lttng_add_procname_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "procname")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "procname"; + field->event_field.type.atype = atype_array; + field->event_field.type.u.array.elem_type.atype = atype_integer; + field->event_field.type.u.array.elem_type.u.basic.integer.size = sizeof(char) * CHAR_BIT; + field->event_field.type.u.array.elem_type.u.basic.integer.alignment = ltt_alignof(char) * CHAR_BIT; + field->event_field.type.u.array.elem_type.u.basic.integer.signedness = is_signed_type(char); + field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.array.elem_type.u.basic.integer.base = 10; + field->event_field.type.u.array.elem_type.u.basic.integer.encoding = lttng_encode_UTF8; + field->event_field.type.u.array.length = sizeof(current->comm); + + field->get_size = procname_get_size; + field->record = procname_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_procname_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Perf Support"); diff --git a/drivers/staging/lttng/lttng-context-tid.c b/drivers/staging/lttng/lttng-context-tid.c new file mode 100644 index 0000000..d5ccdb6 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-tid.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng TID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t tid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void tid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + pid_t tid; + + tid = task_pid_nr(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(tid)); + chan->ops->event_write(ctx, &tid, sizeof(tid)); +} + +int lttng_add_tid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "tid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "tid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = tid_get_size; + field->record = tid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_tid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit TID Context"); diff --git a/drivers/staging/lttng/lttng-context-vpid.c b/drivers/staging/lttng/lttng-context-vpid.c new file mode 100644 index 0000000..3f16e03 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-vpid.c @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng vPID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t vpid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void vpid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + pid_t vpid; + + /* + * nsproxy can be NULL when scheduled out of exit. + */ + if (!current->nsproxy) + vpid = 0; + else + vpid = task_tgid_vnr(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(vpid)); + chan->ops->event_write(ctx, &vpid, sizeof(vpid)); +} + +int lttng_add_vpid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "vpid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "vpid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = vpid_get_size; + field->record = vpid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_vpid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit vPID Context"); diff --git a/drivers/staging/lttng/lttng-context-vppid.c b/drivers/staging/lttng/lttng-context-vppid.c new file mode 100644 index 0000000..f01b020 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-vppid.c @@ -0,0 +1,79 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng vPPID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/syscalls.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t vppid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void vppid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + struct task_struct *parent; + pid_t vppid; + + /* + * nsproxy can be NULL when scheduled out of exit. + */ + rcu_read_lock(); + parent = rcu_dereference(current->real_parent); + if (!parent->nsproxy) + vppid = 0; + else + vppid = task_tgid_vnr(parent); + rcu_read_unlock(); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(vppid)); + chan->ops->event_write(ctx, &vppid, sizeof(vppid)); +} + +int lttng_add_vppid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "vppid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "vppid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = vppid_get_size; + field->record = vppid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_vppid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit vPPID Context"); diff --git a/drivers/staging/lttng/lttng-context-vtid.c b/drivers/staging/lttng/lttng-context-vtid.c new file mode 100644 index 0000000..264bbb3 --- /dev/null +++ b/drivers/staging/lttng/lttng-context-vtid.c @@ -0,0 +1,74 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng vTID context. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include "ltt-events.h" +#include "wrapper/ringbuffer/frontend_types.h" +#include "wrapper/vmalloc.h" +#include "ltt-tracer.h" + +static +size_t vtid_get_size(size_t offset) +{ + size_t size = 0; + + size += lib_ring_buffer_align(offset, ltt_alignof(pid_t)); + size += sizeof(pid_t); + return size; +} + +static +void vtid_record(struct lttng_ctx_field *field, + struct lib_ring_buffer_ctx *ctx, + struct ltt_channel *chan) +{ + pid_t vtid; + + /* + * nsproxy can be NULL when scheduled out of exit. + */ + if (!current->nsproxy) + vtid = 0; + else + vtid = task_pid_vnr(current); + lib_ring_buffer_align_ctx(ctx, ltt_alignof(vtid)); + chan->ops->event_write(ctx, &vtid, sizeof(vtid)); +} + +int lttng_add_vtid_to_ctx(struct lttng_ctx **ctx) +{ + struct lttng_ctx_field *field; + + field = lttng_append_context(ctx); + if (!field) + return -ENOMEM; + if (lttng_find_context(*ctx, "vtid")) { + lttng_remove_context_field(ctx, field); + return -EEXIST; + } + field->event_field.name = "vtid"; + field->event_field.type.atype = atype_integer; + field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.alignment = ltt_alignof(pid_t) * CHAR_BIT; + field->event_field.type.u.basic.integer.signedness = is_signed_type(pid_t); + field->event_field.type.u.basic.integer.reverse_byte_order = 0; + field->event_field.type.u.basic.integer.base = 10; + field->event_field.type.u.basic.integer.encoding = lttng_encode_none; + field->get_size = vtid_get_size; + field->record = vtid_record; + wrapper_vmalloc_sync_all(); + return 0; +} +EXPORT_SYMBOL_GPL(lttng_add_vtid_to_ctx); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit vTID Context"); -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 13/20] lttng: timing calibration feature 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (11 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 12/20] lttng: dynamically selectable context information Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 14/20] lttng: debugfs and procfs ABI Mathieu Desnoyers ` (7 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) This calibration feature is fairly limited for now, but provides an example of how this can be performed. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lttng-calibrate.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lttng-calibrate.c diff --git a/drivers/staging/lttng/lttng-calibrate.c b/drivers/staging/lttng/lttng-calibrate.c new file mode 100644 index 0000000..07e3c5b --- /dev/null +++ b/drivers/staging/lttng/lttng-calibrate.c @@ -0,0 +1,30 @@ +/* + * lttng-calibrate.c + * + * Copyright 2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng probe calibration. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include "ltt-debugfs-abi.h" +#include "ltt-events.h" + +noinline +void lttng_calibrate_kretprobe(void) +{ + asm volatile (""); +} + +int lttng_calibrate(struct lttng_kernel_calibrate *calibrate) +{ + switch (calibrate->type) { + case LTTNG_KERNEL_CALIBRATE_KRETPROBE: + lttng_calibrate_kretprobe(); + break; + default: + return -EINVAL; + } + return 0; +} -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 14/20] lttng: debugfs and procfs ABI 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (12 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 13/20] lttng: timing calibration feature Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 15/20] lttng: Add documentation and TODO files Mathieu Desnoyers ` (6 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Add the "lttng" virtual file to debugfs and procfs. All operations are performed through ioctls (LTTng ioctl range is already reserved upstream) on this virtual file and on anonymous file descriptors returned by these ioctls. Each file descriptor is associated with a tracer "object" (session, channel, stream, event, context). Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/ltt-debugfs-abi.c | 777 +++++++++++++++++++++++++++++++ drivers/staging/lttng/ltt-debugfs-abi.h | 153 ++++++ 2 files changed, 930 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/ltt-debugfs-abi.c create mode 100644 drivers/staging/lttng/ltt-debugfs-abi.h diff --git a/drivers/staging/lttng/ltt-debugfs-abi.c b/drivers/staging/lttng/ltt-debugfs-abi.c new file mode 100644 index 0000000..37cccfa --- /dev/null +++ b/drivers/staging/lttng/ltt-debugfs-abi.c @@ -0,0 +1,777 @@ +/* + * ltt-debugfs-abi.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng debugfs ABI + * + * Mimic system calls for: + * - session creation, returns a file descriptor or failure. + * - channel creation, returns a file descriptor or failure. + * - Operates on a session file descriptor + * - Takes all channel options as parameters. + * - stream get, returns a file descriptor or failure. + * - Operates on a channel file descriptor. + * - stream notifier get, returns a file descriptor or failure. + * - Operates on a channel file descriptor. + * - event creation, returns a file descriptor or failure. + * - Operates on a channel file descriptor + * - Takes an event name as parameter + * - Takes an instrumentation source as parameter + * - e.g. tracepoints, dynamic_probes... + * - Takes instrumentation source specific arguments. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/debugfs.h> +#include <linux/proc_fs.h> +#include <linux/anon_inodes.h> +#include <linux/file.h> +#include <linux/uaccess.h> +#include <linux/slab.h> +#include "wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "wrapper/ringbuffer/vfs.h" +#include "wrapper/poll.h" +#include "ltt-debugfs-abi.h" +#include "ltt-events.h" +#include "ltt-tracer.h" + +/* + * This is LTTng's own personal way to create a system call as an external + * module. We use ioctl() on /sys/kernel/debug/lttng. + */ + +static struct dentry *lttng_dentry; +static struct proc_dir_entry *lttng_proc_dentry; +static const struct file_operations lttng_fops; +static const struct file_operations lttng_session_fops; +static const struct file_operations lttng_channel_fops; +static const struct file_operations lttng_metadata_fops; +static const struct file_operations lttng_event_fops; + +/* + * Teardown management: opened file descriptors keep a refcount on the module, + * so it can only exit when all file descriptors are closed. + */ + +enum channel_type { + PER_CPU_CHANNEL, + METADATA_CHANNEL, +}; + +static +int lttng_abi_create_session(void) +{ + struct ltt_session *session; + struct file *session_file; + int session_fd, ret; + + session = ltt_session_create(); + if (!session) + return -ENOMEM; + session_fd = get_unused_fd(); + if (session_fd < 0) { + ret = session_fd; + goto fd_error; + } + session_file = anon_inode_getfile("[lttng_session]", + <tng_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]", + <tng_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 = <tng_channel_fops; + break; + case METADATA_CHANNEL: + fops = <tng_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]", + <tng_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, + <tng_fops); + if (IS_ERR(lttng_dentry)) + lttng_dentry = NULL; + + lttng_proc_dentry = proc_create_data("lttng", S_IWUSR, NULL, + <tng_fops, NULL); + + if (!lttng_dentry && !lttng_proc_dentry) { + printk(KERN_ERR "Error creating LTTng control file\n"); + ret = -ENOMEM; + goto error; + } +error: + return ret; +} + +void __exit ltt_debugfs_abi_exit(void) +{ + if (lttng_dentry) + debugfs_remove(lttng_dentry); + if (lttng_proc_dentry) + remove_proc_entry("lttng", NULL); +} diff --git a/drivers/staging/lttng/ltt-debugfs-abi.h b/drivers/staging/lttng/ltt-debugfs-abi.h new file mode 100644 index 0000000..42bc9fd --- /dev/null +++ b/drivers/staging/lttng/ltt-debugfs-abi.h @@ -0,0 +1,153 @@ +#ifndef _LTT_DEBUGFS_ABI_H +#define _LTT_DEBUGFS_ABI_H + +/* + * ltt-debugfs-abi.h + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng debugfs ABI header + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/fs.h> + +#define LTTNG_SYM_NAME_LEN 128 + +enum lttng_kernel_instrumentation { + LTTNG_KERNEL_TRACEPOINT = 0, + LTTNG_KERNEL_KPROBE = 1, + LTTNG_KERNEL_FUNCTION = 2, + LTTNG_KERNEL_KRETPROBE = 3, + LTTNG_KERNEL_NOOP = 4, /* not hooked */ + LTTNG_KERNEL_SYSCALL = 5, +}; + +/* + * LTTng consumer mode + */ +enum lttng_kernel_output { + LTTNG_KERNEL_SPLICE = 0, + LTTNG_KERNEL_MMAP = 1, +}; + +/* + * LTTng DebugFS ABI structures. + */ + +struct lttng_kernel_channel { + int overwrite; /* 1: overwrite, 0: discard */ + uint64_t subbuf_size; /* in bytes */ + uint64_t num_subbuf; + unsigned int switch_timer_interval; /* usecs */ + unsigned int read_timer_interval; /* usecs */ + enum lttng_kernel_output output; /* splice, mmap */ +}; + +struct lttng_kernel_kretprobe { + uint64_t addr; + + uint64_t offset; + char symbol_name[LTTNG_SYM_NAME_LEN]; +}; + +/* + * Either addr is used, or symbol_name and offset. + */ +struct lttng_kernel_kprobe { + uint64_t addr; + + uint64_t offset; + char symbol_name[LTTNG_SYM_NAME_LEN]; +}; + +struct lttng_kernel_function_tracer { + char symbol_name[LTTNG_SYM_NAME_LEN]; +}; + +/* + * For syscall tracing, name = '\0' means "enable all". + */ +struct lttng_kernel_event { + char name[LTTNG_SYM_NAME_LEN]; /* event name */ + enum lttng_kernel_instrumentation instrumentation; + /* Per instrumentation type configuration */ + union { + struct lttng_kernel_kretprobe kretprobe; + struct lttng_kernel_kprobe kprobe; + struct lttng_kernel_function_tracer ftrace; + } u; +}; + +struct lttng_kernel_tracer_version { + uint32_t version; + uint32_t patchlevel; + uint32_t sublevel; +}; + +enum lttng_kernel_calibrate_type { + LTTNG_KERNEL_CALIBRATE_KRETPROBE, +}; + +struct lttng_kernel_calibrate { + enum lttng_kernel_calibrate_type type; /* type (input) */ +}; + +enum lttng_kernel_context_type { + LTTNG_KERNEL_CONTEXT_PID = 0, + LTTNG_KERNEL_CONTEXT_PERF_COUNTER = 1, + LTTNG_KERNEL_CONTEXT_PROCNAME = 2, + LTTNG_KERNEL_CONTEXT_PRIO = 3, + LTTNG_KERNEL_CONTEXT_NICE = 4, + LTTNG_KERNEL_CONTEXT_VPID = 5, + LTTNG_KERNEL_CONTEXT_TID = 6, + LTTNG_KERNEL_CONTEXT_VTID = 7, + LTTNG_KERNEL_CONTEXT_PPID = 8, + LTTNG_KERNEL_CONTEXT_VPPID = 9, +}; + +struct lttng_kernel_perf_counter_ctx { + uint32_t type; + uint64_t config; + char name[LTTNG_SYM_NAME_LEN]; +}; + +struct lttng_kernel_context { + enum lttng_kernel_context_type ctx; + union { + struct lttng_kernel_perf_counter_ctx perf_counter; + } u; +}; + +/* LTTng file descriptor ioctl */ +#define LTTNG_KERNEL_SESSION _IO(0xF6, 0x40) +#define LTTNG_KERNEL_TRACER_VERSION \ + _IOR(0xF6, 0x41, struct lttng_kernel_tracer_version) +#define LTTNG_KERNEL_TRACEPOINT_LIST _IO(0xF6, 0x42) +#define LTTNG_KERNEL_WAIT_QUIESCENT _IO(0xF6, 0x43) +#define LTTNG_KERNEL_CALIBRATE \ + _IOWR(0xF6, 0x44, struct lttng_kernel_calibrate) + +/* Session FD ioctl */ +#define LTTNG_KERNEL_METADATA \ + _IOW(0xF6, 0x50, struct lttng_kernel_channel) +#define LTTNG_KERNEL_CHANNEL \ + _IOW(0xF6, 0x51, struct lttng_kernel_channel) +#define LTTNG_KERNEL_SESSION_START _IO(0xF6, 0x52) +#define LTTNG_KERNEL_SESSION_STOP _IO(0xF6, 0x53) + +/* Channel FD ioctl */ +#define LTTNG_KERNEL_STREAM _IO(0xF6, 0x60) +#define LTTNG_KERNEL_EVENT \ + _IOW(0xF6, 0x61, struct lttng_kernel_event) + +/* Event and Channel FD ioctl */ +#define LTTNG_KERNEL_CONTEXT \ + _IOW(0xF6, 0x70, struct lttng_kernel_context) + +/* Event, Channel and Session ioctl */ +#define LTTNG_KERNEL_ENABLE _IO(0xF6, 0x80) +#define LTTNG_KERNEL_DISABLE _IO(0xF6, 0x81) + +#endif /* _LTT_DEBUGFS_ABI_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 15/20] lttng: Add documentation and TODO files 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (13 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 14/20] lttng: debugfs and procfs ABI Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 16/20] lttng: add system call instrumentation probe Mathieu Desnoyers ` (5 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/LICENSE | 27 ++++++++ drivers/staging/lttng/README | 48 ++++++++++++++ drivers/staging/lttng/TODO | 137 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/LICENSE create mode 100644 drivers/staging/lttng/README create mode 100644 drivers/staging/lttng/TODO diff --git a/drivers/staging/lttng/LICENSE b/drivers/staging/lttng/LICENSE new file mode 100644 index 0000000..bb880bf --- /dev/null +++ b/drivers/staging/lttng/LICENSE @@ -0,0 +1,27 @@ +LTTng modules licensing +Mathieu Desnoyers +June 2, 2011 + +* LGPLv2.1/GPLv2 dual-license + +The files contained within this package are licensed under +LGPLv2.1/GPLv2 dual-license (see lgpl-2.1.txt and gpl-2.0.txt for +details), except for files identified by the following sections. + +* GPLv2 license + +These files are licensed exclusively under the GPLv2 license. See +gpl-2.0.txt for details. + +lib/ringbuffer/ring_buffer_splice.c +lib/ringbuffer/ring_buffer_mmap.c +instrumentation/events/mainline/*.h +instrumentation/events/lttng-modules/*.h + +* MIT-style license + +These files are licensed under an MIT-style license: + +lib/prio_heap/lttng_prio_heap.h +lib/prio_heap/lttng_prio_heap.c +lib/bitfield.h diff --git a/drivers/staging/lttng/README b/drivers/staging/lttng/README new file mode 100644 index 0000000..a154d6e --- /dev/null +++ b/drivers/staging/lttng/README @@ -0,0 +1,48 @@ +LTTng 2.0 modules + +Mathieu Desnoyers +November 1st, 2011 + +LTTng 2.0 kernel modules is currently part of the Linux kernel staging +tree. It features (new features since LTTng 0.x): + +- Produces CTF (Common Trace Format) natively, + (http://www.efficios.com/ctf) +- Tracepoints, Function tracer, CPU Performance Monitoring Unit (PMU) + counters, kprobes, and kretprobes support, +- Integrated interface for both kernel and userspace tracing, +- Have the ability to attach "context" information to events in the + trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc). + All the extra information fields to be collected with events are + optional, specified on a per-tracing-session basis (except for + timestamp and event id, which are mandatory). + +To build and install, you need to select "Staging" modules, and the +LTTng kernel tracer. + +Use lttng-tools to control the tracer. LTTng tools should automatically +load the kernel modules when needed. Use Babeltrace to print traces as a +human-readable text log. These tools are available at the following URL: +http://lttng.org/lttng2.0 + +Please note that the LTTng-UST 2.0 (user-space tracing counterpart of +LTTng 2.0) is now ready to be used, but still only available from the +git repository. + +So far, it has been tested on vanilla Linux kernels 2.6.38, 2.6.39 and +3.0 (on x86 32/64-bit, and powerpc 32-bit at the moment, build tested on +ARM). It should work fine with newer kernels and other architectures, +but expect build issues with kernels older than 2.6.36. The clock source +currently used is the standard gettimeofday (slower, less scalable and +less precise than the LTTng 0.x clocks). Support for LTTng 0.x clocks +will be added back soon into LTTng 2.0. Please note that lttng-modules +2.0 can build on a Linux kernel patched with the LTTng 0.x patchset, but +the lttng-modules 2.0 replace the lttng-modules 0.x, so both tracers +cannot be installed at the same time for a given kernel version. + +* Note about Perf PMU counters support + +Each PMU counter has its zero value set when it is attached to a context with +add-context. Therefore, it is normal that the same counters attached to both the +stream context and event context show different values for a given event; what +matters is that they increment at the same rate. diff --git a/drivers/staging/lttng/TODO b/drivers/staging/lttng/TODO new file mode 100644 index 0000000..3fdc5e6 --- /dev/null +++ b/drivers/staging/lttng/TODO @@ -0,0 +1,137 @@ +Please contact Mathieu Desnoyers <mathieu.desnoyers at efficios.com> for +questions about this TODO list. The "Cleanup/Testing" section would be +good to go through before integration into mainline. The "Features" +section is a wish list of features to complete before releasing the +"LTTng 2.0" final version, but are not required to have LTTng working. +These features are mostly performance enhancements and instrumentation +enhancements. + +TODO: + +A) Cleanup/Testing + + 1) Remove debugfs "lttng" file (keep only procfs "lttng" file). + The rationale for this is that this file is needed for + user-level tracing support (LTTng-UST 2.0) intended to be + used on production system, and therefore should be present as + part of a "usually mounted" filesystem rather than a debug + filesystem. + + 2) Cleanup wrappers. The drivers/staging/lttng/wrapper directory + contains various wrapper headers that use kallsyms lookups to + work around some missing EXPORT_SYMBOL_GPL() in the mainline + kernel. Ideally, those few symbols should become exported to + modules by the kernel. + + 3) Test lib ring buffer snapshot feature. + When working on the lttngtop project, Julien Desfossez + reported that he needed to push the consumer position + forward explicitely with lib_ring_buffer_put_next_subbuf. + This means that although the usual case of pairs of + lib_ring_buffer_get_next_subbuf/lib_ring_buffer_put_next_subbuf + work fine, there is probably a problem that needs to be + investigated in + lib_ring_buffer_get_subbuf/lib_ring_buffer_put_subbuf, which + depend on the producer to push the reader position. + Contact: Julien Desfossez <julien.desfossez at polymtl.ca> + + 4) Test latest -rt kernel support. + There has been report of corrupted traces when tracing a + 3.0.10-rt27 in the area of access_ok() system call event. + Still has to be investigated. Cannot be reproduced with + mainline kernel. + Contact: Yannick Brosseau <yannick.brosseau at polymtl.ca> + +B) Features + + 1) Integration of the LTTng 0.x trace clocks into + LTTng 2.0. + Currently using mainline kernel monotonic clock. NMIs can + therefore not be traced, and this causes a significant + performance degradation compared to the LTTng 0.x trace + clocks. Imply the creation of drivers/staging/lttng/arch to + contain the arch-specific clock support files. + * Dependency: addition of clock descriptions to CTF. + See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary + for the LTTng 0.x git tree. + + 2) Port OMAP3 LTTng trace clocks to x86 to support systems + without constant TSC. + * Dependency: (B.1) + See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary + for the LTTng 0.x git tree. + + 3) Implement mmap operation on an anonymous file created by a + LTTNG_KERNEL_CLOCK ioctl to export data to export + synchronized kernel and user-level LTTng trace clocks: + with: + - shared per-cpu data, + - read seqlock. + The content exported by this shared memory area will be + arch-specific. + * Dependency: (B.1) && (B.2) + See: http://git.lttng.org/?p=linux-2.6-lttng.git;a=summary + for the LTTng 0.x git tree, which has vDSO support for + LTTng trace clock on the x86 architecture. + + 3) Integrate the "statedump" module from LTTng 0.x into LTTng + 2.0. + * Dependency: addition of "dynamic enumerations" type to CTF. + See: http://git.lttng.org/?p=lttng-modules.git;a=shortlog;h=refs/heads/v0.19-stable + ltt-statedump.c + + 4) Generate system call TRACE_EVENT headers for all + architectures (currently done: x86 32/64). + + 5) Define "unknown" system calls into instrumentation/syscalls + override files / or do SYSCALL_DEFINE improvements to + mainline kernel to allow automatic generation of these + missing system call descriptions. + + 6) Create missing tracepoint event headers files into + instrumentation/events from headers located in + include/trace/events/. Choice: either do as currently done, + and copy those headers locally into the lttng driver and + perform the modifications locally, or push TRACE_EVENT API + modification into mainline headers, which would require + collaboration from Ftrace/Perf maintainers. + + 7) Poll: implement a poll and/or epoll exclusive wakeup scheme, + which contradicts POSIX, but protect multiple consumer + threads from thundering herd effect. + + 8) Re-integrate sample modules from libringbuffer into + lttng driver. Those modules can be used as example of how to + use libringbuffer in other contexts than LTTng, and are + useful to perform benchmarks of the ringbuffer library. + See: http://www.efficios.com/ringbuffer + + 9) NOHZ support for lib ring buffer. NOHZ infrastructure in the + Linux kernel does not support notifiers chains, which does + not let LTTng play nicely with low power consumption setups + for flight recorder (overwrite mode) live traces. One way to + allow integration between NOHZ and LTTng would be to add + support for such notifiers into NOHZ kernel infrastructure. + + 10) Turn drivers/staging/lttng/ltt-probes.c probe_list into a + hash table. Turns O(n^2) trace systems registration (cost + for n systems) into O(n). (O(1) per system) + + 11) drivers/staging/lttng/probes/lttng-ftrace.c: + LTTng currently uses kretprobes for per-function tracing, + not the function tracer. So lttng-ftrace.c should be used + for "all" function tracing. + + 12) drivers/staging/lttng/probes/lttng-types.c: + This is a currently unused placeholder to export entire C + type declarations into the trace metadata, e.g. for support + of describing the layout of structures/enumeration mapping + along with syscall entry events. The design of this support + will likely change though, and become integrated with the + TRACE_EVENT support within lttng, by adding new macros, and + support for generation of metadata from these macros, to + allow description of those compound types/enumerations. + +Please send patches +To: Greg Kroah-Hartman <greg at kroah.com> +To: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 16/20] lttng: add system call instrumentation probe 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (14 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 15/20] lttng: Add documentation and TODO files Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 17/20] lttng: probe callbacks Mathieu Desnoyers ` (4 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/lttng-syscalls.c | 438 ++++++++++++++++++++++++++++++++ 1 files changed, 438 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/lttng-syscalls.c diff --git a/drivers/staging/lttng/lttng-syscalls.c b/drivers/staging/lttng/lttng-syscalls.c new file mode 100644 index 0000000..16624a7f7 --- /dev/null +++ b/drivers/staging/lttng/lttng-syscalls.c @@ -0,0 +1,438 @@ +/* + * lttng-syscalls.c + * + * Copyright 2010-2011 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng syscall probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/compat.h> +#include <asm/ptrace.h> +#include <asm/syscall.h> + +#include "ltt-events.h" + +#ifndef CONFIG_COMPAT +static inline int is_compat_task(void) +{ + return 0; +} +#endif + +static +void syscall_entry_probe(void *__data, struct pt_regs *regs, long id); + +/* + * Take care of NOARGS not supported by mainline. + */ +#define DECLARE_EVENT_CLASS_NOARGS(name, tstruct, assign, print) +#define DEFINE_EVENT_NOARGS(template, name) +#define TRACE_EVENT_NOARGS(name, struct, assign, print) + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TP_MODULE_OVERRIDE +#define TRACE_INCLUDE_PATH ../instrumentation/syscalls/headers + +#define PARAMS(args...) args + +#undef TRACE_SYSTEM + +/* Hijack probe callback for system calls */ +#undef TP_PROBE_CB +#define TP_PROBE_CB(_template) &syscall_entry_probe +#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ + TRACE_EVENT(_name, PARAMS(_proto), PARAMS(_args),\ + PARAMS(_struct), PARAMS(_assign), PARAMS(_printk)) +#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ + DECLARE_EVENT_CLASS_NOARGS(_name, PARAMS(_struct), PARAMS(_assign),\ + PARAMS(_printk)) +#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ + DEFINE_EVENT_NOARGS(_template, _name) +#define TRACE_SYSTEM syscalls_integers +#include "instrumentation/syscalls/headers/syscalls_integers.h" +#undef TRACE_SYSTEM +#define TRACE_SYSTEM syscalls_pointers +#include "instrumentation/syscalls/headers/syscalls_pointers.h" +#undef TRACE_SYSTEM +#undef SC_TRACE_EVENT +#undef SC_DECLARE_EVENT_CLASS_NOARGS +#undef SC_DEFINE_EVENT_NOARGS + +#define TRACE_SYSTEM syscalls_unknown +#include "instrumentation/syscalls/headers/syscalls_unknown.h" +#undef TRACE_SYSTEM + +/* For compat syscalls */ +#undef _TRACE_SYSCALLS_integers_H +#undef _TRACE_SYSCALLS_pointers_H + +/* Hijack probe callback for system calls */ +#undef TP_PROBE_CB +#define TP_PROBE_CB(_template) &syscall_entry_probe +#define SC_TRACE_EVENT(_name, _proto, _args, _struct, _assign, _printk) \ + TRACE_EVENT(compat_##_name, PARAMS(_proto), PARAMS(_args), \ + PARAMS(_struct), PARAMS(_assign), \ + PARAMS(_printk)) +#define SC_DECLARE_EVENT_CLASS_NOARGS(_name, _struct, _assign, _printk) \ + DECLARE_EVENT_CLASS_NOARGS(compat_##_name, PARAMS(_struct), \ + PARAMS(_assign), PARAMS(_printk)) +#define SC_DEFINE_EVENT_NOARGS(_template, _name) \ + DEFINE_EVENT_NOARGS(compat_##_template, compat_##_name) +#define TRACE_SYSTEM compat_syscalls_integers +#include "instrumentation/syscalls/headers/compat_syscalls_integers.h" +#undef TRACE_SYSTEM +#define TRACE_SYSTEM compat_syscalls_pointers +#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h" +#undef TRACE_SYSTEM +#undef SC_TRACE_EVENT +#undef SC_DECLARE_EVENT_CLASS_NOARGS +#undef SC_DEFINE_EVENT_NOARGS +#undef TP_PROBE_CB + +#undef TP_MODULE_OVERRIDE +#undef LTTNG_PACKAGE_BUILD +#undef CREATE_TRACE_POINTS + +struct trace_syscall_entry { + void *func; + const struct lttng_event_desc *desc; + const struct lttng_event_field *fields; + unsigned int nrargs; +}; + +#define CREATE_SYSCALL_TABLE + +#undef TRACE_SYSCALL_TABLE +#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \ + [ _nr ] = { \ + .func = __event_probe__##_template, \ + .nrargs = (_nrargs), \ + .fields = __event_fields___##_template, \ + .desc = &__event_desc___##_name, \ + }, + +static const struct trace_syscall_entry sc_table[] = { +#include "instrumentation/syscalls/headers/syscalls_integers.h" +#include "instrumentation/syscalls/headers/syscalls_pointers.h" +}; + +#undef TRACE_SYSCALL_TABLE +#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \ + [ _nr ] = { \ + .func = __event_probe__##compat_##_template, \ + .nrargs = (_nrargs), \ + .fields = __event_fields___##compat_##_template,\ + .desc = &__event_desc___##compat_##_name, \ + }, + +/* Create compatibility syscall table */ +const struct trace_syscall_entry compat_sc_table[] = { +#include "instrumentation/syscalls/headers/compat_syscalls_integers.h" +#include "instrumentation/syscalls/headers/compat_syscalls_pointers.h" +}; + +#undef CREATE_SYSCALL_TABLE + +static void syscall_entry_unknown(struct ltt_event *event, + struct pt_regs *regs, unsigned int id) +{ + unsigned long args[UNKNOWN_SYSCALL_NRARGS]; + + syscall_get_arguments(current, regs, 0, UNKNOWN_SYSCALL_NRARGS, args); + if (unlikely(is_compat_task())) + __event_probe__compat_sys_unknown(event, id, args); + else + __event_probe__sys_unknown(event, id, args); +} + +void syscall_entry_probe(void *__data, struct pt_regs *regs, long id) +{ + struct ltt_channel *chan = __data; + struct ltt_event *event, *unknown_event; + const struct trace_syscall_entry *table, *entry; + size_t table_len; + + if (unlikely(is_compat_task())) { + table = compat_sc_table; + table_len = ARRAY_SIZE(compat_sc_table); + unknown_event = chan->sc_compat_unknown; + } else { + table = sc_table; + table_len = ARRAY_SIZE(sc_table); + unknown_event = chan->sc_unknown; + } + if (unlikely(id >= table_len)) { + syscall_entry_unknown(unknown_event, regs, id); + return; + } + if (unlikely(is_compat_task())) + event = chan->compat_sc_table[id]; + else + event = chan->sc_table[id]; + if (unlikely(!event)) { + syscall_entry_unknown(unknown_event, regs, id); + return; + } + entry = &table[id]; + WARN_ON_ONCE(!entry); + + switch (entry->nrargs) { + case 0: + { + void (*fptr)(void *__data) = entry->func; + + fptr(event); + break; + } + case 1: + { + void (*fptr)(void *__data, unsigned long arg0) = entry->func; + unsigned long args[1]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0]); + break; + } + case 2: + { + void (*fptr)(void *__data, + unsigned long arg0, + unsigned long arg1) = entry->func; + unsigned long args[2]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0], args[1]); + break; + } + case 3: + { + void (*fptr)(void *__data, + unsigned long arg0, + unsigned long arg1, + unsigned long arg2) = entry->func; + unsigned long args[3]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0], args[1], args[2]); + break; + } + case 4: + { + void (*fptr)(void *__data, + unsigned long arg0, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3) = entry->func; + unsigned long args[4]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0], args[1], args[2], args[3]); + break; + } + case 5: + { + void (*fptr)(void *__data, + unsigned long arg0, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4) = entry->func; + unsigned long args[5]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0], args[1], args[2], args[3], args[4]); + break; + } + case 6: + { + void (*fptr)(void *__data, + unsigned long arg0, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5) = entry->func; + unsigned long args[6]; + + syscall_get_arguments(current, regs, 0, entry->nrargs, args); + fptr(event, args[0], args[1], args[2], + args[3], args[4], args[5]); + break; + } + default: + break; + } +} + +/* noinline to diminish caller stack size */ +static +int fill_table(const struct trace_syscall_entry *table, size_t table_len, + struct ltt_event **chan_table, struct ltt_channel *chan, void *filter) +{ + const struct lttng_event_desc *desc; + unsigned int i; + + /* Allocate events for each syscall, insert into table */ + for (i = 0; i < table_len; i++) { + struct lttng_kernel_event ev; + desc = table[i].desc; + + if (!desc) { + /* Unknown syscall */ + continue; + } + /* + * Skip those already populated by previous failed + * register for this channel. + */ + if (chan_table[i]) + continue; + memset(&ev, 0, sizeof(ev)); + strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); + ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev.instrumentation = LTTNG_KERNEL_NOOP; + chan_table[i] = ltt_event_create(chan, &ev, filter, + desc); + if (!chan_table[i]) { + /* + * If something goes wrong in event registration + * after the first one, we have no choice but to + * leave the previous events in there, until + * deleted by session teardown. + */ + return -EINVAL; + } + } + return 0; +} + +int lttng_syscalls_register(struct ltt_channel *chan, void *filter) +{ + struct lttng_kernel_event ev; + int ret; + + wrapper_vmalloc_sync_all(); + + if (!chan->sc_table) { + /* create syscall table mapping syscall to events */ + chan->sc_table = kzalloc(sizeof(struct ltt_event *) + * ARRAY_SIZE(sc_table), GFP_KERNEL); + if (!chan->sc_table) + return -ENOMEM; + } + +#ifdef CONFIG_COMPAT + if (!chan->compat_sc_table) { + /* create syscall table mapping compat syscall to events */ + chan->compat_sc_table = kzalloc(sizeof(struct ltt_event *) + * ARRAY_SIZE(compat_sc_table), GFP_KERNEL); + if (!chan->compat_sc_table) + return -ENOMEM; + } +#endif + if (!chan->sc_unknown) { + const struct lttng_event_desc *desc = + &__event_desc___sys_unknown; + + memset(&ev, 0, sizeof(ev)); + strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); + ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev.instrumentation = LTTNG_KERNEL_NOOP; + chan->sc_unknown = ltt_event_create(chan, &ev, filter, + desc); + if (!chan->sc_unknown) { + return -EINVAL; + } + } + + if (!chan->sc_compat_unknown) { + const struct lttng_event_desc *desc = + &__event_desc___compat_sys_unknown; + + memset(&ev, 0, sizeof(ev)); + strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); + ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev.instrumentation = LTTNG_KERNEL_NOOP; + chan->sc_compat_unknown = ltt_event_create(chan, &ev, filter, + desc); + if (!chan->sc_compat_unknown) { + return -EINVAL; + } + } + + if (!chan->sc_exit) { + const struct lttng_event_desc *desc = + &__event_desc___exit_syscall; + + memset(&ev, 0, sizeof(ev)); + strncpy(ev.name, desc->name, LTTNG_SYM_NAME_LEN); + ev.name[LTTNG_SYM_NAME_LEN - 1] = '\0'; + ev.instrumentation = LTTNG_KERNEL_NOOP; + chan->sc_exit = ltt_event_create(chan, &ev, filter, + desc); + if (!chan->sc_exit) { + return -EINVAL; + } + } + + ret = fill_table(sc_table, ARRAY_SIZE(sc_table), + chan->sc_table, chan, filter); + if (ret) + return ret; +#ifdef CONFIG_COMPAT + ret = fill_table(compat_sc_table, ARRAY_SIZE(compat_sc_table), + chan->compat_sc_table, chan, filter); + if (ret) + return ret; +#endif + ret = tracepoint_probe_register("sys_enter", + (void *) syscall_entry_probe, chan); + if (ret) + return ret; + /* + * We change the name of sys_exit tracepoint due to namespace + * conflict with sys_exit syscall entry. + */ + ret = tracepoint_probe_register("sys_exit", + (void *) __event_probe__exit_syscall, + chan->sc_exit); + if (ret) { + WARN_ON_ONCE(tracepoint_probe_unregister("sys_enter", + (void *) syscall_entry_probe, chan)); + } + return ret; +} + +/* + * Only called at session destruction. + */ +int lttng_syscalls_unregister(struct ltt_channel *chan) +{ + int ret; + + if (!chan->sc_table) + return 0; + ret = tracepoint_probe_unregister("sys_exit", + (void *) __event_probe__exit_syscall, + chan->sc_exit); + if (ret) + return ret; + ret = tracepoint_probe_unregister("sys_enter", + (void *) syscall_entry_probe, chan); + if (ret) + return ret; + /* ltt_event destroy will be performed by ltt_session_destroy() */ + kfree(chan->sc_table); +#ifdef CONFIG_COMPAT + kfree(chan->compat_sc_table); +#endif + return 0; +} -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 17/20] lttng: probe callbacks 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (15 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 16/20] lttng: add system call instrumentation probe Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 18/20] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers ` (3 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Implement the LTTng probe callbacks. One notable file here is lttng-events.h, which is the core implementation of the LTTng TRACE_EVENT macros for generation of probes and tracepoint decription from the TRACE_EVENT declarations. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/probes/Makefile | 37 ++ drivers/staging/lttng/probes/define_trace.h | 132 ++++ drivers/staging/lttng/probes/lttng-events-reset.h | 84 +++ drivers/staging/lttng/probes/lttng-events.h | 703 +++++++++++++++++++++ drivers/staging/lttng/probes/lttng-ftrace.c | 188 ++++++ drivers/staging/lttng/probes/lttng-kprobes.c | 164 +++++ drivers/staging/lttng/probes/lttng-kretprobes.c | 277 ++++++++ drivers/staging/lttng/probes/lttng-probe-block.c | 31 + drivers/staging/lttng/probes/lttng-probe-irq.c | 31 + drivers/staging/lttng/probes/lttng-probe-kvm.c | 31 + drivers/staging/lttng/probes/lttng-probe-lttng.c | 24 + drivers/staging/lttng/probes/lttng-probe-sched.c | 30 + drivers/staging/lttng/probes/lttng-type-list.h | 21 + drivers/staging/lttng/probes/lttng-types.c | 49 ++ drivers/staging/lttng/probes/lttng-types.h | 72 +++ drivers/staging/lttng/probes/lttng.h | 15 + 16 files changed, 1889 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/probes/Makefile create mode 100644 drivers/staging/lttng/probes/define_trace.h create mode 100644 drivers/staging/lttng/probes/lttng-events-reset.h create mode 100644 drivers/staging/lttng/probes/lttng-events.h create mode 100644 drivers/staging/lttng/probes/lttng-ftrace.c create mode 100644 drivers/staging/lttng/probes/lttng-kprobes.c create mode 100644 drivers/staging/lttng/probes/lttng-kretprobes.c create mode 100644 drivers/staging/lttng/probes/lttng-probe-block.c create mode 100644 drivers/staging/lttng/probes/lttng-probe-irq.c create mode 100644 drivers/staging/lttng/probes/lttng-probe-kvm.c create mode 100644 drivers/staging/lttng/probes/lttng-probe-lttng.c create mode 100644 drivers/staging/lttng/probes/lttng-probe-sched.c create mode 100644 drivers/staging/lttng/probes/lttng-type-list.h create mode 100644 drivers/staging/lttng/probes/lttng-types.c create mode 100644 drivers/staging/lttng/probes/lttng-types.h create mode 100644 drivers/staging/lttng/probes/lttng.h diff --git a/drivers/staging/lttng/probes/Makefile b/drivers/staging/lttng/probes/Makefile new file mode 100644 index 0000000..bdc1179 --- /dev/null +++ b/drivers/staging/lttng/probes/Makefile @@ -0,0 +1,37 @@ +# +# Makefile for the LTT probes. +# + +ccflags-y += -I$(PWD)/probes +obj-m += lttng-types.o + +obj-m += lttng-probe-lttng.o + +obj-m += lttng-probe-sched.o +obj-m += lttng-probe-irq.o + +ifneq ($(CONFIG_KVM),) +obj-m += lttng-probe-kvm.o +endif + +ifneq ($(CONFIG_BLOCK),) +ifneq ($(CONFIG_EVENT_TRACING),) # need blk_cmd_buf_len +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ + echo "lttng-probe-block.o" ; fi;) +endif +endif + +ifneq ($(CONFIG_KPROBES),) +obj-m += lttng-kprobes.o +endif + + +ifneq ($(CONFIG_KRETPROBES),) +obj-m += lttng-kretprobes.o +endif + +ifneq ($(CONFIG_DYNAMIC_FTRACE),) +obj-m += lttng-ftrace.o +endif diff --git a/drivers/staging/lttng/probes/define_trace.h b/drivers/staging/lttng/probes/define_trace.h new file mode 100644 index 0000000..3c9a467 --- /dev/null +++ b/drivers/staging/lttng/probes/define_trace.h @@ -0,0 +1,132 @@ +/* + * define_trace.h + * + * Copyright (C) 2009 Steven Rostedt <rostedt at goodmis.org> + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +/* + * Trace files that want to automate creationg of all tracepoints defined + * in their file should include this file. The following are macros that the + * trace file may define: + * + * TRACE_SYSTEM defines the system the tracepoint is for + * + * TRACE_INCLUDE_FILE if the file name is something other than TRACE_SYSTEM.h + * This macro may be defined to tell define_trace.h what file to include. + * Note, leave off the ".h". + * + * TRACE_INCLUDE_PATH if the path is something other than core kernel include/trace + * then this macro can define the path to use. Note, the path is relative to + * define_trace.h, not the file including it. Full path names for out of tree + * modules must be used. + */ + +#ifdef CREATE_TRACE_POINTS + +/* Prevent recursion */ +#undef CREATE_TRACE_POINTS + +#include <linux/stringify.h> +/* + * module.h includes tracepoints, and because ftrace.h + * pulls in module.h: + * trace/ftrace.h -> linux/ftrace_event.h -> linux/perf_event.h -> + * linux/ftrace.h -> linux/module.h + * we must include module.h here before we play with any of + * the TRACE_EVENT() macros, otherwise the tracepoints included + * by module.h may break the build. + */ +#include <linux/module.h> + +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DEFINE_TRACE(name) + +#undef TRACE_EVENT_CONDITION +#define TRACE_EVENT_CONDITION(name, proto, args, cond, tstruct, assign, print) \ + TRACE_EVENT(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)) + +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct, \ + assign, print, reg, unreg) \ + DEFINE_TRACE_FN(name, reg, unreg) + +#undef DEFINE_EVENT +#define DEFINE_EVENT(template, name, proto, args) \ + DEFINE_TRACE(name) + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_TRACE(name) + +#undef DEFINE_EVENT_CONDITION +#define DEFINE_EVENT_CONDITION(template, name, proto, args, cond) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +#undef DECLARE_TRACE +#define DECLARE_TRACE(name, proto, args) \ + DEFINE_TRACE(name) + +#undef TRACE_INCLUDE +#undef __TRACE_INCLUDE + +#ifndef TRACE_INCLUDE_FILE +# define TRACE_INCLUDE_FILE TRACE_SYSTEM +# define UNDEF_TRACE_INCLUDE_FILE +#endif + +#ifndef TRACE_INCLUDE_PATH +# define __TRACE_INCLUDE(system) <trace/events/system.h> +# define UNDEF_TRACE_INCLUDE_PATH +#else +# define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h) +#endif + +# define TRACE_INCLUDE(system) __TRACE_INCLUDE(system) + +/* Let the trace headers be reread */ +#define TRACE_HEADER_MULTI_READ + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* Make all open coded DECLARE_TRACE nops */ +#undef DECLARE_TRACE +#define DECLARE_TRACE(name, proto, args) + +#ifdef LTTNG_PACKAGE_BUILD +#include "lttng-events.h" +#endif + +#undef TRACE_EVENT +#undef TRACE_EVENT_FN +#undef TRACE_EVENT_CONDITION +#undef DECLARE_EVENT_CLASS +#undef DEFINE_EVENT +#undef DEFINE_EVENT_PRINT +#undef DEFINE_EVENT_CONDITION +#undef TRACE_HEADER_MULTI_READ +#undef DECLARE_TRACE + +/* Only undef what we defined in this file */ +#ifdef UNDEF_TRACE_INCLUDE_FILE +# undef TRACE_INCLUDE_FILE +# undef UNDEF_TRACE_INCLUDE_FILE +#endif + +#ifdef UNDEF_TRACE_INCLUDE_PATH +# undef TRACE_INCLUDE_PATH +# undef UNDEF_TRACE_INCLUDE_PATH +#endif + +/* We may be processing more files */ +#define CREATE_TRACE_POINTS + +#endif /* CREATE_TRACE_POINTS */ diff --git a/drivers/staging/lttng/probes/lttng-events-reset.h b/drivers/staging/lttng/probes/lttng-events-reset.h new file mode 100644 index 0000000..c8a1046 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-events-reset.h @@ -0,0 +1,84 @@ +/* + * lttng-events-reset.h + * + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +/* Reset macros used within TRACE_EVENT to "nothing" */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding) + +#undef __dynamic_array_len +#define __dynamic_array_len(_type, _item, _length) + +#undef __string +#define __string(_item, _src) + +#undef tp_assign +#define tp_assign(dest, src) + +#undef tp_memcpy +#define tp_memcpy(dest, src, len) + +#undef tp_memcpy_dyn +#define tp_memcpy_dyn(dest, src, len) + +#undef tp_strcpy +#define tp_strcpy(dest, src) + +#undef __get_str +#define __get_str(field) + +#undef __get_dynamic_array +#define __get_dynamic_array(field) + +#undef __get_dynamic_array_len +#define __get_dynamic_array_len(field) + +#undef TP_PROTO +#define TP_PROTO(args...) + +#undef TP_ARGS +#define TP_ARGS(args...) + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) + +#undef TP_fast_assign +#define TP_fast_assign(args...) + +#undef __perf_count +#define __perf_count(args...) + +#undef __perf_addr +#define __perf_addr(args...) + +#undef TP_perf_assign +#define TP_perf_assign(args...) + +#undef TP_printk +#define TP_printk(args...) + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) + +#undef DECLARE_EVENT_CLASS_NOARGS +#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) + +#undef DEFINE_EVENT +#define DEFINE_EVENT(_template, _name, _proto, _args) + +#undef DEFINE_EVENT_NOARGS +#define DEFINE_EVENT_NOARGS(_template, _name) + +#undef TRACE_EVENT_FLAGS +#define TRACE_EVENT_FLAGS(name, value) diff --git a/drivers/staging/lttng/probes/lttng-events.h b/drivers/staging/lttng/probes/lttng-events.h new file mode 100644 index 0000000..ff6273f --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-events.h @@ -0,0 +1,703 @@ +/* + * lttng-events.h + * + * Copyright (C) 2009 Steven Rostedt <rostedt at goodmis.org> + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/debugfs.h> +#include "lttng.h" +#include "lttng-types.h" +#include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "../wrapper/ringbuffer/frontend_types.h" +#include "../ltt-events.h" +#include "../ltt-tracer-core.h" + +/* + * Macro declarations used for all stages. + */ + +/* + * DECLARE_EVENT_CLASS can be used to add a generic function + * handlers for events. That is, if all events have the same + * parameters and just have distinct trace points. + * Each tracepoint can be defined with DEFINE_EVENT and that + * will map the DECLARE_EVENT_CLASS to the tracepoint. + * + * TRACE_EVENT is a one to one mapping between tracepoint and template. + */ + +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ + DECLARE_EVENT_CLASS(name, \ + PARAMS(proto), \ + PARAMS(args), \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)) \ + DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args)) + +#undef TRACE_EVENT_NOARGS +#define TRACE_EVENT_NOARGS(name, tstruct, assign, print) \ + DECLARE_EVENT_CLASS_NOARGS(name, \ + PARAMS(tstruct), \ + PARAMS(assign), \ + PARAMS(print)) \ + DEFINE_EVENT_NOARGS(name, name) + + +#undef DEFINE_EVENT_PRINT +#define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) + +/* Callbacks are meaningless to LTTng. */ +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct, \ + assign, print, reg, unreg) \ + TRACE_EVENT(name, PARAMS(proto), PARAMS(args), \ + PARAMS(tstruct), PARAMS(assign), PARAMS(print)) \ + +/* + * Stage 1 of the trace events. + * + * Create dummy trace calls for each events, verifying that the LTTng module + * TRACE_EVENT headers match the kernel arguments. Will be optimized out by the + * compiler. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#undef TP_PROTO +#define TP_PROTO(args...) args + +#undef TP_ARGS +#define TP_ARGS(args...) args + +#undef DEFINE_EVENT +#define DEFINE_EVENT(_template, _name, _proto, _args) \ +void trace_##_name(_proto); + +#undef DEFINE_EVENT_NOARGS +#define DEFINE_EVENT_NOARGS(_template, _name) \ +void trace_##_name(void *__data); + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 2 of the trace events. + * + * Create event field type metadata section. + * Each event produce an array of fields. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) \ + { \ + .name = #_item, \ + .type = __type_integer(_type, _order, _base, none), \ + }, + +#undef __field +#define __field(_type, _item) \ + __field_full(_type, _item, __BYTE_ORDER, 10) + +#undef __field_ext +#define __field_ext(_type, _item, _filter_type) \ + __field(_type, _item) + +#undef __field_hex +#define __field_hex(_type, _item) \ + __field_full(_type, _item, __BYTE_ORDER, 16) + +#undef __field_network +#define __field_network(_type, _item) \ + __field_full(_type, _item, __BIG_ENDIAN, 10) + +#undef __field_network_hex +#define __field_network_hex(_type, _item) \ + __field_full(_type, _item, __BIG_ENDIAN, 16) + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + { \ + .name = #_item, \ + .type = \ + { \ + .atype = atype_array, \ + .u.array = \ + { \ + .length = _length, \ + .elem_type = __type_integer(_type, _order, _base, _encoding), \ + }, \ + }, \ + }, + +#undef __array +#define __array(_type, _item, _length) \ + __array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, none) + +#undef __array_text +#define __array_text(_type, _item, _length) \ + __array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, UTF8) + +#undef __array_hex +#define __array_hex(_type, _item, _length) \ + __array_enc_ext(_type, _item, _length, __BYTE_ORDER, 16, none) + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ + { \ + .name = #_item, \ + .type = \ + { \ + .atype = atype_sequence, \ + .u.sequence = \ + { \ + .length_type = __type_integer(u32, __BYTE_ORDER, 10, none), \ + .elem_type = __type_integer(_type, _order, _base, _encoding), \ + }, \ + }, \ + }, + +#undef __dynamic_array +#define __dynamic_array(_type, _item, _length) \ + __dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, none) + +#undef __dynamic_array_text +#define __dynamic_array_text(_type, _item, _length) \ + __dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 10, UTF8) + +#undef __dynamic_array_hex +#define __dynamic_array_hex(_type, _item, _length) \ + __dynamic_array_enc_ext(_type, _item, _length, __BYTE_ORDER, 16, none) + +#undef __string +#define __string(_item, _src) \ + { \ + .name = #_item, \ + .type = \ + { \ + .atype = atype_string, \ + .u.basic.string.encoding = lttng_encode_UTF8, \ + }, \ + }, + +#undef __string_from_user +#define __string_from_user(_item, _src) \ + __string(_item, _src) + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args /* Only one used in this phase */ + +#undef DECLARE_EVENT_CLASS_NOARGS +#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \ + static const struct lttng_event_field __event_fields___##_name[] = { \ + _tstruct \ + }; + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ + DECLARE_EVENT_CLASS_NOARGS(_name, PARAMS(_tstruct), PARAMS(_assign), \ + PARAMS(_print)) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 3 of the trace events. + * + * Create probe callback prototypes. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#undef TP_PROTO +#define TP_PROTO(args...) args + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ +static void __event_probe__##_name(void *__data, _proto); + +#undef DECLARE_EVENT_CLASS_NOARGS +#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \ +static void __event_probe__##_name(void *__data); + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 3.9 of the trace events. + * + * Create event descriptions. + */ + +/* Named field types must be defined in lttng-types.h */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#ifndef TP_PROBE_CB +#define TP_PROBE_CB(_template) &__event_probe__##_template +#endif + +#undef DEFINE_EVENT_NOARGS +#define DEFINE_EVENT_NOARGS(_template, _name) \ +static const struct lttng_event_desc __event_desc___##_name = { \ + .fields = __event_fields___##_template, \ + .name = #_name, \ + .probe_callback = (void *) TP_PROBE_CB(_template), \ + .nr_fields = ARRAY_SIZE(__event_fields___##_template), \ + .owner = THIS_MODULE, \ +}; + +#undef DEFINE_EVENT +#define DEFINE_EVENT(_template, _name, _proto, _args) \ + DEFINE_EVENT_NOARGS(_template, _name) + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + + +/* + * Stage 4 of the trace events. + * + * Create an array of event description pointers. + */ + +/* Named field types must be defined in lttng-types.h */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#undef DEFINE_EVENT_NOARGS +#define DEFINE_EVENT_NOARGS(_template, _name) \ + &__event_desc___##_name, + +#undef DEFINE_EVENT +#define DEFINE_EVENT(_template, _name, _proto, _args) \ + DEFINE_EVENT_NOARGS(_template, _name) + +#define TP_ID1(_token, _system) _token##_system +#define TP_ID(_token, _system) TP_ID1(_token, _system) + +static const struct lttng_event_desc *TP_ID(__event_desc___, TRACE_SYSTEM)[] = { +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) +}; + +#undef TP_ID1 +#undef TP_ID + + +/* + * Stage 5 of the trace events. + * + * Create a toplevel descriptor for the whole probe. + */ + +#define TP_ID1(_token, _system) _token##_system +#define TP_ID(_token, _system) TP_ID1(_token, _system) + +/* non-const because list head will be modified when registered. */ +static __used struct lttng_probe_desc TP_ID(__probe_desc___, TRACE_SYSTEM) = { + .event_desc = TP_ID(__event_desc___, TRACE_SYSTEM), + .nr_events = ARRAY_SIZE(TP_ID(__event_desc___, TRACE_SYSTEM)), +}; + +#undef TP_ID1 +#undef TP_ID + +/* + * Stage 6 of the trace events. + * + * Create static inline function that calculates event size. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) \ + __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __event_len += sizeof(_type); + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ + __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __event_len += sizeof(_type) * (_length); + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(u32)); \ + __event_len += sizeof(u32); \ + __event_len += lib_ring_buffer_align(__event_len, ltt_alignof(_type)); \ + __dynamic_len[__dynamic_len_idx] = (_length); \ + __event_len += sizeof(_type) * __dynamic_len[__dynamic_len_idx]; \ + __dynamic_len_idx++; + +#undef __string +#define __string(_item, _src) \ + __event_len += __dynamic_len[__dynamic_len_idx++] = strlen(_src) + 1; + +/* + * strlen_user includes \0. If returns 0, it faulted, so we set size to + * 1 (\0 only). + */ +#undef __string_from_user +#define __string_from_user(_item, _src) \ + __event_len += __dynamic_len[__dynamic_len_idx++] = \ + min_t(size_t, strlen_user(_src), 1); + +#undef TP_PROTO +#define TP_PROTO(args...) args + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ +static inline size_t __event_get_size__##_name(size_t *__dynamic_len, _proto) \ +{ \ + size_t __event_len = 0; \ + unsigned int __dynamic_len_idx = 0; \ + \ + if (0) \ + (void) __dynamic_len_idx; /* don't warn if unused */ \ + _tstruct \ + return __event_len; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 7 of the trace events. + * + * Create static inline function that calculates event payload alignment. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) \ + __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ + __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + __event_align = max_t(size_t, __event_align, ltt_alignof(u32)); \ + __event_align = max_t(size_t, __event_align, ltt_alignof(_type)); + +#undef __string +#define __string(_item, _src) + +#undef __string_from_user +#define __string_from_user(_item, _src) + +#undef TP_PROTO +#define TP_PROTO(args...) args + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ +static inline size_t __event_get_align__##_name(_proto) \ +{ \ + size_t __event_align = 1; \ + _tstruct \ + return __event_align; \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + + +/* + * Stage 8 of the trace events. + * + * Create structure declaration that allows the "assign" macros to access the + * field types. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +/* Named field types must be defined in lttng-types.h */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) _type _item; + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding) \ + _type _item; + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + _type _item; + +#undef __string +#define __string(_item, _src) char _item; + +#undef __string_from_user +#define __string_from_user(_item, _src) \ + __string(_item, _src) + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ +struct __event_typemap__##_name { \ + _tstruct \ +}; + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + + +/* + * Stage 9 of the trace events. + * + * Create the probe function : call even size calculation and write event data + * into the buffer. + * + * We use both the field and assignment macros to write the fields in the order + * defined in the field declaration. The field declarations control the + * execution order, jumping to the appropriate assignment block. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#undef __field_full +#define __field_full(_type, _item, _order, _base) \ + goto __assign_##_item; \ +__end_field_##_item: + +#undef __array_enc_ext +#define __array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + goto __assign_##_item; \ +__end_field_##_item: + +#undef __dynamic_array_enc_ext +#define __dynamic_array_enc_ext(_type, _item, _length, _order, _base, _encoding)\ + goto __assign_##_item##_1; \ +__end_field_##_item##_1: \ + goto __assign_##_item##_2; \ +__end_field_##_item##_2: + +#undef __string +#define __string(_item, _src) \ + goto __assign_##_item; \ +__end_field_##_item: + +#undef __string_from_user +#define __string_from_user(_item, _src) \ + __string(_item, _src) + +/* + * Macros mapping tp_assign() to "=", tp_memcpy() to memcpy() and tp_strcpy() to + * strcpy(). + */ +#undef tp_assign +#define tp_assign(dest, src) \ +__assign_##dest: \ + { \ + __typeof__(__typemap.dest) __tmp = (src); \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__tmp)); \ + __chan->ops->event_write(&__ctx, &__tmp, sizeof(__tmp));\ + } \ + goto __end_field_##dest; + +#undef tp_memcpy +#define tp_memcpy(dest, src, len) \ +__assign_##dest: \ + if (0) \ + (void) __typemap.dest; \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + __chan->ops->event_write(&__ctx, src, len); \ + goto __end_field_##dest; + +#undef tp_memcpy_dyn +#define tp_memcpy_dyn(dest, src) \ +__assign_##dest##_1: \ + { \ + u32 __tmpl = __dynamic_len[__dynamic_len_idx]; \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(u32)); \ + __chan->ops->event_write(&__ctx, &__tmpl, sizeof(u32)); \ + } \ + goto __end_field_##dest##_1; \ +__assign_##dest##_2: \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + __chan->ops->event_write(&__ctx, src, \ + sizeof(__typemap.dest) * __get_dynamic_array_len(dest));\ + goto __end_field_##dest##_2; + +#undef tp_memcpy_from_user +#define tp_memcpy_from_user(dest, src, len) \ + __assign_##dest: \ + if (0) \ + (void) __typemap.dest; \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest)); \ + __chan->ops->event_write_from_user(&__ctx, src, len); \ + goto __end_field_##dest; + +/* + * The string length including the final \0. + */ +#undef tp_copy_string_from_user +#define tp_copy_string_from_user(dest, src) \ + __assign_##dest: \ + { \ + size_t __ustrlen; \ + \ + if (0) \ + (void) __typemap.dest; \ + lib_ring_buffer_align_ctx(&__ctx, ltt_alignof(__typemap.dest));\ + __ustrlen = __get_dynamic_array_len(dest); \ + if (likely(__ustrlen) > 1) { \ + __chan->ops->event_write_from_user(&__ctx, src, \ + __ustrlen - 1); \ + } \ + __chan->ops->event_memset(&__ctx, 0, 1); \ + } \ + goto __end_field_##dest; +#undef tp_strcpy +#define tp_strcpy(dest, src) \ + tp_memcpy(dest, src, __get_dynamic_array_len(dest)) + +/* Named field types must be defined in lttng-types.h */ + +#undef __get_str +#define __get_str(field) field + +#undef __get_dynamic_array +#define __get_dynamic_array(field) field + +/* Beware: this get len actually consumes the len value */ +#undef __get_dynamic_array_len +#define __get_dynamic_array_len(field) __dynamic_len[__dynamic_len_idx++] + +#undef TP_PROTO +#define TP_PROTO(args...) args + +#undef TP_ARGS +#define TP_ARGS(args...) args + +#undef TP_STRUCT__entry +#define TP_STRUCT__entry(args...) args + +#undef TP_fast_assign +#define TP_fast_assign(args...) args + +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(_name, _proto, _args, _tstruct, _assign, _print) \ +static void __event_probe__##_name(void *__data, _proto) \ +{ \ + struct ltt_event *__event = __data; \ + struct ltt_channel *__chan = __event->chan; \ + struct lib_ring_buffer_ctx __ctx; \ + size_t __event_len, __event_align; \ + size_t __dynamic_len_idx = 0; \ + size_t __dynamic_len[ARRAY_SIZE(__event_fields___##_name)]; \ + struct __event_typemap__##_name __typemap; \ + int __ret; \ + \ + if (0) \ + (void) __dynamic_len_idx; /* don't warn if unused */ \ + if (unlikely(!ACCESS_ONCE(__chan->session->active))) \ + return; \ + if (unlikely(!ACCESS_ONCE(__chan->enabled))) \ + return; \ + if (unlikely(!ACCESS_ONCE(__event->enabled))) \ + return; \ + __event_len = __event_get_size__##_name(__dynamic_len, _args); \ + __event_align = __event_get_align__##_name(_args); \ + lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ + __event_align, -1); \ + __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ + if (__ret < 0) \ + return; \ + /* Control code (field ordering) */ \ + _tstruct \ + __chan->ops->event_commit(&__ctx); \ + return; \ + /* Copy code, steered by control code */ \ + _assign \ +} + +#undef DECLARE_EVENT_CLASS_NOARGS +#define DECLARE_EVENT_CLASS_NOARGS(_name, _tstruct, _assign, _print) \ +static void __event_probe__##_name(void *__data) \ +{ \ + struct ltt_event *__event = __data; \ + struct ltt_channel *__chan = __event->chan; \ + struct lib_ring_buffer_ctx __ctx; \ + size_t __event_len, __event_align; \ + int __ret; \ + \ + if (unlikely(!ACCESS_ONCE(__chan->session->active))) \ + return; \ + if (unlikely(!ACCESS_ONCE(__chan->enabled))) \ + return; \ + if (unlikely(!ACCESS_ONCE(__event->enabled))) \ + return; \ + __event_len = 0; \ + __event_align = 1; \ + lib_ring_buffer_ctx_init(&__ctx, __chan->chan, __event, __event_len, \ + __event_align, -1); \ + __ret = __chan->ops->event_reserve(&__ctx, __event->id); \ + if (__ret < 0) \ + return; \ + /* Control code (field ordering) */ \ + _tstruct \ + __chan->ops->event_commit(&__ctx); \ + return; \ + /* Copy code, steered by control code */ \ + _assign \ +} + +#include TRACE_INCLUDE(TRACE_INCLUDE_FILE) + +/* + * Stage 10 of the trace events. + * + * Register/unregister probes at module load/unload. + */ + +#include "lttng-events-reset.h" /* Reset all macros within TRACE_EVENT */ + +#define TP_ID1(_token, _system) _token##_system +#define TP_ID(_token, _system) TP_ID1(_token, _system) +#define module_init_eval1(_token, _system) module_init(_token##_system) +#define module_init_eval(_token, _system) module_init_eval1(_token, _system) +#define module_exit_eval1(_token, _system) module_exit(_token##_system) +#define module_exit_eval(_token, _system) module_exit_eval1(_token, _system) + +#ifndef TP_MODULE_OVERRIDE +static int TP_ID(__lttng_events_init__, TRACE_SYSTEM)(void) +{ + wrapper_vmalloc_sync_all(); + return ltt_probe_register(&TP_ID(__probe_desc___, TRACE_SYSTEM)); +} + +module_init_eval(__lttng_events_init__, TRACE_SYSTEM); + +static void TP_ID(__lttng_events_exit__, TRACE_SYSTEM)(void) +{ + ltt_probe_unregister(&TP_ID(__probe_desc___, TRACE_SYSTEM)); +} + +module_exit_eval(__lttng_events_exit__, TRACE_SYSTEM); +#endif + +#undef module_init_eval +#undef module_exit_eval +#undef TP_ID1 +#undef TP_ID + +#undef TP_PROTO +#undef TP_ARGS +#undef TRACE_EVENT_FLAGS diff --git a/drivers/staging/lttng/probes/lttng-ftrace.c b/drivers/staging/lttng/probes/lttng-ftrace.c new file mode 100644 index 0000000..1aa7183 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-ftrace.c @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng function tracer integration module. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +/* + * Ftrace function tracer does not seem to provide synchronization between probe + * teardown and callback execution. Therefore, we make this module permanently + * loaded (unloadable). + * + * TODO: Move to register_ftrace_function() (which is exported for + * modules) for Linux >= 3.0. It is faster (only enables the selected + * functions), and will stay there. + */ + +#include <linux/module.h> +#include <linux/ftrace.h> +#include <linux/slab.h> +#include "../ltt-events.h" +#include "../wrapper/ringbuffer/frontend_types.h" +#include "../wrapper/ftrace.h" +#include "../wrapper/vmalloc.h" +#include "../ltt-tracer.h" + +static +void lttng_ftrace_handler(unsigned long ip, unsigned long parent_ip, void **data) +{ + struct ltt_event *event = *data; + struct ltt_channel *chan = event->chan; + struct lib_ring_buffer_ctx ctx; + struct { + unsigned long ip; + unsigned long parent_ip; + } payload; + int ret; + + if (unlikely(!ACCESS_ONCE(chan->session->active))) + return; + if (unlikely(!ACCESS_ONCE(chan->enabled))) + return; + if (unlikely(!ACCESS_ONCE(event->enabled))) + return; + + lib_ring_buffer_ctx_init(&ctx, chan->chan, event, + sizeof(payload), ltt_alignof(payload), -1); + ret = chan->ops->event_reserve(&ctx, event->id); + if (ret < 0) + return; + payload.ip = ip; + payload.parent_ip = parent_ip; + lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload)); + chan->ops->event_write(&ctx, &payload, sizeof(payload)); + chan->ops->event_commit(&ctx); + return; +} + +/* + * Create event description + */ +static +int lttng_create_ftrace_event(const char *name, struct ltt_event *event) +{ + struct lttng_event_field *fields; + struct lttng_event_desc *desc; + int ret; + + desc = kzalloc(sizeof(*event->desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + desc->name = kstrdup(name, GFP_KERNEL); + if (!desc->name) { + ret = -ENOMEM; + goto error_str; + } + desc->nr_fields = 2; + desc->fields = fields = + kzalloc(2 * sizeof(struct lttng_event_field), GFP_KERNEL); + if (!desc->fields) { + ret = -ENOMEM; + goto error_fields; + } + fields[0].name = "ip"; + fields[0].type.atype = atype_integer; + fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long); + fields[0].type.u.basic.integer.reverse_byte_order = 0; + fields[0].type.u.basic.integer.base = 16; + fields[0].type.u.basic.integer.encoding = lttng_encode_none; + + fields[1].name = "parent_ip"; + fields[1].type.atype = atype_integer; + fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long); + fields[1].type.u.basic.integer.reverse_byte_order = 0; + fields[1].type.u.basic.integer.base = 16; + fields[1].type.u.basic.integer.encoding = lttng_encode_none; + + desc->owner = THIS_MODULE; + event->desc = desc; + + return 0; + +error_fields: + kfree(desc->name); +error_str: + kfree(desc); + return ret; +} + +static +struct ftrace_probe_ops lttng_ftrace_ops = { + .func = lttng_ftrace_handler, +}; + +int lttng_ftrace_register(const char *name, + const char *symbol_name, + struct ltt_event *event) +{ + int ret; + + ret = lttng_create_ftrace_event(name, event); + if (ret) + goto error; + + event->u.ftrace.symbol_name = kstrdup(symbol_name, GFP_KERNEL); + if (!event->u.ftrace.symbol_name) + goto name_error; + + /* Ensure the memory we just allocated don't trigger page faults */ + wrapper_vmalloc_sync_all(); + + ret = wrapper_register_ftrace_function_probe(event->u.ftrace.symbol_name, + <tng_ftrace_ops, event); + if (ret < 0) + goto register_error; + return 0; + +register_error: + kfree(event->u.ftrace.symbol_name); +name_error: + kfree(event->desc->name); + kfree(event->desc); +error: + return ret; +} +EXPORT_SYMBOL_GPL(lttng_ftrace_register); + +void lttng_ftrace_unregister(struct ltt_event *event) +{ + wrapper_unregister_ftrace_function_probe(event->u.ftrace.symbol_name, + <tng_ftrace_ops, event); +} +EXPORT_SYMBOL_GPL(lttng_ftrace_unregister); + +void lttng_ftrace_destroy_private(struct ltt_event *event) +{ + kfree(event->u.ftrace.symbol_name); + kfree(event->desc->fields); + kfree(event->desc->name); + kfree(event->desc); +} +EXPORT_SYMBOL_GPL(lttng_ftrace_destroy_private); + +int lttng_ftrace_init(void) +{ + wrapper_vmalloc_sync_all(); + return 0; +} +module_init(lttng_ftrace_init) + +/* + * Ftrace takes care of waiting for a grace period (RCU sched) at probe + * unregistration, and disables preemption around probe call. + */ +void lttng_ftrace_exit(void) +{ +} +module_exit(lttng_ftrace_exit) + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Ftrace Support"); diff --git a/drivers/staging/lttng/probes/lttng-kprobes.c b/drivers/staging/lttng/probes/lttng-kprobes.c new file mode 100644 index 0000000..784002a --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-kprobes.c @@ -0,0 +1,164 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng kprobes integration module. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/kprobes.h> +#include <linux/slab.h> +#include "../ltt-events.h" +#include "../wrapper/ringbuffer/frontend_types.h" +#include "../wrapper/vmalloc.h" +#include "../ltt-tracer.h" + +static +int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs) +{ + struct ltt_event *event = + container_of(p, struct ltt_event, u.kprobe.kp); + struct ltt_channel *chan = event->chan; + struct lib_ring_buffer_ctx ctx; + int ret; + unsigned long data = (unsigned long) p->addr; + + if (unlikely(!ACCESS_ONCE(chan->session->active))) + return 0; + if (unlikely(!ACCESS_ONCE(chan->enabled))) + return 0; + if (unlikely(!ACCESS_ONCE(event->enabled))) + return 0; + + lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(data), + ltt_alignof(data), -1); + ret = chan->ops->event_reserve(&ctx, event->id); + if (ret < 0) + return 0; + lib_ring_buffer_align_ctx(&ctx, ltt_alignof(data)); + chan->ops->event_write(&ctx, &data, sizeof(data)); + chan->ops->event_commit(&ctx); + return 0; +} + +/* + * Create event description + */ +static +int lttng_create_kprobe_event(const char *name, struct ltt_event *event) +{ + struct lttng_event_field *field; + struct lttng_event_desc *desc; + int ret; + + desc = kzalloc(sizeof(*event->desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + desc->name = kstrdup(name, GFP_KERNEL); + if (!desc->name) { + ret = -ENOMEM; + goto error_str; + } + desc->nr_fields = 1; + desc->fields = field = + kzalloc(1 * sizeof(struct lttng_event_field), GFP_KERNEL); + if (!field) { + ret = -ENOMEM; + goto error_field; + } + field->name = "ip"; + field->type.atype = atype_integer; + field->type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; + field->type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + field->type.u.basic.integer.signedness = is_signed_type(unsigned long); + field->type.u.basic.integer.reverse_byte_order = 0; + field->type.u.basic.integer.base = 16; + field->type.u.basic.integer.encoding = lttng_encode_none; + desc->owner = THIS_MODULE; + event->desc = desc; + + return 0; + +error_field: + kfree(desc->name); +error_str: + kfree(desc); + return ret; +} + +int lttng_kprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event) +{ + int ret; + + /* Kprobes expects a NULL symbol name if unused */ + if (symbol_name[0] == '\0') + symbol_name = NULL; + + ret = lttng_create_kprobe_event(name, event); + if (ret) + goto error; + memset(&event->u.kprobe.kp, 0, sizeof(event->u.kprobe.kp)); + event->u.kprobe.kp.pre_handler = lttng_kprobes_handler_pre; + if (symbol_name) { + event->u.kprobe.symbol_name = + kzalloc(LTTNG_SYM_NAME_LEN * sizeof(char), + GFP_KERNEL); + if (!event->u.kprobe.symbol_name) { + ret = -ENOMEM; + goto name_error; + } + memcpy(event->u.kprobe.symbol_name, symbol_name, + LTTNG_SYM_NAME_LEN * sizeof(char)); + event->u.kprobe.kp.symbol_name = + event->u.kprobe.symbol_name; + } + event->u.kprobe.kp.offset = offset; + event->u.kprobe.kp.addr = (void *) (unsigned long) addr; + + /* + * Ensure the memory we just allocated don't trigger page faults. + * Well.. kprobes itself puts the page fault handler on the blacklist, + * but we can never be too careful. + */ + wrapper_vmalloc_sync_all(); + + ret = register_kprobe(&event->u.kprobe.kp); + if (ret) + goto register_error; + return 0; + +register_error: + kfree(event->u.kprobe.symbol_name); +name_error: + kfree(event->desc->fields); + kfree(event->desc->name); + kfree(event->desc); +error: + return ret; +} +EXPORT_SYMBOL_GPL(lttng_kprobes_register); + +void lttng_kprobes_unregister(struct ltt_event *event) +{ + unregister_kprobe(&event->u.kprobe.kp); +} +EXPORT_SYMBOL_GPL(lttng_kprobes_unregister); + +void lttng_kprobes_destroy_private(struct ltt_event *event) +{ + kfree(event->u.kprobe.symbol_name); + kfree(event->desc->fields); + kfree(event->desc->name); + kfree(event->desc); +} +EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_private); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Kprobes Support"); diff --git a/drivers/staging/lttng/probes/lttng-kretprobes.c b/drivers/staging/lttng/probes/lttng-kretprobes.c new file mode 100644 index 0000000..6b29101 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-kretprobes.c @@ -0,0 +1,277 @@ +/* + * (C) Copyright 2009-2011 - + * Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng kretprobes integration module. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/kprobes.h> +#include <linux/slab.h> +#include <linux/kref.h> +#include "../ltt-events.h" +#include "../wrapper/ringbuffer/frontend_types.h" +#include "../wrapper/vmalloc.h" +#include "../ltt-tracer.h" + +enum lttng_kretprobe_type { + EVENT_ENTRY = 0, + EVENT_RETURN = 1, +}; + +struct lttng_krp { + struct kretprobe krp; + struct ltt_event *event[2]; /* ENTRY and RETURN */ + struct kref kref_register; + struct kref kref_alloc; +}; + +static +int _lttng_kretprobes_handler(struct kretprobe_instance *krpi, + struct pt_regs *regs, + enum lttng_kretprobe_type type) +{ + struct lttng_krp *lttng_krp = + container_of(krpi->rp, struct lttng_krp, krp); + struct ltt_event *event = + lttng_krp->event[type]; + struct ltt_channel *chan = event->chan; + struct lib_ring_buffer_ctx ctx; + int ret; + struct { + unsigned long ip; + unsigned long parent_ip; + } payload; + + if (unlikely(!ACCESS_ONCE(chan->session->active))) + return 0; + if (unlikely(!ACCESS_ONCE(chan->enabled))) + return 0; + if (unlikely(!ACCESS_ONCE(event->enabled))) + return 0; + + payload.ip = (unsigned long) krpi->rp->kp.addr; + payload.parent_ip = (unsigned long) krpi->ret_addr; + + lib_ring_buffer_ctx_init(&ctx, chan->chan, event, sizeof(payload), + ltt_alignof(payload), -1); + ret = chan->ops->event_reserve(&ctx, event->id); + if (ret < 0) + return 0; + lib_ring_buffer_align_ctx(&ctx, ltt_alignof(payload)); + chan->ops->event_write(&ctx, &payload, sizeof(payload)); + chan->ops->event_commit(&ctx); + return 0; +} + +static +int lttng_kretprobes_handler_entry(struct kretprobe_instance *krpi, + struct pt_regs *regs) +{ + return _lttng_kretprobes_handler(krpi, regs, EVENT_ENTRY); +} + +static +int lttng_kretprobes_handler_return(struct kretprobe_instance *krpi, + struct pt_regs *regs) +{ + return _lttng_kretprobes_handler(krpi, regs, EVENT_RETURN); +} + +/* + * Create event description + */ +static +int lttng_create_kprobe_event(const char *name, struct ltt_event *event, + enum lttng_kretprobe_type type) +{ + struct lttng_event_field *fields; + struct lttng_event_desc *desc; + int ret; + char *alloc_name; + size_t name_len; + const char *suffix = NULL; + + desc = kzalloc(sizeof(*event->desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + name_len = strlen(name); + switch (type) { + case EVENT_ENTRY: + suffix = "_entry"; + break; + case EVENT_RETURN: + suffix = "_return"; + break; + } + name_len += strlen(suffix); + alloc_name = kmalloc(name_len + 1, GFP_KERNEL); + if (!alloc_name) { + ret = -ENOMEM; + goto error_str; + } + strcpy(alloc_name, name); + strcat(alloc_name, suffix); + desc->name = alloc_name; + desc->nr_fields = 2; + desc->fields = fields = + kzalloc(2 * sizeof(struct lttng_event_field), GFP_KERNEL); + if (!desc->fields) { + ret = -ENOMEM; + goto error_fields; + } + fields[0].name = "ip"; + fields[0].type.atype = atype_integer; + fields[0].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[0].type.u.basic.integer.signedness = is_signed_type(unsigned long); + fields[0].type.u.basic.integer.reverse_byte_order = 0; + fields[0].type.u.basic.integer.base = 16; + fields[0].type.u.basic.integer.encoding = lttng_encode_none; + + fields[1].name = "parent_ip"; + fields[1].type.atype = atype_integer; + fields[1].type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.alignment = ltt_alignof(unsigned long) * CHAR_BIT; + fields[1].type.u.basic.integer.signedness = is_signed_type(unsigned long); + fields[1].type.u.basic.integer.reverse_byte_order = 0; + fields[1].type.u.basic.integer.base = 16; + fields[1].type.u.basic.integer.encoding = lttng_encode_none; + + desc->owner = THIS_MODULE; + event->desc = desc; + + return 0; + +error_fields: + kfree(desc->name); +error_str: + kfree(desc); + return ret; +} + +int lttng_kretprobes_register(const char *name, + const char *symbol_name, + uint64_t offset, + uint64_t addr, + struct ltt_event *event_entry, + struct ltt_event *event_return) +{ + int ret; + struct lttng_krp *lttng_krp; + + /* Kprobes expects a NULL symbol name if unused */ + if (symbol_name[0] == '\0') + symbol_name = NULL; + + ret = lttng_create_kprobe_event(name, event_entry, EVENT_ENTRY); + if (ret) + goto error; + ret = lttng_create_kprobe_event(name, event_return, EVENT_RETURN); + if (ret) + goto event_return_error; + lttng_krp = kzalloc(sizeof(*lttng_krp), GFP_KERNEL); + if (!lttng_krp) + goto krp_error; + lttng_krp->krp.entry_handler = lttng_kretprobes_handler_entry; + lttng_krp->krp.handler = lttng_kretprobes_handler_return; + if (symbol_name) { + char *alloc_symbol; + + alloc_symbol = kstrdup(symbol_name, GFP_KERNEL); + if (!alloc_symbol) { + ret = -ENOMEM; + goto name_error; + } + lttng_krp->krp.kp.symbol_name = + alloc_symbol; + event_entry->u.kretprobe.symbol_name = + alloc_symbol; + event_return->u.kretprobe.symbol_name = + alloc_symbol; + } + lttng_krp->krp.kp.offset = offset; + lttng_krp->krp.kp.addr = (void *) (unsigned long) addr; + + /* Allow probe handler to find event structures */ + lttng_krp->event[EVENT_ENTRY] = event_entry; + lttng_krp->event[EVENT_RETURN] = event_return; + event_entry->u.kretprobe.lttng_krp = lttng_krp; + event_return->u.kretprobe.lttng_krp = lttng_krp; + + /* + * Both events must be unregistered before the kretprobe is + * unregistered. Same for memory allocation. + */ + kref_init(<tng_krp->kref_alloc); + kref_get(<tng_krp->kref_alloc); /* inc refcount to 2 */ + kref_init(<tng_krp->kref_register); + kref_get(<tng_krp->kref_register); /* inc refcount to 2 */ + + /* + * Ensure the memory we just allocated don't trigger page faults. + * Well.. kprobes itself puts the page fault handler on the blacklist, + * but we can never be too careful. + */ + wrapper_vmalloc_sync_all(); + + ret = register_kretprobe(<tng_krp->krp); + if (ret) + goto register_error; + return 0; + +register_error: + kfree(lttng_krp->krp.kp.symbol_name); +name_error: + kfree(lttng_krp); +krp_error: + kfree(event_return->desc->fields); + kfree(event_return->desc->name); + kfree(event_return->desc); +event_return_error: + kfree(event_entry->desc->fields); + kfree(event_entry->desc->name); + kfree(event_entry->desc); +error: + return ret; +} +EXPORT_SYMBOL_GPL(lttng_kretprobes_register); + +static +void _lttng_kretprobes_unregister_release(struct kref *kref) +{ + struct lttng_krp *lttng_krp = + container_of(kref, struct lttng_krp, kref_register); + unregister_kretprobe(<tng_krp->krp); +} + +void lttng_kretprobes_unregister(struct ltt_event *event) +{ + kref_put(&event->u.kretprobe.lttng_krp->kref_register, + _lttng_kretprobes_unregister_release); +} +EXPORT_SYMBOL_GPL(lttng_kretprobes_unregister); + +static +void _lttng_kretprobes_release(struct kref *kref) +{ + struct lttng_krp *lttng_krp = + container_of(kref, struct lttng_krp, kref_alloc); + kfree(lttng_krp->krp.kp.symbol_name); +} + +void lttng_kretprobes_destroy_private(struct ltt_event *event) +{ + kfree(event->desc->fields); + kfree(event->desc->name); + kfree(event->desc); + kref_put(&event->u.kretprobe.lttng_krp->kref_alloc, + _lttng_kretprobes_release); +} +EXPORT_SYMBOL_GPL(lttng_kretprobes_destroy_private); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers"); +MODULE_DESCRIPTION("Linux Trace Toolkit Kretprobes Support"); diff --git a/drivers/staging/lttng/probes/lttng-probe-block.c b/drivers/staging/lttng/probes/lttng-probe-block.c new file mode 100644 index 0000000..9eeebfc --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-probe-block.c @@ -0,0 +1,31 @@ +/* + * probes/lttng-probe-block.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng block probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/blktrace_api.h> + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include <trace/events/block.h> + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/block.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng block probes"); diff --git a/drivers/staging/lttng/probes/lttng-probe-irq.c b/drivers/staging/lttng/probes/lttng-probe-irq.c new file mode 100644 index 0000000..4a6a322 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-probe-irq.c @@ -0,0 +1,31 @@ +/* + * probes/lttng-probe-irq.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng irq probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include <trace/events/irq.h> + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/irq.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng irq probes"); diff --git a/drivers/staging/lttng/probes/lttng-probe-kvm.c b/drivers/staging/lttng/probes/lttng-probe-kvm.c new file mode 100644 index 0000000..9efc6dd --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-probe-kvm.c @@ -0,0 +1,31 @@ +/* + * probes/lttng-probe-kvm.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng kvm probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/kvm_host.h> + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include <trace/events/kvm.h> + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/kvm.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng kvm probes"); diff --git a/drivers/staging/lttng/probes/lttng-probe-lttng.c b/drivers/staging/lttng/probes/lttng-probe-lttng.c new file mode 100644 index 0000000..62aab6c --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-probe-lttng.c @@ -0,0 +1,24 @@ +/* + * probes/lttng-probe-core.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng core probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/lttng.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng core probes"); diff --git a/drivers/staging/lttng/probes/lttng-probe-sched.c b/drivers/staging/lttng/probes/lttng-probe-sched.c new file mode 100644 index 0000000..18c1521 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-probe-sched.c @@ -0,0 +1,30 @@ +/* + * probes/lttng-probe-sched.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng sched probes. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include <trace/events/sched.h> + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/sched.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng sched probes"); diff --git a/drivers/staging/lttng/probes/lttng-type-list.h b/drivers/staging/lttng/probes/lttng-type-list.h new file mode 100644 index 0000000..7b953db --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-type-list.h @@ -0,0 +1,21 @@ +/* + * lttng-type-list.h + * + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +/* Type list, used to create metadata */ + +/* Enumerations */ +TRACE_EVENT_ENUM(hrtimer_mode, + V(HRTIMER_MODE_ABS), + V(HRTIMER_MODE_REL), + V(HRTIMER_MODE_PINNED), + V(HRTIMER_MODE_ABS_PINNED), + V(HRTIMER_MODE_REL_PINNED), + R(HRTIMER_MODE_UNDEFINED, 0x04, 0x20), /* Example (to remove) */ +) + +TRACE_EVENT_TYPE(hrtimer_mode, enum, unsigned char) diff --git a/drivers/staging/lttng/probes/lttng-types.c b/drivers/staging/lttng/probes/lttng-types.c new file mode 100644 index 0000000..93a9ae5 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-types.c @@ -0,0 +1,49 @@ +/* + * probes/lttng-types.c + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng types. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include "../wrapper/vmalloc.h" /* for wrapper_vmalloc_sync_all() */ +#include "../ltt-events.h" +#include "lttng-types.h" +#include <linux/hrtimer.h> + +#define STAGE_EXPORT_ENUMS +#include "lttng-types.h" +#include "lttng-type-list.h" +#undef STAGE_EXPORT_ENUMS + +struct lttng_enum lttng_enums[] = { +#define STAGE_EXPORT_TYPES +#include "lttng-types.h" +#include "lttng-type-list.h" +#undef STAGE_EXPORT_TYPES +}; + +static int lttng_types_init(void) +{ + int ret = 0; + + wrapper_vmalloc_sync_all(); + /* TODO */ + return ret; +} + +module_init(lttng_types_init); + +static void lttng_types_exit(void) +{ +} + +module_exit(lttng_types_exit); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers at efficios.com>"); +MODULE_DESCRIPTION("LTTng types"); diff --git a/drivers/staging/lttng/probes/lttng-types.h b/drivers/staging/lttng/probes/lttng-types.h new file mode 100644 index 0000000..1062028 --- /dev/null +++ b/drivers/staging/lttng/probes/lttng-types.h @@ -0,0 +1,72 @@ +/* + * Protect against multiple inclusion of structure declarations, but run the + * stages below each time. + */ +#ifndef _LTTNG_PROBES_LTTNG_TYPES_H +#define _LTTNG_PROBES_LTTNG_TYPES_H + +/* + * probes/lttng-types.h + * + * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * LTTng types. + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#include <linux/seq_file.h> +#include "lttng.h" +#include "../ltt-events.h" +#include "../ltt-tracer.h" +#include "../ltt-endian.h" + +#endif /* _LTTNG_PROBES_LTTNG_TYPES_H */ + +/* Export enumerations */ + +#ifdef STAGE_EXPORT_ENUMS + +#undef TRACE_EVENT_TYPE +#define TRACE_EVENT_TYPE(_name, _abstract_type, args...) + +#undef TRACE_EVENT_ENUM +#define TRACE_EVENT_ENUM(_name, _entries...) \ + const struct lttng_enum_entry __trace_event_enum_##_name[] = { \ + PARAMS(_entries) \ + }; + +/* Enumeration entry (single value) */ +#undef V +#define V(_string) { _string, _string, #_string} + +/* Enumeration entry (range) */ +#undef R +#define R(_string, _range_start, _range_end) \ + { _range_start, _range_end, #_string } + +#endif /* STAGE_EXPORT_ENUMS */ + + +/* Export named types */ + +#ifdef STAGE_EXPORT_TYPES + +#undef TRACE_EVENT_TYPE___enum +#define TRACE_EVENT_TYPE___enum(_name, _container_type) \ + { \ + .name = #_name, \ + .container_type = __type_integer(_container_type, __BYTE_ORDER, 10, none), \ + .entries = __trace_event_enum_##_name, \ + .len = ARRAY_SIZE(__trace_event_enum_##_name), \ + }, + +/* Local declaration */ +#undef TRACE_EVENT_TYPE +#define TRACE_EVENT_TYPE(_name, _abstract_type, args...) \ + TRACE_EVENT_TYPE___##_abstract_type(_name, args) + +#undef TRACE_EVENT_ENUM +#define TRACE_EVENT_ENUM(_name, _entries...) + +#endif /* STAGE_EXPORT_TYPES */ diff --git a/drivers/staging/lttng/probes/lttng.h b/drivers/staging/lttng/probes/lttng.h new file mode 100644 index 0000000..e16fc2d --- /dev/null +++ b/drivers/staging/lttng/probes/lttng.h @@ -0,0 +1,15 @@ +#ifndef _LTTNG_PROBES_LTTNG_H +#define _LTTNG_PROBES_LTTNG_H + +/* + * lttng.h + * + * Copyright (C) 2010-2011 Mathieu Desnoyers <mathieu.desnoyers at efficios.com> + * + * Dual LGPL v2.1/GPL v2 license. + */ + +#undef PARAMS +#define PARAMS(args...) args + +#endif /* _LTTNG_PROBES_LTTNG_H */ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 18/20] lttng: toplevel Makefile and Kconfig 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (16 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 17/20] lttng: probe callbacks Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 19/20] staging: add LTTng to build Mathieu Desnoyers ` (2 subsequent siblings) 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/lttng/Kconfig | 35 +++++++++++++++++++++++++++++++++++ drivers/staging/lttng/Makefile | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/lttng/Kconfig create mode 100644 drivers/staging/lttng/Makefile diff --git a/drivers/staging/lttng/Kconfig b/drivers/staging/lttng/Kconfig new file mode 100644 index 0000000..34c4a4f --- /dev/null +++ b/drivers/staging/lttng/Kconfig @@ -0,0 +1,35 @@ +config LTTNG + tristate "LTTng kernel tracer" + depends on TRACEPOINTS + help + The LTTng 2.0 Tracer Toolchain allows integrated kernel and + user-space tracing from a single user interface: the "lttng" + command. See http://lttng.org website for the "lttng-tools" + user-space tracer control tools package and the "babeltrace" + package for conversion of trace data to a human-readable + format. + + LTTng features: + - System-wide tracing across kernel, libraries and + applications, + - Tracepoints, detailed syscall tracing (fast strace replacement), + Function tracer, CPU Performance Monitoring Unit (PMU) counters + and kprobes support, + - Have the ability to attach "context" information to events in the + trace (e.g. any PMU counter, pid, ppid, tid, comm name, etc). All + the extra information fields to be collected with events are + optional, specified on a per-tracing-session basis (except for + timestamp and event id, which are mandatory). + - Precise and fast clock sources with near cycle-level + timestamps, + - Efficient trace data transport: + - Compact Binary format with CTF, + - Per-core buffers ensures scalability, + - Fast-paths in caller context, amortized synchronization, + - Zero-copy using splice and mmap system calls, over disk, + network or consumed in-place, + - Multiple concurrent tracing sessions are supported, + - Designed to meet hard real-time constraints, + - Supports live streaming of the trace data, + - Produces CTF (Common Trace Format) natively (see + http://www.efficios.com/ctf). diff --git a/drivers/staging/lttng/Makefile b/drivers/staging/lttng/Makefile new file mode 100644 index 0000000..9ad4eb0 --- /dev/null +++ b/drivers/staging/lttng/Makefile @@ -0,0 +1,33 @@ +# +# Makefile for the LTTng modules. +# + +obj-m += ltt-ring-buffer-client-discard.o +obj-m += ltt-ring-buffer-client-overwrite.o +obj-m += ltt-ring-buffer-metadata-client.o +obj-m += ltt-ring-buffer-client-mmap-discard.o +obj-m += ltt-ring-buffer-client-mmap-overwrite.o +obj-m += ltt-ring-buffer-metadata-mmap-client.o + +obj-m += ltt-relay.o +ltt-relay-objs := ltt-events.o ltt-debugfs-abi.o \ + ltt-probes.o ltt-context.o \ + lttng-context-pid.o lttng-context-procname.o \ + lttng-context-prio.o lttng-context-nice.o \ + lttng-context-vpid.o lttng-context-tid.o \ + lttng-context-vtid.o lttng-context-ppid.o \ + lttng-context-vppid.o lttng-calibrate.o + +ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) +ltt-relay-objs += lttng-syscalls.o +endif + +ifneq ($(CONFIG_PERF_EVENTS),) +ltt-relay-objs += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 33 \) ] ; then \ + echo "lttng-context-perf-counters.o" ; fi;) +endif + +obj-m += probes/ +obj-m += lib/ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 19/20] staging: add LTTng to build 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (17 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 18/20] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 20/20] Add LTTng entry to MAINTAINERS file Mathieu Desnoyers 2011-11-29 1:07 ` [lttng-dev] LTTng driver submission for staging (2nd attempt) Greg KH 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + 2 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 06c9081..09895ba 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -72,6 +72,8 @@ source "drivers/staging/phison/Kconfig" source "drivers/staging/line6/Kconfig" +source "drivers/staging/lttng/Kconfig" + source "drivers/gpu/drm/vmwgfx/Kconfig" source "drivers/gpu/drm/nouveau/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f3c5e33..08f7ccc 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ +obj-$(CONFIG_LTTNG) += lttng/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] [PATCH 20/20] Add LTTng entry to MAINTAINERS file 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (18 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 19/20] staging: add LTTng to build Mathieu Desnoyers @ 2011-11-28 12:42 ` Mathieu Desnoyers 2011-11-29 1:07 ` [lttng-dev] LTTng driver submission for staging (2nd attempt) Greg KH 20 siblings, 0 replies; 25+ messages in thread From: Mathieu Desnoyers @ 2011-11-28 12:42 UTC (permalink / raw) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> --- MAINTAINERS | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6185d05..7627a1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4065,6 +4065,13 @@ W: http://ltp.sourceforge.net/ T: git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev S: Maintained +LTTng (Linux Trace Toolkit Next Generation) +M: Mathieu Desnoyers <mathieu.desnoyers at efficios.com> +L: lttng-dev at lists.lttng.org (moderated for non-subscribers) +W: http://lttng.org +S: Maintained +F: drivers/staging/lttng/ + M32R ARCHITECTURE M: Hirokazu Takata <takata at linux-m32r.org> L: linux-m32r at ml.linux-m32r.org -- 1.7.2.5 ^ permalink raw reply [flat|nested] 25+ messages in thread
* [lttng-dev] LTTng driver submission for staging (2nd attempt) 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers ` (19 preceding siblings ...) 2011-11-28 12:42 ` [lttng-dev] [PATCH 20/20] Add LTTng entry to MAINTAINERS file Mathieu Desnoyers @ 2011-11-29 1:07 ` Greg KH 20 siblings, 0 replies; 25+ messages in thread From: Greg KH @ 2011-11-29 1:07 UTC (permalink / raw) On Mon, Nov 28, 2011 at 07:42:07AM -0500, Mathieu Desnoyers wrote: > > Hi Greg, > > This a resend of the LTTng driver patchset for staging. After your > review of the first round, I proceeded to the following modifications: > > - Understood that git format-patch must be given the commit prior to the > first commit to include in the patchset as first commit ID, this > adding the missing 0001-lttng-lib-lttng-priority-heap.patch. (cause of > the build failure) > - Added missing (empty) system call instrumentation "override" files, > that were known to git, but discarded by git format-patch. Made sure > they appear in the patches as place-holders by adding a comment in > those files. > - Removed gpl*.txt/lgpl*.txt license files. > - Removed Changelog. > - Added TODO file. > - While going through the TODO, I noticed that I needed to fix the > syscall TRACE_EVENT generation scripts (along with the headers > generated) to complete support of 32-bit compat syscalls on x86-64. I > did these modifications. > - Tested the build on x86-64/x86-32, and run-time tested on x86-32, > using the patchset rather than the git tree commits to ensure you > won't run into any issues on your side. Nice, that worked, all now applied. greg k-h ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2011-11-30 6:23 UTC | newest] Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-11-28 12:42 [lttng-dev] LTTng driver submission for staging (2nd attempt) Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 01/20] lttng lib: lttng priority heap Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 02/20] lttng lib: ring buffer Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 03/20] lttng lib: portable bitfield read/write header Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 04/20] lttng: BUILD_RUNTIME_BUG_ON Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 05/20] lttng: offset alignment header Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 06/20] lttng libs: add Makefile Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 07/20] lttng wrappers Mathieu Desnoyers 2011-11-29 1:04 ` Greg KH 2011-11-29 2:22 ` Mathieu Desnoyers 2011-11-30 6:23 ` Greg KH 2011-11-28 12:42 ` [lttng-dev] [PATCH 08/20] lttng instrumentation: tracepoint events Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 09/20] lttng: syscall instrumentation Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 10/20] lttng: lib ring buffer clients Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 11/20] lttng: tracer control and core structures Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 12/20] lttng: dynamically selectable context information Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 13/20] lttng: timing calibration feature Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 14/20] lttng: debugfs and procfs ABI Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 15/20] lttng: Add documentation and TODO files Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 16/20] lttng: add system call instrumentation probe Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 17/20] lttng: probe callbacks Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 18/20] lttng: toplevel Makefile and Kconfig Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 19/20] staging: add LTTng to build Mathieu Desnoyers 2011-11-28 12:42 ` [lttng-dev] [PATCH 20/20] Add LTTng entry to MAINTAINERS file Mathieu Desnoyers 2011-11-29 1:07 ` [lttng-dev] LTTng driver submission for staging (2nd attempt) Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox