From 140a62b06d149c780aef54f6ef0282310407734c Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 23 Feb 2018 11:37:10 -0500 Subject: [PATCH 01/16] Create a memory pool for temporary tracepoint probes storage This memory pool is created when the lttng-tracer module is loaded. It allocates 4 buffers of 4k on each CPU. These buffers are designed to allow tracepoint probes to temporarily store data that does not fit on the stack (during the code_pre and code_post phases). The memory is freed when the lttng-tracer module is unloaded. This removes the need for dynamic allocation during the execution of tracepoint probes, which does not behave well on PREEMPT_RT kernel, even when invoked with the GFP_ATOMIC | GFP_NOWAIT flags. Signed-off-by: Julien Desfossez Signed-off-by: Mathieu Desnoyers --- Makefile | 3 +- lttng-abi.c | 9 +++ lttng-tp-mempool.c | 172 +++++++++++++++++++++++++++++++++++++++++++++ lttng-tp-mempool.h | 63 +++++++++++++++++ 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 lttng-tp-mempool.c create mode 100644 lttng-tp-mempool.h diff --git a/Makefile b/Makefile index f377874a..dfa5a588 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,8 @@ ifneq ($(KERNELRELEASE),) lttng-filter.o lttng-filter-interpreter.o \ lttng-filter-specialize.o \ lttng-filter-validator.o \ - probes/lttng-probe-user.o + probes/lttng-probe-user.o \ + lttng-tp-mempool.o ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),) lttng-tracer-objs += lttng-syscalls.o diff --git a/lttng-abi.c b/lttng-abi.c index 901e58c0..c45c10f4 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include /* @@ -1722,6 +1723,12 @@ int __init lttng_abi_init(void) wrapper_vmalloc_sync_all(); lttng_clock_ref(); + + ret = lttng_tp_mempool_init(); + if (ret) { + goto error; + } + lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL, <tng_fops, NULL); @@ -1734,6 +1741,7 @@ int __init lttng_abi_init(void) return 0; error: + lttng_tp_mempool_destroy(); lttng_clock_unref(); return ret; } @@ -1741,6 +1749,7 @@ error: /* No __exit annotation because used by init error path too. */ void lttng_abi_exit(void) { + lttng_tp_mempool_destroy(); lttng_clock_unref(); if (lttng_proc_dentry) remove_proc_entry("lttng", NULL); diff --git a/lttng-tp-mempool.c b/lttng-tp-mempool.c new file mode 100644 index 00000000..d984bd45 --- /dev/null +++ b/lttng-tp-mempool.c @@ -0,0 +1,172 @@ +/* + * lttng-tp-mempool.c + * + * Copyright (C) 2018 Julien Desfossez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include + +struct lttng_tp_buf_entry { + int cpu; /* To make sure we return the entry to the right pool. */ + char buf[LTTNG_TP_MEMPOOL_BUF_SIZE]; + struct list_head list; +}; + +/* + * No exclusive access strategy for now, this memory pool is currently only + * used from a non-preemptible context, and the interrupt tracepoint probes do + * not use this facility. + */ +struct per_cpu_buf { + struct list_head free_list; /* Free struct lttng_tp_buf_entry. */ +}; + +static struct per_cpu_buf __percpu *pool; /* Per-cpu buffer. */ + +int lttng_tp_mempool_init(void) +{ + int ret, cpu; + + /* The pool is only supposed to be allocated once. */ + if (pool) { + WARN_ON_ONCE(1); + ret = -1; + goto end; + } + + pool = alloc_percpu(struct per_cpu_buf); + if (!pool) { + ret = -ENOMEM; + goto end; + } + + for_each_possible_cpu(cpu) { + struct per_cpu_buf *cpu_buf = per_cpu_ptr(pool, cpu); + + INIT_LIST_HEAD(&cpu_buf->free_list); + } + + for_each_possible_cpu(cpu) { + int i; + struct per_cpu_buf *cpu_buf = per_cpu_ptr(pool, cpu); + + for (i = 0; i < LTTNG_TP_MEMPOOL_NR_BUF_PER_CPU; i++) { + struct lttng_tp_buf_entry *entry; + + entry = kzalloc(sizeof(struct lttng_tp_buf_entry), + GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto error_free_pool; + } + entry->cpu = cpu; + list_add_tail(&entry->list, &cpu_buf->free_list); + } + } + + ret = 0; + goto end; + +error_free_pool: + lttng_tp_mempool_destroy(); +end: + return ret; +} + +void lttng_tp_mempool_destroy(void) +{ + int cpu; + + if (!pool) { + return; + } + + for_each_possible_cpu(cpu) { + struct per_cpu_buf *cpu_buf = per_cpu_ptr(pool, cpu); + struct lttng_tp_buf_entry *entry, *tmp; + int i = 0; + + list_for_each_entry_safe(entry, tmp, &cpu_buf->free_list, list) { + list_del(&entry->list); + kfree(entry); + i++; + } + if (i < LTTNG_TP_MEMPOOL_NR_BUF_PER_CPU) { + printk(KERN_WARNING "Leak detected in tp-mempool\n"); + } + } + free_percpu(pool); + pool = NULL; +} + +void *lttng_tp_mempool_alloc(size_t size) +{ + void *ret; + struct lttng_tp_buf_entry *entry; + struct per_cpu_buf *cpu_buf; + int cpu = smp_processor_id(); + + if (size > LTTNG_TP_MEMPOOL_BUF_SIZE) { + ret = NULL; + goto end; + } + + cpu_buf = per_cpu_ptr(pool, cpu); + if (list_empty(&cpu_buf->free_list)) { + ret = NULL; + goto end; + } + + entry = list_first_entry(&cpu_buf->free_list, struct lttng_tp_buf_entry, list); + /* Remove the entry from the free list. */ + list_del(&entry->list); + + memset(entry->buf, 0, LTTNG_TP_MEMPOOL_BUF_SIZE); + + ret = (void *) entry->buf; + +end: + return ret; +} + +void lttng_tp_mempool_free(void *ptr) +{ + struct lttng_tp_buf_entry *entry; + struct per_cpu_buf *cpu_buf; + + if (!ptr) { + goto end; + } + + entry = container_of(ptr, struct lttng_tp_buf_entry, buf); + if (!entry) { + goto end; + } + + cpu_buf = per_cpu_ptr(pool, entry->cpu); + if (!cpu_buf) { + goto end; + } + /* Add it to the free list. */ + list_add_tail(&entry->list, &cpu_buf->free_list); + +end: + return; +} diff --git a/lttng-tp-mempool.h b/lttng-tp-mempool.h new file mode 100644 index 00000000..7ce41129 --- /dev/null +++ b/lttng-tp-mempool.h @@ -0,0 +1,63 @@ +#ifndef LTTNG_TP_MEMPOOL_H +#define LTTNG_TP_MEMPOOL_H + +/* + * lttng-tp-mempool.h + * + * Copyright (C) 2018 Julien Desfossez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define LTTNG_TP_MEMPOOL_NR_BUF_PER_CPU 4 +#define LTTNG_TP_MEMPOOL_BUF_SIZE 4096 + +/* + * Initialize the pool, only performed once. The pool is a set of + * LTTNG_TP_MEMPOOL_NR_BUF_PER_CPU buffers of size LTTNG_TP_MEMPOOL_BUF_SIZE + * per-cpu. + * + * Returns 0 on success, a negative value on error. + */ +int lttng_tp_mempool_init(void); + +/* + * Destroy the pool and free all the memory allocated. + */ +void lttng_tp_mempool_destroy(void); + +/* + * Ask for a buffer on the current cpu. + * + * The pool is per-cpu, but there is no exclusive access guarantee on the + * per-cpu free-list, the caller needs to ensure it cannot get preempted or + * interrupted while performing the allocation. + * + * The maximum size that can be allocated is LTTNG_TP_MEMPOOL_BUF_SIZE, and the + * maximum number of buffers allocated simultaneously on the same CPU is + * LTTNG_TP_MEMPOOL_NR_BUF_PER_CPU. + * + * Return a pointer to a buffer on success, NULL on error. + */ +void *lttng_tp_mempool_alloc(size_t size); + +/* + * Release the memory reserved. Same concurrency limitations as the allocation. + */ +void lttng_tp_mempool_free(void *ptr); + +#endif /* LTTNG_TP_MEMPOOL_H */ -- 2.34.1 From 1e537d1facc8af916278babcde0a5407cb26eb3b Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Fri, 23 Feb 2018 11:37:11 -0500 Subject: [PATCH 02/16] Use the memory pool instead of kmalloc Replace the use of kmalloc/kfree in the tracepoint probes that need dynamic allocation with the tracepoint memory pool alloc/free. Signed-off-by: Julien Desfossez Signed-off-by: Mathieu Desnoyers --- .../headers/syscalls_pointers_override.h | 33 ++++++++----------- probes/lttng-tracepoint-event-impl.h | 1 + 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index 6b12a562..d22b1802 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -100,9 +100,8 @@ SC_LTTNG_TRACEPOINT_EVENT(pipe2, } \ \ if (inp) { \ - tp_locvar->fds_in = kmalloc( \ - tp_locvar->nr_ulong * sizeof(unsigned long), \ - GFP_ATOMIC | GFP_NOWAIT); \ + tp_locvar->fds_in = lttng_tp_mempool_alloc( \ + tp_locvar->nr_ulong * sizeof(unsigned long)); \ if (!tp_locvar->fds_in) \ goto error; \ \ @@ -113,9 +112,8 @@ SC_LTTNG_TRACEPOINT_EVENT(pipe2, goto error; \ } \ if (outp) { \ - tp_locvar->fds_out = kmalloc( \ - tp_locvar->nr_ulong * sizeof(unsigned long), \ - GFP_ATOMIC | GFP_NOWAIT); \ + tp_locvar->fds_out = lttng_tp_mempool_alloc( \ + tp_locvar->nr_ulong * sizeof(unsigned long)); \ if (!tp_locvar->fds_out) \ goto error; \ \ @@ -126,9 +124,8 @@ SC_LTTNG_TRACEPOINT_EVENT(pipe2, goto error; \ } \ if (exp) { \ - tp_locvar->fds_ex = kmalloc( \ - tp_locvar->nr_ulong * sizeof(unsigned long), \ - GFP_ATOMIC | GFP_NOWAIT); \ + tp_locvar->fds_ex = lttng_tp_mempool_alloc( \ + tp_locvar->nr_ulong * sizeof(unsigned long)); \ if (!tp_locvar->fds_ex) \ goto error; \ \ @@ -221,9 +218,9 @@ end: ; /* Label at end of compound statement. */ \ ) #define LTTNG_SYSCALL_SELECT_code_post \ - kfree(tp_locvar->fds_in); \ - kfree(tp_locvar->fds_out); \ - kfree(tp_locvar->fds_ex); + lttng_tp_mempool_free(tp_locvar->fds_in); \ + lttng_tp_mempool_free(tp_locvar->fds_out); \ + lttng_tp_mempool_free(tp_locvar->fds_ex); #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) #define OVERRIDE_32_select @@ -413,8 +410,7 @@ static struct lttng_type lttng_pollfd_elem = { { \ int err; \ \ - tp_locvar->fds = kmalloc(tp_locvar->alloc_fds, \ - GFP_ATOMIC | GFP_NOWAIT); \ + tp_locvar->fds = lttng_tp_mempool_alloc(tp_locvar->alloc_fds); \ if (!tp_locvar->fds) \ goto error; \ err = lib_ring_buffer_copy_from_user_check_nofault( \ @@ -494,7 +490,7 @@ end: \ ) #define LTTNG_SYSCALL_POLL_code_post \ - kfree(tp_locvar->fds); + lttng_tp_mempool_free(tp_locvar->fds); #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) #define OVERRIDE_32_poll @@ -761,9 +757,8 @@ static struct lttng_type lttng_epoll_wait_elem = { tp_locvar->fds_length = ret; \ } \ \ - tp_locvar->events = kmalloc( \ - maxalloc * sizeof(struct epoll_event), \ - GFP_ATOMIC | GFP_NOWAIT); \ + tp_locvar->events = lttng_tp_mempool_alloc( \ + maxalloc * sizeof(struct epoll_event)); \ if (!tp_locvar->events) { \ tp_locvar->fds_length = 0; \ goto skip_code; \ @@ -805,7 +800,7 @@ static struct lttng_type lttng_epoll_wait_elem = { #define LTTNG_SYSCALL_EPOLL_WAIT_code_post \ sc_out( \ - kfree(tp_locvar->events); \ + lttng_tp_mempool_free(tp_locvar->events); \ ) diff --git a/probes/lttng-tracepoint-event-impl.h b/probes/lttng-tracepoint-event-impl.h index 61f1c2d8..0842dcc0 100644 --- a/probes/lttng-tracepoint-event-impl.h +++ b/probes/lttng-tracepoint-event-impl.h @@ -34,6 +34,7 @@ #include #include #include +#include #define __LTTNG_NULL_STRING "(null)" -- 2.34.1 From 4fb36907467c550c8ce05878799fe27bc2bc8dc6 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Thu, 8 Mar 2018 11:18:56 -0500 Subject: [PATCH 03/16] Fix: update kvm instrumentation for 4.1.50+ Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/kvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/events/lttng-module/kvm.h b/instrumentation/events/lttng-module/kvm.h index 76eaa69a..8f9a1328 100644 --- a/instrumentation/events/lttng-module/kvm.h +++ b/instrumentation/events/lttng-module/kvm.h @@ -89,6 +89,7 @@ LTTNG_TRACEPOINT_EVENT(kvm_ack_irq, || LTTNG_DEBIAN_KERNEL_RANGE(4,14,13,0,1,0, 4,15,0,0,0,0) \ || LTTNG_KERNEL_RANGE(4,9,77, 4,10,0) \ || LTTNG_KERNEL_RANGE(4,4,112, 4,5,0) \ + || LTTNG_KERNEL_RANGE(4,1,50, 4,2,0) \ || LTTNG_KERNEL_RANGE(3,16,52, 3,17,0) \ || LTTNG_KERNEL_RANGE(3,2,97, 3,3,0) \ || LTTNG_DEBIAN_KERNEL_RANGE(4,9,65,0,3,0, 4,10,0,0,0,0) \ -- 2.34.1 From ca6fdddba6f9d25c051dd5c12fbb661ae1826663 Mon Sep 17 00:00:00 2001 From: Lars Persson Date: Sun, 11 Mar 2018 15:02:43 +0100 Subject: [PATCH 04/16] Fix: do not use CONFIG_HOTPLUG_CPU for the new hotplug API Kernel configurations without CONFIG_HOTPLUG_CPU throw an unknown symbol error when attempting to insert the lttng-trace module: lttng_tracer: Unknown symbol lttng_hp_prepare (err 0) lttng_tracer: Unknown symbol lttng_hp_online (err 0) This was caused by lttng-events and lttng-context-perf-counter not agreeing on which preprocessor condition that should guard the use of the hotplug API. In fact the API is available also on kernels built without CONFIG_HOTPLUG_CPU. Signed-off-by: Lars Persson Signed-off-by: Mathieu Desnoyers --- lttng-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lttng-events.c b/lttng-events.c index 0a8b2a68..624a1338 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -2644,7 +2644,7 @@ void lttng_transport_unregister(struct lttng_transport *transport) } EXPORT_SYMBOL_GPL(lttng_transport_unregister); -#if (defined(CONFIG_HOTPLUG_CPU) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) enum cpuhp_state lttng_hp_prepare; enum cpuhp_state lttng_hp_online; -- 2.34.1 From 5f26db404979bb0a2279be57ec757c1d8077b1fd Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 13 Mar 2018 12:14:43 -0400 Subject: [PATCH 05/16] Cleanup: comment about CONFIG_HOTPLUG_CPU ifdef Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- lttng-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lttng-events.c b/lttng-events.c index 624a1338..5e9c72bf 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -2760,7 +2760,7 @@ static void __exit lttng_exit_cpu_hotplug(void) cpuhp_remove_multi_state(lttng_hp_prepare); } -#else /* #if (CONFIG_HOTPLUG_CPU && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))) */ +#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) */ static int lttng_init_cpu_hotplug(void) { return 0; @@ -2768,7 +2768,7 @@ static int lttng_init_cpu_hotplug(void) static void lttng_exit_cpu_hotplug(void) { } -#endif /* #else #if (CONFIG_HOTPLUG_CPU && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0))) */ +#endif /* #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) */ static int __init lttng_events_init(void) -- 2.34.1 From 8d499a15a5e3b795014285af950ab9c3d685315c Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 22 Mar 2018 17:33:32 -0400 Subject: [PATCH 06/16] Fix: btrfs instrumentation namespacing Trips this warning: [ 122.301894] WARNING: CPU: 6 PID: 1654 at /home/efficios/git/lttng-modules/lttng-probes.c:99 fixup_lazy_probes+0x195/0x200 [lttng_tracer] [ 122.304974] Modules linked in: lttng_probe_compaction(O+) lttng_probe_btrfs(O) lttng_probe_block(O) lttng_ring_buffer_metadata_mmap_client(O) lttng_ring_buffer_client_mmap_overwrite(O) lttng_ring_buffer_client_mmap_discard(O) lttng_ring_buffer_metadata_client(O) lttng_ring_buffer_client_overwrite(O) lttng_ring_buffer_client_discard(O) lttng_tracer(O) lttng_statedump(O) lttng_ftrace(O) lttng_kprobes(O) lttng_clock(O) lttng_lib_ring_buffer(O) lttng_kretprobes(O) [ 122.314772] CPU: 6 PID: 1654 Comm: modprobe Tainted: G O 4.16.0-rc6+ #54 [ 122.316738] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 [ 122.320280] RIP: 0010:fixup_lazy_probes+0x195/0x200 [lttng_tracer] [ 122.321825] RSP: 0018:ffffc90008467ca0 EFLAGS: 00010286 [ 122.323137] RAX: 00000000ffffffff RBX: ffffffffa01e7000 RCX: 0000000000000061 [ 122.324847] RDX: 0000000000000005 RSI: ffffffffa01e21ac RDI: ffffffffa01e233b [ 122.326528] RBP: ffffffffa017f078 R08: 0000000000000062 R09: 0000000000000345 [ 122.328154] R10: 0000000000000000 R11: ffffc90008467a28 R12: 0000000000000005 [ 122.329791] R13: 0000000000000010 R14: 0000000000000010 R15: 0000000000000006 [ 122.331410] FS: 00007f6c8d9a7740(0000) GS:ffff880c0fb80000(0000) knlGS:0000000000000000 [ 122.333323] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 122.334673] CR2: 00007ffcc9698ff8 CR3: 0000000c0afae004 CR4: 00000000001606e0 [ 122.336300] Call Trace: [ 122.337011] ? __event_probe__compaction_migratepages+0x250/0x250 [lttng_probe_compaction] [ 122.338901] lttng_get_probe_list_head.part.2+0x19/0x20 [lttng_tracer] [ 122.340349] lttng_probe_register+0xd5/0xe0 [lttng_tracer] [ 122.341607] ? __event_probe__compaction_migratepages+0x250/0x250 [lttng_probe_compaction] [ 122.343453] do_one_initcall+0x3d/0x16e [ 122.344383] ? _cond_resched+0x15/0x30 [ 122.345323] ? kmem_cache_alloc_trace+0xe1/0x1b0 [ 122.346394] ? do_init_module+0x22/0x20c [ 122.347329] do_init_module+0x5a/0x20c [ 122.350037] load_module+0x244f/0x2980 [ 122.350958] ? m_show+0x190/0x190 [ 122.351774] ? security_capable+0x41/0x60 [ 122.352723] SYSC_finit_module+0x80/0xb0 [ 122.353716] do_syscall_64+0x76/0x1a0 [ 122.354565] entry_SYSCALL_64_after_hwframe+0x3d/0xa2 [ 122.355669] RIP: 0033:0x7f6c8d4c73c9 [ 122.356502] RSP: 002b:00007ffcc969c248 EFLAGS: 00000206 ORIG_RAX: 0000000000000139 [ 122.358209] RAX: ffffffffffffffda RBX: 000055763df4fee9 RCX: 00007f6c8d4c73c9 [ 122.359684] RDX: 0000000000000000 RSI: 000055763df4fee9 RDI: 0000000000000004 [ 122.361182] RBP: 0000000000000000 R08: 0000000000000000 R09: 000055763f39a450 [ 122.362663] R10: 0000000000000004 R11: 0000000000000206 R12: 000055763f392400 [ 122.364144] R13: 000055763f396cb0 R14: 000055763f3925a0 R15: 0000000000040000 [ 122.365690] Code: 25 14 a0 4a 8b 04 f0 48 8b 30 31 c0 e8 25 3b 10 e1 48 8b 43 08 48 8b 33 4c 89 e2 4a 8b 04 f0 48 8b 38 e8 9f b7 b1 e1 85 c0 74 07 <0f> 0b e9 b3 fe ff ff 48 c7 c7 16 26 14 a0 e8 f8 3a 10 e1 48 8b [ 122.369348] ---[ end trace 15840f1166edf835 ]--- Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/btrfs.h | 60 +++++++++++++++++---- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/instrumentation/events/lttng-module/btrfs.h b/instrumentation/events/lttng-module/btrfs.h index b3bf72c1..4eb0db2f 100644 --- a/instrumentation/events/lttng-module/btrfs.h +++ b/instrumentation/events/lttng-module/btrfs.h @@ -743,7 +743,11 @@ LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_ref_head, ) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + add_delayed_ref_head, + + btrfs_add_delayed_ref_head, TP_PROTO(const struct btrfs_fs_info *fs_info, const struct btrfs_delayed_ref_head *head_ref, @@ -752,7 +756,11 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, TP_ARGS(fs_info, head_ref, action) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, run_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + run_delayed_ref_head, + + btrfs_run_delayed_ref_head, TP_PROTO(const struct btrfs_fs_info *fs_info, const struct btrfs_delayed_ref_head *head_ref, @@ -780,7 +788,11 @@ LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_ref_head, ) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + add_delayed_ref_head, + + btrfs_add_delayed_ref_head, TP_PROTO(const struct btrfs_fs_info *fs_info, const struct btrfs_delayed_ref_node *ref, @@ -790,7 +802,11 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, TP_ARGS(fs_info, ref, head_ref, action) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, run_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + run_delayed_ref_head, + + btrfs_run_delayed_ref_head, TP_PROTO(const struct btrfs_fs_info *fs_info, const struct btrfs_delayed_ref_node *ref, @@ -818,7 +834,11 @@ LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_ref_head, ) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + add_delayed_ref_head, + + btrfs_add_delayed_ref_head, TP_PROTO(struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *ref, @@ -828,7 +848,11 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, TP_ARGS(fs_info, ref, head_ref, action) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, run_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + run_delayed_ref_head, + + btrfs_run_delayed_ref_head, TP_PROTO(struct btrfs_fs_info *fs_info, struct btrfs_delayed_ref_node *ref, @@ -855,7 +879,11 @@ LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_ref_head, ) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + add_delayed_ref_head, + + btrfs_add_delayed_ref_head, TP_PROTO(const struct btrfs_delayed_ref_node *ref, const struct btrfs_delayed_ref_head *head_ref, @@ -864,7 +892,11 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, TP_ARGS(ref, head_ref, action) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, run_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + run_delayed_ref_head, + + btrfs_run_delayed_ref_head, TP_PROTO(const struct btrfs_delayed_ref_node *ref, const struct btrfs_delayed_ref_head *head_ref, @@ -890,7 +922,11 @@ LTTNG_TRACEPOINT_EVENT_CLASS(btrfs_delayed_ref_head, ) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + add_delayed_ref_head, + + btrfs_add_delayed_ref_head, TP_PROTO(struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_head *head_ref, @@ -899,7 +935,11 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, add_delayed_ref_head, TP_ARGS(ref, head_ref, action) ) -LTTNG_TRACEPOINT_EVENT_INSTANCE(btrfs_delayed_ref_head, run_delayed_ref_head, +LTTNG_TRACEPOINT_EVENT_INSTANCE_MAP(btrfs_delayed_ref_head, + + run_delayed_ref_head, + + btrfs_run_delayed_ref_head, TP_PROTO(struct btrfs_delayed_ref_node *ref, struct btrfs_delayed_ref_head *head_ref, -- 2.34.1 From 3b907b884cb5ac6ade60004f0182c6430f0493c0 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Fri, 23 Mar 2018 11:41:46 -0400 Subject: [PATCH 07/16] Fix: update kvm instrumentation for Ubuntu 3.13.0-144 Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/kvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/events/lttng-module/kvm.h b/instrumentation/events/lttng-module/kvm.h index 8f9a1328..85aa8a74 100644 --- a/instrumentation/events/lttng-module/kvm.h +++ b/instrumentation/events/lttng-module/kvm.h @@ -91,6 +91,7 @@ LTTNG_TRACEPOINT_EVENT(kvm_ack_irq, || LTTNG_KERNEL_RANGE(4,4,112, 4,5,0) \ || LTTNG_KERNEL_RANGE(4,1,50, 4,2,0) \ || LTTNG_KERNEL_RANGE(3,16,52, 3,17,0) \ + || LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,144, 3,14,0,0) \ || LTTNG_KERNEL_RANGE(3,2,97, 3,3,0) \ || LTTNG_DEBIAN_KERNEL_RANGE(4,9,65,0,3,0, 4,10,0,0,0,0) \ || LTTNG_FEDORA_KERNEL_RANGE(4,14,13,300, 4,15,0,0)) -- 2.34.1 From fcf8037d3ae12d2af5d02bae4fa8451bee62a7d9 Mon Sep 17 00:00:00 2001 From: Khalid Elmously Date: Sun, 25 Mar 2018 11:06:03 -0400 Subject: [PATCH 08/16] Update: kvm instrumentation for ubuntu 4.13.0-38 Starting from 4.13.0-38 the ubuntu kernel backport a kvm instrumentation change introduced in 4.15 which affects the prototype of the kvm_mmio event. Signed-off-by: Khalid Elmously Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/kvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/events/lttng-module/kvm.h b/instrumentation/events/lttng-module/kvm.h index 85aa8a74..9bb08c55 100644 --- a/instrumentation/events/lttng-module/kvm.h +++ b/instrumentation/events/lttng-module/kvm.h @@ -93,6 +93,7 @@ LTTNG_TRACEPOINT_EVENT(kvm_ack_irq, || LTTNG_KERNEL_RANGE(3,16,52, 3,17,0) \ || LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,144, 3,14,0,0) \ || LTTNG_KERNEL_RANGE(3,2,97, 3,3,0) \ + || LTTNG_UBUNTU_KERNEL_RANGE(4,13,16,38, 4,14,0,0) \ || LTTNG_DEBIAN_KERNEL_RANGE(4,9,65,0,3,0, 4,10,0,0,0,0) \ || LTTNG_FEDORA_KERNEL_RANGE(4,14,13,300, 4,15,0,0)) -- 2.34.1 From 3f65e00d72b3b8938d57c042172e124496a0c070 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 17 Apr 2018 11:07:45 -0400 Subject: [PATCH 09/16] Fix: Add gfp_flags arg to mm_vmscan_kswapd_wake for 4.17 See upstream commit: commit 5ecd9d403ad081ed2de7b118c1e96124d4e0ba6c Author: David Rientjes Date: Thu Apr 5 16:25:16 2018 -0700 mm, page_alloc: wakeup kcompactd even if kswapd cannot free more memory Kswapd will not wakeup if per-zone watermarks are not failing or if too many previous attempts at background reclaim have failed. This can be true if there is a lot of free memory available. For high- order allocations, kswapd is responsible for waking up kcompactd for background compaction. If the zone is not below its watermarks or reclaim has recently failed (lots of free memory, nothing left to reclaim), kcompactd does not get woken up. When __GFP_DIRECT_RECLAIM is not allowed, allow kcompactd to still be woken up even if kswapd will not reclaim. This allows high-order allocations, such as thp, to still trigger background compaction even when the zone has an abundance of free memory. Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/mm_vmscan.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/instrumentation/events/lttng-module/mm_vmscan.h b/instrumentation/events/lttng-module/mm_vmscan.h index a69b42fe..9661c9d4 100644 --- a/instrumentation/events/lttng-module/mm_vmscan.h +++ b/instrumentation/events/lttng-module/mm_vmscan.h @@ -84,6 +84,21 @@ LTTNG_TRACEPOINT_EVENT(mm_vmscan_kswapd_wake, #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) +LTTNG_TRACEPOINT_EVENT(mm_vmscan_wakeup_kswapd, + + TP_PROTO(int nid, int zid, int order, gfp_t gfp_flags), + + TP_ARGS(nid, zid, order, gfp_flags), + + TP_FIELDS( + ctf_integer(int, nid, nid) + ctf_integer(int, zid, zid) + ctf_integer(int, order, order) + ctf_integer(gfp_t, gfp_flags, gfp_flags) + ) +) +#else LTTNG_TRACEPOINT_EVENT(mm_vmscan_wakeup_kswapd, TP_PROTO(int nid, int zid, int order), @@ -96,6 +111,7 @@ LTTNG_TRACEPOINT_EVENT(mm_vmscan_wakeup_kswapd, ctf_integer(int, order, order) ) ) +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0)) -- 2.34.1 From 3d64c22ed9663f5db5eb6bbff189cd1b1b339336 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 17 Apr 2018 11:07:46 -0400 Subject: [PATCH 10/16] Fix: use struct reclaim_stat in mm_vmscan_lru_shrink_inactive for 4.17 See upstream commit: commit d51d1e64500fcb48fc6a18c77c965b8f48a175f2 Author: Steven Rostedt Date: Tue Apr 10 16:28:07 2018 -0700 mm, vmscan, tracing: use pointer to reclaim_stat struct in trace event The trace event trace_mm_vmscan_lru_shrink_inactive() currently has 12 parameters! Seven of them are from the reclaim_stat structure. This structure is currently local to mm/vmscan.c. By moving it to the global vmstat.h header, we can also reference it from the vmscan tracepoints. In moving it, it brings down the overhead of passing so many arguments to the trace event. In the future, we may limit the number of arguments that a trace event may pass (ideally just 6, but more realistically it may be 8). Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- .../events/lttng-module/mm_vmscan.h | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/instrumentation/events/lttng-module/mm_vmscan.h b/instrumentation/events/lttng-module/mm_vmscan.h index 9661c9d4..9a77ead9 100644 --- a/instrumentation/events/lttng-module/mm_vmscan.h +++ b/instrumentation/events/lttng-module/mm_vmscan.h @@ -550,7 +550,31 @@ LTTNG_TRACEPOINT_EVENT(mm_vmscan_writepage, ) #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) +LTTNG_TRACEPOINT_EVENT(mm_vmscan_lru_shrink_inactive, + + TP_PROTO(int nid, + unsigned long nr_scanned, unsigned long nr_reclaimed, + struct reclaim_stat *stat, int priority, int file), + + TP_ARGS(nid, nr_scanned, nr_reclaimed, stat, priority, file), + + TP_FIELDS( + ctf_integer(int, nid, nid) + ctf_integer(unsigned long, nr_scanned, nr_scanned) + ctf_integer(unsigned long, nr_reclaimed, nr_reclaimed) + ctf_integer(unsigned long, nr_dirty, stat->nr_dirty) + ctf_integer(unsigned long, nr_writeback, stat->nr_writeback) + ctf_integer(unsigned long, nr_congested, stat->nr_congested) + ctf_integer(unsigned long, nr_immediate, stat->nr_immediate) + ctf_integer(unsigned long, nr_activate, stat->nr_activate) + ctf_integer(unsigned long, nr_ref_keep, stat->nr_ref_keep) + ctf_integer(unsigned long, nr_unmap_fail, stat->nr_unmap_fail) + ctf_integer(int, priority, priority) + ctf_integer(int, reclaim_flags, trace_shrink_flags(file)) + ) +) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)) LTTNG_TRACEPOINT_EVENT(mm_vmscan_lru_shrink_inactive, TP_PROTO(int nid, -- 2.34.1 From 1d93f931374748651b7481db73a25f3eb644f86c Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 17 Apr 2018 11:07:47 -0400 Subject: [PATCH 11/16] Fix: sunrpc instrumentation for 4.17 See upstream commit: commit e671edb9428c8a61662aaf8c39f5edced7cc45c7 Author: Chuck Lever Date: Fri Mar 16 10:33:44 2018 -0400 sunrpc: Simplify synopsis of some trace points Clean up: struct rpc_task carries a pointer to a struct rpc_clnt, and in fact task->tk_client is always what is passed into trace points that are already passing @task. Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/rpc.h | 88 +++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/instrumentation/events/lttng-module/rpc.h b/instrumentation/events/lttng-module/rpc.h index 29e0cd7b..b9e45fef 100644 --- a/instrumentation/events/lttng-module/rpc.h +++ b/instrumentation/events/lttng-module/rpc.h @@ -33,6 +33,88 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_status, rpc_bind_status, TP_ARGS(task) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) +LTTNG_TRACEPOINT_EVENT(rpc_connect_status, + TP_PROTO(const struct rpc_task *task), + + TP_ARGS(task), + + TP_FIELDS( + ctf_integer_hex(const struct rpc_task *, task, task) + ctf_integer_hex(const struct rpc_clnt *, clnt, task->tk_client) + ctf_integer(int, status, task->tk_status) + ) +) + +LTTNG_TRACEPOINT_EVENT_CLASS(rpc_task_running, + + TP_PROTO(const struct rpc_task *task, const void *action), + + TP_ARGS(task, action), + + TP_FIELDS( + ctf_integer_hex(const struct rpc_clnt *, clnt, task->tk_client) + ctf_integer_hex(const struct rpc_task *, task, task) + ctf_integer_hex(const void *, action, action) + ctf_integer(unsigned long, runstate, task->tk_runstate) + ctf_integer(int, status, task->tk_status) + ctf_integer(unsigned short, flags, task->tk_flags) + ) +) + +LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_begin, + + TP_PROTO(const struct rpc_task *task, const void *action), + + TP_ARGS(task, action) +) + +LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_run_action, + + TP_PROTO(const struct rpc_task *task, const void *action), + + TP_ARGS(task, action) +) + +LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_complete, + + TP_PROTO(const struct rpc_task *task, const void *action), + + TP_ARGS(task, action) +) + +LTTNG_TRACEPOINT_EVENT_CLASS(rpc_task_queued, + + TP_PROTO(const struct rpc_task *task, const struct rpc_wait_queue *q), + + TP_ARGS(task, q), + + TP_FIELDS( + ctf_integer_hex(const struct rpc_clnt *, clnt, task->tk_client) + ctf_integer_hex(const struct rpc_task *, task, task) + ctf_integer(unsigned long, timeout, task->tk_timeout) + ctf_integer(unsigned long, runstate, task->tk_runstate) + ctf_integer(int, status, task->tk_status) + ctf_integer(unsigned short, flags, task->tk_flags) + ctf_string(q_name, rpc_qname(q)) + ) +) + +LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_queued, rpc_task_sleep, + + TP_PROTO(const struct rpc_task *task, const struct rpc_wait_queue *q), + + TP_ARGS(task, q) +) + +LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_queued, rpc_task_wakeup, + + TP_PROTO(const struct rpc_task *task, const struct rpc_wait_queue *q), + + TP_ARGS(task, q) +) + +#else LTTNG_TRACEPOINT_EVENT(rpc_connect_status, TP_PROTO(struct rpc_task *task, int status), @@ -66,7 +148,6 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_begin, TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action), TP_ARGS(clnt, task, action) - ) LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_run_action, @@ -74,7 +155,6 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_run_action, TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action), TP_ARGS(clnt, task, action) - ) LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_complete, @@ -82,7 +162,6 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_running, rpc_task_complete, TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action), TP_ARGS(clnt, task, action) - ) LTTNG_TRACEPOINT_EVENT_CLASS(rpc_task_queued, @@ -107,7 +186,6 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_queued, rpc_task_sleep, TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q), TP_ARGS(clnt, task, q) - ) LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_queued, rpc_task_wakeup, @@ -115,8 +193,8 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(rpc_task_queued, rpc_task_wakeup, TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q), TP_ARGS(clnt, task, q) - ) +#endif #endif /* LTTNG_TRACE_RPC_H */ -- 2.34.1 From d3c50f6c6cf99fe2555c4ff9bb434e9718f4dacd Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 1 May 2018 16:42:44 -0400 Subject: [PATCH 12/16] Fix: update RCU instrumentation for 4.17 Signed-off-by: Mathieu Desnoyers --- instrumentation/events/lttng-module/rcu.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/instrumentation/events/lttng-module/rcu.h b/instrumentation/events/lttng-module/rcu.h index 4528a79b..7760bd6e 100644 --- a/instrumentation/events/lttng-module/rcu.h +++ b/instrumentation/events/lttng-module/rcu.h @@ -612,7 +612,9 @@ LTTNG_TRACEPOINT_EVENT(rcu_barrier, grplo, grphi, gp_tasks) do { } \ while (0) #define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)) +#define trace_rcu_dyntick(polarity, oldnesting, newnesting, dyntick) do { } while (0) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) #define trace_rcu_dyntick(polarity, oldnesting, newnesting) do { } while (0) #else #define trace_rcu_dyntick(polarity) do { } while (0) -- 2.34.1 From 50f48712d7d32a8d6e67b8f18f4f5559df24b5cc Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 9 May 2018 14:12:56 -0400 Subject: [PATCH 13/16] Version 2.9.9 Signed-off-by: Mathieu Desnoyers --- ChangeLog | 24 ++++++++++++++++++++++++ lttng-tracer.h | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4cc67a98..bb4c2f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2018-05-09 (Lost Sock Memorial Day) LTTng modules 2.9.9 + * Fix: update RCU instrumentation for 4.17 + * Fix: sunrpc instrumentation for 4.17 + * Fix: use struct reclaim_stat in mm_vmscan_lru_shrink_inactive for 4.17 + * Fix: Add gfp_flags arg to mm_vmscan_kswapd_wake for 4.17 + * Update: kvm instrumentation for ubuntu 4.13.0-38 + * Fix: update kvm instrumentation for Ubuntu 3.13.0-144 + * Fix: btrfs instrumentation namespacing + * Cleanup: comment about CONFIG_HOTPLUG_CPU ifdef + * Fix: do not use CONFIG_HOTPLUG_CPU for the new hotplug API + * Fix: update kvm instrumentation for 4.1.50+ + * Use the memory pool instead of kmalloc + * Create a memory pool for temporary tracepoint probes storage + * Fix: use proper pid_ns in the process statedump + * Fix: add variable quoting to shell scripts + * Update: kvm instrumentation for fedora 4.14.13-300 + * Fix: Add Fedora version macros + * Fix: update btrfs instrumentation for SuSE 4.4.114-92 + * Fix: update block instrumentation for SuSE 4.4.114-92 + * Fix: update rcu instrumentation for v4.16 + * Fix: update vmscan instrumentation for v4.16 + * Fix: update timer instrumentation on 4.16 and 4.14-rt + * Update kvm instrumentation for debian kernel 4.14.0-3 + 2018-01-30 (National Croissant Day) LTTng modules 2.9.8 * Fix: network instrumentation protocol enum * Fix: update btrfs instrumentation for SuSE 4.4.103-6 diff --git a/lttng-tracer.h b/lttng-tracer.h index 5e1d3822..88709c68 100644 --- a/lttng-tracer.h +++ b/lttng-tracer.h @@ -42,7 +42,7 @@ #define LTTNG_MODULES_MAJOR_VERSION 2 #define LTTNG_MODULES_MINOR_VERSION 9 -#define LTTNG_MODULES_PATCHLEVEL_VERSION 8 +#define LTTNG_MODULES_PATCHLEVEL_VERSION 9 #define LTTNG_MODULES_EXTRAVERSION "" #define LTTNG_VERSION_NAME "Joannès" -- 2.34.1 From 6599a4eb8b93ae14c01fe301c7e953047a71e2af Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 17 May 2018 14:20:47 -0400 Subject: [PATCH 14/16] ID tracker: implement vpid/uid/vuid/gid/vgid trackers Signed-off-by: Mathieu Desnoyers --- Makefile | 2 +- lttng-abi.c | 78 ++++++- lttng-abi.h | 23 ++ lttng-events.c | 245 ++++++++++++---------- lttng-events.h | 59 ++++-- lttng-tracker-pid.c => lttng-tracker-id.c | 125 +++++++---- probes/lttng-tracepoint-event-impl.h | 51 ++++- 7 files changed, 410 insertions(+), 173 deletions(-) rename lttng-tracker-pid.c => lttng-tracker-id.c (53%) diff --git a/Makefile b/Makefile index dfa5a588..8414837b 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ ifneq ($(KERNELRELEASE),) lttng-context-hostname.o wrapper/random.o \ probes/lttng.o wrapper/trace-clock.o \ wrapper/page_alloc.o \ - lttng-tracker-pid.o \ + lttng-tracker-id.o \ lttng-filter.o lttng-filter-interpreter.o \ lttng-filter-specialize.o \ lttng-filter-validator.o \ diff --git a/lttng-abi.c b/lttng-abi.c index c45c10f4..18b11507 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -463,6 +463,27 @@ fd_error: return ret; } +static +enum tracker_type get_tracker_type(struct lttng_kernel_tracker_args *tracker) +{ + switch (tracker->type) { + case LTTNG_KERNEL_TRACKER_PID: + return TRACKER_PID; + case LTTNG_KERNEL_TRACKER_VPID: + return TRACKER_VPID; + case LTTNG_KERNEL_TRACKER_UID: + return TRACKER_UID; + case LTTNG_KERNEL_TRACKER_VUID: + return TRACKER_VUID; + case LTTNG_KERNEL_TRACKER_GID: + return TRACKER_GID; + case LTTNG_KERNEL_TRACKER_VGID: + return TRACKER_VGID; + default: + return TRACKER_UNKNOWN; + } +} + /** * lttng_session_ioctl - lttng session fd ioctl * @@ -480,9 +501,13 @@ fd_error: * LTTNG_KERNEL_METADATA * Returns a LTTng metadata file descriptor * LTTNG_KERNEL_SESSION_TRACK_PID - * Add PID to session tracker + * Add PID to session PID tracker * LTTNG_KERNEL_SESSION_UNTRACK_PID - * Remove PID from session tracker + * Remove PID from session PID tracker + * LTTNG_KERNEL_SESSION_TRACK_ID + * Add ID to tracker + * LTTNG_KERNEL_SESSION_UNTRACK_ID + * Remove ID from tracker * * The returned channel will be deleted when its file descriptor is closed. */ @@ -563,11 +588,54 @@ long lttng_session_ioctl(struct file *file, unsigned int cmd, unsigned long arg) METADATA_CHANNEL); } case LTTNG_KERNEL_SESSION_TRACK_PID: - return lttng_session_track_pid(session, (int) arg); + return lttng_session_track_id(session, TRACKER_PID, (int) arg); case LTTNG_KERNEL_SESSION_UNTRACK_PID: - return lttng_session_untrack_pid(session, (int) arg); + return lttng_session_untrack_id(session, TRACKER_PID, (int) arg); + case LTTNG_KERNEL_SESSION_TRACK_ID: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_track_id(session, tracker_type, tracker.id); + } + case LTTNG_KERNEL_SESSION_UNTRACK_ID: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_untrack_id(session, tracker_type, + tracker.id); + } case LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS: - return lttng_session_list_tracker_pids(session); + return lttng_session_list_tracker_ids(session, TRACKER_PID); + case LTTNG_KERNEL_SESSION_LIST_TRACKER_IDS: + { + struct lttng_kernel_tracker_args tracker; + enum tracker_type tracker_type; + + if (copy_from_user(&tracker, + (struct lttng_kernel_tracker_args __user *) arg, + sizeof(struct lttng_kernel_tracker_args))) + return -EFAULT; + tracker_type = get_tracker_type(&tracker); + if (tracker_type == TRACKER_UNKNOWN) + return -EINVAL; + return lttng_session_list_tracker_ids(session, tracker_type); + } case LTTNG_KERNEL_SESSION_METADATA_REGEN: return lttng_session_metadata_regenerate(session); case LTTNG_KERNEL_SESSION_STATEDUMP: diff --git a/lttng-abi.h b/lttng-abi.h index 822b8839..dba0f20f 100644 --- a/lttng-abi.h +++ b/lttng-abi.h @@ -174,6 +174,22 @@ struct lttng_kernel_filter_bytecode { char data[0]; } __attribute__((packed)); +enum lttng_kernel_tracker_type { + LTTNG_KERNEL_TRACKER_UNKNOWN = -1, + + LTTNG_KERNEL_TRACKER_PID = 0, + LTTNG_KERNEL_TRACKER_VPID = 1, + LTTNG_KERNEL_TRACKER_UID = 2, + LTTNG_KERNEL_TRACKER_VUID = 3, + LTTNG_KERNEL_TRACKER_GID = 4, + LTTNG_KERNEL_TRACKER_VGID = 5, +}; + +struct lttng_kernel_tracker_args { + enum lttng_kernel_tracker_type type; + int32_t id; +}; + /* LTTng file descriptor ioctl */ #define LTTNG_KERNEL_SESSION _IO(0xF6, 0x45) #define LTTNG_KERNEL_TRACER_VERSION \ @@ -197,6 +213,7 @@ struct lttng_kernel_filter_bytecode { _IOR(0xF6, 0x58, int32_t) #define LTTNG_KERNEL_SESSION_UNTRACK_PID \ _IOR(0xF6, 0x59, int32_t) + /* * ioctl 0x58 and 0x59 are duplicated here. It works, since _IOR vs _IO * are generating two different ioctl numbers, but this was not done on @@ -206,6 +223,12 @@ struct lttng_kernel_filter_bytecode { #define LTTNG_KERNEL_SESSION_METADATA_REGEN _IO(0xF6, 0x59) /* 0x5A and 0x5B are reserved for a future ABI-breaking cleanup. */ #define LTTNG_KERNEL_SESSION_STATEDUMP _IO(0xF6, 0x5C) +#define LTTNG_KERNEL_SESSION_LIST_TRACKER_IDS \ + _IOR(0xF6, 0x5D, struct lttng_kernel_tracker_args) +#define LTTNG_KERNEL_SESSION_TRACK_ID \ + _IOR(0xF6, 0x5E, struct lttng_kernel_tracker_args) +#define LTTNG_KERNEL_SESSION_UNTRACK_ID \ + _IOR(0xF6, 0x5F, struct lttng_kernel_tracker_args) /* Channel FD ioctl */ #define LTTNG_KERNEL_STREAM _IO(0xF6, 0x62) diff --git a/lttng-events.c b/lttng-events.c index 5e9c72bf..ea2c5841 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -155,6 +155,18 @@ struct lttng_session *lttng_session_create(void) for (i = 0; i < LTTNG_EVENT_HT_SIZE; i++) INIT_HLIST_HEAD(&session->events_ht.table[i]); list_add(&session->list, &sessions); + session->pid_tracker.session = session; + session->pid_tracker.tracker_type = TRACKER_PID; + session->vpid_tracker.session = session; + session->vpid_tracker.tracker_type = TRACKER_VPID; + session->uid_tracker.session = session; + session->uid_tracker.tracker_type = TRACKER_UID; + session->vuid_tracker.session = session; + session->vuid_tracker.tracker_type = TRACKER_VUID; + session->gid_tracker.session = session; + session->gid_tracker.tracker_type = TRACKER_GID; + session->vgid_tracker.session = session; + session->vgid_tracker.tracker_type = TRACKER_VGID; mutex_unlock(&sessions_mutex); return session; @@ -205,8 +217,12 @@ void lttng_session_destroy(struct lttng_session *session) } list_for_each_entry(metadata_stream, &session->metadata_cache->metadata_stream, list) _lttng_metadata_channel_hangup(metadata_stream); - if (session->pid_tracker) - lttng_pid_tracker_destroy(session->pid_tracker); + lttng_id_tracker_destroy(&session->pid_tracker, false); + lttng_id_tracker_destroy(&session->vpid_tracker, false); + lttng_id_tracker_destroy(&session->uid_tracker, false); + lttng_id_tracker_destroy(&session->vuid_tracker, false); + lttng_id_tracker_destroy(&session->gid_tracker, false); + lttng_id_tracker_destroy(&session->vgid_tracker, false); kref_put(&session->metadata_cache->refcount, metadata_cache_destroy); list_del(&session->list); mutex_unlock(&sessions_mutex); @@ -904,91 +920,85 @@ void _lttng_event_destroy(struct lttng_event *event) kmem_cache_free(event_cache, event); } -int lttng_session_track_pid(struct lttng_session *session, int pid) +struct lttng_id_tracker *get_tracker(struct lttng_session *session, + enum tracker_type tracker_type) +{ + switch (tracker_type) { + case TRACKER_PID: + return &session->pid_tracker; + case TRACKER_VPID: + return &session->vpid_tracker; + case TRACKER_UID: + return &session->uid_tracker; + case TRACKER_VUID: + return &session->vuid_tracker; + case TRACKER_GID: + return &session->gid_tracker; + case TRACKER_VGID: + return &session->vgid_tracker; + default: + WARN_ON_ONCE(1); + return NULL; + } +} + +int lttng_session_track_id(struct lttng_session *session, + enum tracker_type tracker_type, int id) { + struct lttng_id_tracker *tracker; int ret; - if (pid < -1) + tracker = get_tracker(session, tracker_type); + if (!tracker) + return -EINVAL; + if (id < -1) return -EINVAL; mutex_lock(&sessions_mutex); - if (pid == -1) { - /* track all pids: destroy tracker. */ - if (session->pid_tracker) { - struct lttng_pid_tracker *lpf; - - lpf = session->pid_tracker; - rcu_assign_pointer(session->pid_tracker, NULL); - synchronize_trace(); - lttng_pid_tracker_destroy(lpf); - } + if (id == -1) { + /* track all ids: destroy tracker. */ + lttng_id_tracker_destroy(tracker, true); ret = 0; } else { - if (!session->pid_tracker) { - struct lttng_pid_tracker *lpf; - - lpf = lttng_pid_tracker_create(); - if (!lpf) { - ret = -ENOMEM; - goto unlock; - } - ret = lttng_pid_tracker_add(lpf, pid); - rcu_assign_pointer(session->pid_tracker, lpf); - } else { - ret = lttng_pid_tracker_add(session->pid_tracker, pid); - } + ret = lttng_id_tracker_add(tracker, id); } -unlock: mutex_unlock(&sessions_mutex); return ret; } -int lttng_session_untrack_pid(struct lttng_session *session, int pid) +int lttng_session_untrack_id(struct lttng_session *session, + enum tracker_type tracker_type, int id) { + struct lttng_id_tracker *tracker; int ret; - if (pid < -1) + tracker = get_tracker(session, tracker_type); + if (!tracker) + return -EINVAL; + if (id < -1) return -EINVAL; mutex_lock(&sessions_mutex); - if (pid == -1) { - /* untrack all pids: replace by empty tracker. */ - struct lttng_pid_tracker *old_lpf = session->pid_tracker; - struct lttng_pid_tracker *lpf; - - lpf = lttng_pid_tracker_create(); - if (!lpf) { - ret = -ENOMEM; - goto unlock; - } - rcu_assign_pointer(session->pid_tracker, lpf); - synchronize_trace(); - if (old_lpf) - lttng_pid_tracker_destroy(old_lpf); - ret = 0; + if (id == -1) { + /* untrack all ids: replace by empty tracker. */ + ret = lttng_id_tracker_empty_set(tracker); } else { - if (!session->pid_tracker) { - ret = -ENOENT; - goto unlock; - } - ret = lttng_pid_tracker_del(session->pid_tracker, pid); + ret = lttng_id_tracker_del(tracker, id); } -unlock: mutex_unlock(&sessions_mutex); return ret; } static -void *pid_list_start(struct seq_file *m, loff_t *pos) +void *id_list_start(struct seq_file *m, loff_t *pos) { - struct lttng_session *session = m->private; - struct lttng_pid_tracker *lpf; - struct lttng_pid_hash_node *e; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + struct lttng_id_hash_node *e; int iter = 0, i; mutex_lock(&sessions_mutex); - lpf = session->pid_tracker; - if (lpf) { - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; + if (id_tracker_p) { + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &id_tracker_p->id_hash[i]; lttng_hlist_for_each_entry(e, head, hlist) { if (iter++ >= *pos) @@ -996,9 +1006,9 @@ void *pid_list_start(struct seq_file *m, loff_t *pos) } } } else { - /* PID tracker disabled. */ + /* ID tracker disabled. */ if (iter >= *pos && iter == 0) { - return session; /* empty tracker */ + return id_tracker_p; /* empty tracker */ } iter++; } @@ -1008,18 +1018,17 @@ void *pid_list_start(struct seq_file *m, loff_t *pos) /* Called with sessions_mutex held. */ static -void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) +void *id_list_next(struct seq_file *m, void *p, loff_t *ppos) { - struct lttng_session *session = m->private; - struct lttng_pid_tracker *lpf; - struct lttng_pid_hash_node *e; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + struct lttng_id_hash_node *e; int iter = 0, i; (*ppos)++; - lpf = session->pid_tracker; - if (lpf) { - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; + if (id_tracker_p) { + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &id_tracker_p->id_hash[i]; lttng_hlist_for_each_entry(e, head, hlist) { if (iter++ >= *ppos) @@ -1027,9 +1036,9 @@ void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) } } } else { - /* PID tracker disabled. */ + /* ID tracker disabled. */ if (iter >= *ppos && iter == 0) - return session; /* empty tracker */ + return p; /* empty tracker */ iter++; } @@ -1038,67 +1047,91 @@ void *pid_list_next(struct seq_file *m, void *p, loff_t *ppos) } static -void pid_list_stop(struct seq_file *m, void *p) +void id_list_stop(struct seq_file *m, void *p) { mutex_unlock(&sessions_mutex); } static -int pid_list_show(struct seq_file *m, void *p) +int id_list_show(struct seq_file *m, void *p) { - int pid; + struct lttng_id_tracker *id_tracker = m->private; + struct lttng_id_tracker_rcu *id_tracker_p = id_tracker->p; + int id; - if (p == m->private) { + if (p == id_tracker_p) { /* Tracker disabled. */ - pid = -1; + id = -1; } else { - const struct lttng_pid_hash_node *e = p; + const struct lttng_id_hash_node *e = p; - pid = lttng_pid_tracker_get_node_pid(e); + id = lttng_id_tracker_get_node_id(e); + } + switch (id_tracker->tracker_type) { + case TRACKER_PID: + seq_printf(m, "process { pid = %d; };\n", id); + break; + case TRACKER_VPID: + seq_printf(m, "process { vpid = %d; };\n", id); + break; + case TRACKER_UID: + seq_printf(m, "user { uid = %d; };\n", id); + break; + case TRACKER_VUID: + seq_printf(m, "user { vuid = %d; };\n", id); + break; + case TRACKER_GID: + seq_printf(m, "group { gid = %d; };\n", id); + break; + case TRACKER_VGID: + seq_printf(m, "group { vgid = %d; };\n", id); + break; + default: + seq_printf(m, "UNKNOWN { field = %d };\n", id); } - seq_printf(m, "process { pid = %d; };\n", pid); return 0; } static -const struct seq_operations lttng_tracker_pids_list_seq_ops = { - .start = pid_list_start, - .next = pid_list_next, - .stop = pid_list_stop, - .show = pid_list_show, +const struct seq_operations lttng_tracker_ids_list_seq_ops = { + .start = id_list_start, + .next = id_list_next, + .stop = id_list_stop, + .show = id_list_show, }; static -int lttng_tracker_pids_list_open(struct inode *inode, struct file *file) +int lttng_tracker_ids_list_open(struct inode *inode, struct file *file) { - return seq_open(file, <tng_tracker_pids_list_seq_ops); + return seq_open(file, <tng_tracker_ids_list_seq_ops); } static -int lttng_tracker_pids_list_release(struct inode *inode, struct file *file) +int lttng_tracker_ids_list_release(struct inode *inode, struct file *file) { struct seq_file *m = file->private_data; - struct lttng_session *session = m->private; + struct lttng_id_tracker *id_tracker = m->private; int ret; - WARN_ON_ONCE(!session); + WARN_ON_ONCE(!id_tracker); ret = seq_release(inode, file); - if (!ret && session) - fput(session->file); + if (!ret) + fput(id_tracker->session->file); return ret; } -const struct file_operations lttng_tracker_pids_list_fops = { +const struct file_operations lttng_tracker_ids_list_fops = { .owner = THIS_MODULE, - .open = lttng_tracker_pids_list_open, + .open = lttng_tracker_ids_list_open, .read = seq_read, .llseek = seq_lseek, - .release = lttng_tracker_pids_list_release, + .release = lttng_tracker_ids_list_release, }; -int lttng_session_list_tracker_pids(struct lttng_session *session) +int lttng_session_list_tracker_ids(struct lttng_session *session, + enum tracker_type tracker_type) { - struct file *tracker_pids_list_file; + struct file *tracker_ids_list_file; struct seq_file *m; int file_fd, ret; @@ -1108,30 +1141,32 @@ int lttng_session_list_tracker_pids(struct lttng_session *session) goto fd_error; } - tracker_pids_list_file = anon_inode_getfile("[lttng_tracker_pids_list]", - <tng_tracker_pids_list_fops, + tracker_ids_list_file = anon_inode_getfile("[lttng_tracker_ids_list]", + <tng_tracker_ids_list_fops, NULL, O_RDWR); - if (IS_ERR(tracker_pids_list_file)) { - ret = PTR_ERR(tracker_pids_list_file); + if (IS_ERR(tracker_ids_list_file)) { + ret = PTR_ERR(tracker_ids_list_file); goto file_error; } if (atomic_long_add_unless(&session->file->f_count, 1, INT_MAX) == INT_MAX) { goto refcount_error; } - ret = lttng_tracker_pids_list_fops.open(NULL, tracker_pids_list_file); + ret = lttng_tracker_ids_list_fops.open(NULL, tracker_ids_list_file); if (ret < 0) goto open_error; - m = tracker_pids_list_file->private_data; - m->private = session; - fd_install(file_fd, tracker_pids_list_file); + m = tracker_ids_list_file->private_data; + + m->private = get_tracker(session, tracker_type); + BUG_ON(!m->private); + fd_install(file_fd, tracker_ids_list_file); return file_fd; open_error: atomic_long_dec(&session->file->f_count); refcount_error: - fput(tracker_pids_list_file); + fput(tracker_ids_list_file); file_error: put_unused_fd(file_fd); fd_error: diff --git a/lttng-events.h b/lttng-events.h index 5a96bf31..c3f23a5e 100644 --- a/lttng-events.h +++ b/lttng-events.h @@ -478,19 +478,36 @@ struct lttng_dynamic_len_stack { DECLARE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack); /* - * struct lttng_pid_tracker declared in header due to deferencing of *v + * struct lttng_id_tracker declared in header due to deferencing of *v * in RCU_INITIALIZER(v). */ -#define LTTNG_PID_HASH_BITS 6 -#define LTTNG_PID_TABLE_SIZE (1 << LTTNG_PID_HASH_BITS) +#define LTTNG_ID_HASH_BITS 6 +#define LTTNG_ID_TABLE_SIZE (1 << LTTNG_ID_HASH_BITS) -struct lttng_pid_tracker { - struct hlist_head pid_hash[LTTNG_PID_TABLE_SIZE]; +enum tracker_type { + TRACKER_PID, + TRACKER_VPID, + TRACKER_UID, + TRACKER_VUID, + TRACKER_GID, + TRACKER_VGID, + + TRACKER_UNKNOWN, +}; + +struct lttng_id_tracker_rcu { + struct hlist_head id_hash[LTTNG_ID_TABLE_SIZE]; +}; + +struct lttng_id_tracker { + struct lttng_session *session; + enum tracker_type tracker_type; + struct lttng_id_tracker_rcu *p; /* RCU dereferenced. */ }; -struct lttng_pid_hash_node { +struct lttng_id_hash_node { struct hlist_node hlist; - int pid; + int id; }; struct lttng_session { @@ -503,7 +520,12 @@ struct lttng_session { unsigned int free_chan_id; /* Next chan ID to allocate */ uuid_le uuid; /* Trace session unique ID */ struct lttng_metadata_cache *metadata_cache; - struct lttng_pid_tracker *pid_tracker; + struct lttng_id_tracker pid_tracker; + struct lttng_id_tracker vpid_tracker; + struct lttng_id_tracker uid_tracker; + struct lttng_id_tracker vuid_tracker; + struct lttng_id_tracker gid_tracker; + struct lttng_id_tracker vgid_tracker; unsigned int metadata_dumped:1, tstate:1; /* Transient enable state */ /* List of enablers */ @@ -598,17 +620,20 @@ void lttng_probes_exit(void); int lttng_metadata_output_channel(struct lttng_metadata_stream *stream, struct channel *chan); -int lttng_pid_tracker_get_node_pid(const struct lttng_pid_hash_node *node); -struct lttng_pid_tracker *lttng_pid_tracker_create(void); -void lttng_pid_tracker_destroy(struct lttng_pid_tracker *lpf); -bool lttng_pid_tracker_lookup(struct lttng_pid_tracker *lpf, int pid); -int lttng_pid_tracker_add(struct lttng_pid_tracker *lpf, int pid); -int lttng_pid_tracker_del(struct lttng_pid_tracker *lpf, int pid); +int lttng_id_tracker_get_node_id(const struct lttng_id_hash_node *node); +int lttng_id_tracker_empty_set(struct lttng_id_tracker *lf); +void lttng_id_tracker_destroy(struct lttng_id_tracker *lf, bool rcu); +bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id); +int lttng_id_tracker_add(struct lttng_id_tracker *lf, int id); +int lttng_id_tracker_del(struct lttng_id_tracker *lf, int id); -int lttng_session_track_pid(struct lttng_session *session, int pid); -int lttng_session_untrack_pid(struct lttng_session *session, int pid); +int lttng_session_track_id(struct lttng_session *session, + enum tracker_type tracker_type, int id); +int lttng_session_untrack_id(struct lttng_session *session, + enum tracker_type tracker_type, int id); -int lttng_session_list_tracker_pids(struct lttng_session *session); +int lttng_session_list_tracker_ids(struct lttng_session *session, + enum tracker_type tracker_type); void lttng_clock_ref(void); void lttng_clock_unref(void); diff --git a/lttng-tracker-pid.c b/lttng-tracker-id.c similarity index 53% rename from lttng-tracker-pid.c rename to lttng-tracker-id.c index 02b15c42..9194c2d3 100644 --- a/lttng-tracker-pid.c +++ b/lttng-tracker-id.c @@ -43,62 +43,83 @@ * sessions_mutex across calls to create, destroy, add, and del * functions of this API. */ -int lttng_pid_tracker_get_node_pid(const struct lttng_pid_hash_node *node) +int lttng_id_tracker_get_node_id(const struct lttng_id_hash_node *node) { - return node->pid; + return node->id; } /* * Lookup performed from RCU read-side critical section (RCU sched), * protected by preemption off at the tracepoint call site. - * Return 1 if found, 0 if not found. + * Return true if found, false if not found. */ -bool lttng_pid_tracker_lookup(struct lttng_pid_tracker *lpf, int pid) +bool lttng_id_tracker_lookup(struct lttng_id_tracker_rcu *p, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + uint32_t hash = hash_32(id, 32); - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; lttng_hlist_for_each_entry_rcu(e, head, hlist) { - if (pid == e->pid) - return 1; /* Found */ + if (id == e->id) + return true; /* Found */ } - return 0; + return false; +} +EXPORT_SYMBOL_GPL(lttng_id_tracker_lookup); + +static struct lttng_id_tracker_rcu *lttng_id_tracker_rcu_create(void) +{ + struct lttng_id_tracker_rcu *tracker; + + tracker = kzalloc(sizeof(struct lttng_id_tracker_rcu), GFP_KERNEL); + if (!tracker) + return NULL; + return tracker; } -EXPORT_SYMBOL_GPL(lttng_pid_tracker_lookup); /* * Tracker add and del operations support concurrent RCU lookups. */ -int lttng_pid_tracker_add(struct lttng_pid_tracker *lpf, int pid) +int lttng_id_tracker_add(struct lttng_id_tracker *lf, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + struct lttng_id_tracker_rcu *p = lf->p; + uint32_t hash = hash_32(id, 32); + bool allocated = false; - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + if (!p) { + p = lttng_id_tracker_rcu_create(); + if (!p) + return -ENOMEM; + allocated = true; + } + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; lttng_hlist_for_each_entry(e, head, hlist) { - if (pid == e->pid) + if (id == e->id) return -EEXIST; } - e = kmalloc(sizeof(struct lttng_pid_hash_node), GFP_KERNEL); + e = kmalloc(sizeof(struct lttng_id_hash_node), GFP_KERNEL); if (!e) return -ENOMEM; - e->pid = pid; + e->id = id; hlist_add_head_rcu(&e->hlist, head); + if (allocated) { + rcu_assign_pointer(lf->p, p); + } return 0; } static -void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e) +void id_tracker_del_node_rcu(struct lttng_id_hash_node *e) { hlist_del_rcu(&e->hlist); /* * We choose to use a heavyweight synchronize on removal here, - * since removal of a PID from the tracker mask is a rare + * since removal of an ID from the tracker mask is a rare * operation, and we don't want to use more cache lines than - * what we really need when doing the PID lookups, so we don't + * what we really need when doing the ID lookups, so we don't * want to afford adding a rcu_head field to those pid hash * node. */ @@ -111,48 +132,74 @@ void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e) * concurrent RCU lookups. */ static -void pid_tracker_del_node(struct lttng_pid_hash_node *e) +void id_tracker_del_node(struct lttng_id_hash_node *e) { hlist_del(&e->hlist); kfree(e); } -int lttng_pid_tracker_del(struct lttng_pid_tracker *lpf, int pid) +int lttng_id_tracker_del(struct lttng_id_tracker *lf, int id) { struct hlist_head *head; - struct lttng_pid_hash_node *e; - uint32_t hash = hash_32(pid, 32); + struct lttng_id_hash_node *e; + struct lttng_id_tracker_rcu *p = lf->p; + uint32_t hash = hash_32(id, 32); - head = &lpf->pid_hash[hash & (LTTNG_PID_TABLE_SIZE - 1)]; + if (!p) + return -ENOENT; + head = &p->id_hash[hash & (LTTNG_ID_TABLE_SIZE - 1)]; /* * No need of _safe iteration, because we stop traversal as soon * as we remove the entry. */ lttng_hlist_for_each_entry(e, head, hlist) { - if (pid == e->pid) { - pid_tracker_del_node_rcu(e); + if (id == e->id) { + id_tracker_del_node_rcu(e); return 0; } } return -ENOENT; /* Not found */ } -struct lttng_pid_tracker *lttng_pid_tracker_create(void) -{ - return kzalloc(sizeof(struct lttng_pid_tracker), GFP_KERNEL); -} - -void lttng_pid_tracker_destroy(struct lttng_pid_tracker *lpf) +static void lttng_id_tracker_rcu_destroy(struct lttng_id_tracker_rcu *p) { int i; - for (i = 0; i < LTTNG_PID_TABLE_SIZE; i++) { - struct hlist_head *head = &lpf->pid_hash[i]; - struct lttng_pid_hash_node *e; + if (!p) + return; + for (i = 0; i < LTTNG_ID_TABLE_SIZE; i++) { + struct hlist_head *head = &p->id_hash[i]; + struct lttng_id_hash_node *e; struct hlist_node *tmp; lttng_hlist_for_each_entry_safe(e, tmp, head, hlist) - pid_tracker_del_node(e); + id_tracker_del_node(e); } - kfree(lpf); + kfree(p); +} + +int lttng_id_tracker_empty_set(struct lttng_id_tracker *lf) +{ + struct lttng_id_tracker_rcu *p, *oldp; + + p = lttng_id_tracker_rcu_create(); + if (!p) + return -ENOMEM; + oldp = lf->p; + rcu_assign_pointer(lf->p, p); + synchronize_trace(); + lttng_id_tracker_rcu_destroy(oldp); + return 0; +} + +void lttng_id_tracker_destroy(struct lttng_id_tracker *lf, bool rcu) +{ + struct lttng_id_tracker_rcu *p = lf->p; + + if (!lf->p) + return; + rcu_assign_pointer(lf->p, NULL); + if (rcu) + synchronize_trace(); + lttng_id_tracker_rcu_destroy(p); } diff --git a/probes/lttng-tracepoint-event-impl.h b/probes/lttng-tracepoint-event-impl.h index 0842dcc0..b615eeab 100644 --- a/probes/lttng-tracepoint-event-impl.h +++ b/probes/lttng-tracepoint-event-impl.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1140,7 +1141,7 @@ static void __event_probe__##_name(void *__data, _proto) \ struct probe_local_vars __tp_locvar; \ struct probe_local_vars *tp_locvar __attribute__((unused)) = \ &__tp_locvar; \ - struct lttng_pid_tracker *__lpf; \ + struct lttng_id_tracker_rcu *__lf; \ \ if (!_TP_SESSION_CHECK(session, __session)) \ return; \ @@ -1150,8 +1151,27 @@ static void __event_probe__##_name(void *__data, _proto) \ return; \ if (unlikely(!READ_ONCE(__event->enabled))) \ return; \ - __lpf = lttng_rcu_dereference(__session->pid_tracker); \ - if (__lpf && likely(!lttng_pid_tracker_lookup(__lpf, current->tgid))) \ + __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \ + return; \ + __lf = lttng_rcu_dereference(__session->uid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(&init_user_ns, current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(current_user_ns(), current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->gid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(&init_user_ns, current_gid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(current_user_ns(), current_gid())))) \ return; \ __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \ __dynamic_len_idx = __orig_dynamic_len_offset; \ @@ -1214,7 +1234,7 @@ static void __event_probe__##_name(void *__data) \ struct probe_local_vars __tp_locvar; \ struct probe_local_vars *tp_locvar __attribute__((unused)) = \ &__tp_locvar; \ - struct lttng_pid_tracker *__lpf; \ + struct lttng_id_tracker_rcu *__lf; \ \ if (!_TP_SESSION_CHECK(session, __session)) \ return; \ @@ -1224,8 +1244,27 @@ static void __event_probe__##_name(void *__data) \ return; \ if (unlikely(!READ_ONCE(__event->enabled))) \ return; \ - __lpf = lttng_rcu_dereference(__session->pid_tracker); \ - if (__lpf && likely(!lttng_pid_tracker_lookup(__lpf, current->pid))) \ + __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vpid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, task_tgid_vnr(current)))) \ + return; \ + __lf = lttng_rcu_dereference(__session->uid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(&init_user_ns, current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vuid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kuid(current_user_ns(), current_uid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->gid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(&init_user_ns, current_gid())))) \ + return; \ + __lf = lttng_rcu_dereference(__session->vgid_tracker.p); \ + if (__lf && likely(!lttng_id_tracker_lookup(__lf, \ + from_kgid(current_user_ns(), current_gid())))) \ return; \ __orig_dynamic_len_offset = this_cpu_ptr(<tng_dynamic_len_stack)->offset; \ __dynamic_len_idx = __orig_dynamic_len_offset; \ -- 2.34.1 From 7f9b8cf773f405a82f81929a8aa73a3c7dc15551 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Fri, 29 Jun 2018 17:28:30 -0400 Subject: [PATCH 15/16] Add extra version information framework Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers --- .gitignore | 2 ++ Makefile.ABI.workarounds | 14 +++++++++ extra-version-git.sh | 20 +++++++++++++ extra-version-name.sh | 13 +++++++++ extra-version-patches.sh | 21 ++++++++++++++ extra_version/README | 2 ++ extra_version/patches/README | 2 ++ lttng-events.c | 55 ++++++++++++++++++++++++++++++++++++ 8 files changed, 129 insertions(+) create mode 100755 extra-version-git.sh create mode 100755 extra-version-name.sh create mode 100755 extra-version-patches.sh create mode 100644 extra_version/README create mode 100644 extra_version/patches/README diff --git a/.gitignore b/.gitignore index f22e828e..38e16841 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,5 @@ GTAGS *.orig *~ \#*# + +/extra_version diff --git a/Makefile.ABI.workarounds b/Makefile.ABI.workarounds index fcd980de..04b223a8 100644 --- a/Makefile.ABI.workarounds +++ b/Makefile.ABI.workarounds @@ -34,6 +34,20 @@ ifneq ($(RT_PATCH_VERSION), 0) ccflags-y += -DRT_PATCH_VERSION=$(RT_PATCH_VERSION) endif +EXTRA_VERSION_NAME:=$(shell $(TOP_LTTNG_MODULES_DIR)/extra-version-name.sh $(TOP_LTTNG_MODULES_DIR)) + +ifneq ($(EXTRA_VERSION_NAME), 0) + ccflags-y += -DLTTNG_EXTRA_VERSION_NAME='"$(EXTRA_VERSION_NAME)"' +endif + +EXTRA_VERSION_GIT:=$(shell $(TOP_LTTNG_MODULES_DIR)/extra-version-git.sh $(TOP_LTTNG_MODULES_DIR)) + +ifneq ($(EXTRA_VERSION_GIT), 0) + ccflags-y += -DLTTNG_EXTRA_VERSION_GIT='"$(EXTRA_VERSION_GIT)"' +endif + +EXTRA_VERSION_PATCHES:=$(shell $(TOP_LTTNG_MODULES_DIR)/extra-version-patches.sh $(TOP_LTTNG_MODULES_DIR)) + # Starting with kernel 4.12, the ftrace header was moved to private headers # and as such is not available when building against distro headers instead # of the full kernel sources. In the situation, define LTTNG_FTRACE_MISSING_HEADER diff --git a/extra-version-git.sh b/extra-version-git.sh new file mode 100755 index 00000000..e5a3e176 --- /dev/null +++ b/extra-version-git.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: (GPL-2.0 OR LGPL-2.1) + +# First argument is the path to the lttng modules sources. +TOP_LTTNG_MODULES_DIR="$1" + +GIT_VERSION="0" + +if test -x "$(which git 2>&1;true)" && test -r "${TOP_LTTNG_MODULES_DIR}/.git"; then + GIT_VERSION_STR="$(cd "${TOP_LTTNG_MODULES_DIR}" && git describe --tags --dirty)" + GIT_CURRENT_TAG="$(cd "${TOP_LTTNG_MODULES_DIR}" && git describe --tags --exact-match --match="v[0-9]*" HEAD 2> /dev/null)" + + GIT_VERSION="${GIT_VERSION_STR}" + + if ! echo "${GIT_VERSION_STR}" | grep -- "-dirty" >/dev/null && test "x$GIT_CURRENT_TAG" != "x"; then + GIT_VERSION="0" + fi +fi + +echo "${GIT_VERSION}" diff --git a/extra-version-name.sh b/extra-version-name.sh new file mode 100755 index 00000000..f7042567 --- /dev/null +++ b/extra-version-name.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# SPDX-License-Identifier: (GPL-2.0 OR LGPL-2.1) + +# First argument is the path to the lttng modules sources. +TOP_LTTNG_MODULES_DIR="$1" + +EXTRA_VERSION_NAME="$(sed -n '1p' "${TOP_LTTNG_MODULES_DIR}/extra_version/name" 2> /dev/null)" + +if [ "x${EXTRA_VERSION_NAME}" != "x" ]; then + echo "${EXTRA_VERSION_NAME}" +else + echo "0" +fi diff --git a/extra-version-patches.sh b/extra-version-patches.sh new file mode 100755 index 00000000..4e8a1b52 --- /dev/null +++ b/extra-version-patches.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# SPDX-License-Identifier: (GPL-2.0 OR LGPL-2.1) + +# First argument is the path to the lttng modules sources. +TOP_LTTNG_MODULES_DIR="$1" + +if ! test -d "${TOP_LTTNG_MODULES_DIR}"; then + exit 1 +fi + +TMPFILE="$(mktemp)" + +find "${TOP_LTTNG_MODULES_DIR}/extra_version/patches/" -maxdepth 1 ! -name 'README' -type f -printf '%f\n' | sort -r \ + | sed -E 's/[^a-zA-Z0-9 \.]/-/g ; s/(.*)/MODULE_INFO(extra_version_patch, "\1");/g' >"${TMPFILE}" 2>/dev/null + +if test ! -f "${TOP_LTTNG_MODULES_DIR}/extra_version/patches.i" || \ + test x"$(cat "${TMPFILE}")" != x"$(cat "${TOP_LTTNG_MODULES_DIR}/extra_version/patches.i")"; then + mv "${TMPFILE}" "${TOP_LTTNG_MODULES_DIR}/extra_version/patches.i" +fi + +rm -f "${TMPFILE}" diff --git a/extra_version/README b/extra_version/README new file mode 100644 index 00000000..5eef496d --- /dev/null +++ b/extra_version/README @@ -0,0 +1,2 @@ +The first line of the "name" file is used to populate the "extra_version_name" +modinfo key of each built module. diff --git a/extra_version/patches/README b/extra_version/patches/README new file mode 100644 index 00000000..22ea3d37 --- /dev/null +++ b/extra_version/patches/README @@ -0,0 +1,2 @@ +The name of each file in this directory except this README will be used to +populate a "extra_version_path" modinfo key for each built module. diff --git a/lttng-events.c b/lttng-events.c index ea2c5841..d767c7f7 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -2842,6 +2842,22 @@ static int __init lttng_events_init(void) ret = lttng_init_cpu_hotplug(); if (ret) goto error_hotplug; + printk(KERN_NOTICE "LTTng: Loaded modules v%s.%s.%s%s (%s)%s%s\n", + __stringify(LTTNG_MODULES_MAJOR_VERSION), + __stringify(LTTNG_MODULES_MINOR_VERSION), + __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION), + LTTNG_MODULES_EXTRAVERSION, + LTTNG_VERSION_NAME, +#ifdef LTTNG_EXTRA_VERSION_GIT + LTTNG_EXTRA_VERSION_GIT[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_GIT, +#else + "", +#endif +#ifdef LTTNG_EXTRA_VERSION_NAME + LTTNG_EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_NAME); +#else + ""); +#endif return 0; error_hotplug: @@ -2854,6 +2870,22 @@ error_kmem: lttng_tracepoint_exit(); error_tp: lttng_context_exit(); + printk(KERN_NOTICE "LTTng: Failed to load modules v%s.%s.%s%s (%s)%s%s\n", + __stringify(LTTNG_MODULES_MAJOR_VERSION), + __stringify(LTTNG_MODULES_MINOR_VERSION), + __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION), + LTTNG_MODULES_EXTRAVERSION, + LTTNG_VERSION_NAME, +#ifdef LTTNG_EXTRA_VERSION_GIT + LTTNG_EXTRA_VERSION_GIT[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_GIT, +#else + "", +#endif +#ifdef LTTNG_EXTRA_VERSION_NAME + LTTNG_EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_NAME); +#else + ""); +#endif return ret; } @@ -2871,10 +2903,33 @@ static void __exit lttng_events_exit(void) kmem_cache_destroy(event_cache); lttng_tracepoint_exit(); lttng_context_exit(); + printk(KERN_NOTICE "LTTng: Unloaded modules v%s.%s.%s%s (%s)%s%s\n", + __stringify(LTTNG_MODULES_MAJOR_VERSION), + __stringify(LTTNG_MODULES_MINOR_VERSION), + __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION), + LTTNG_MODULES_EXTRAVERSION, + LTTNG_VERSION_NAME, +#ifdef LTTNG_EXTRA_VERSION_GIT + LTTNG_EXTRA_VERSION_GIT[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_GIT, +#else + "", +#endif +#ifdef LTTNG_EXTRA_VERSION_NAME + LTTNG_EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " LTTNG_EXTRA_VERSION_NAME); +#else + ""); +#endif } module_exit(lttng_events_exit); +#include "extra_version/patches.i" +#ifdef LTTNG_EXTRA_VERSION_GIT +MODULE_INFO(extra_version_git, LTTNG_EXTRA_VERSION_GIT); +#endif +#ifdef LTTNG_EXTRA_VERSION_NAME +MODULE_INFO(extra_version_name, LTTNG_EXTRA_VERSION_NAME); +#endif MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Mathieu Desnoyers "); MODULE_DESCRIPTION("LTTng Events"); -- 2.34.1 From f369ff5f8d0c501ef8d003bf26e033c525c75bf3 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Mon, 9 Jul 2018 14:36:31 -0400 Subject: [PATCH 16/16] Backport revision 1 Signed-off-by: Jonathan Rajotte --- extra_version/name | 1 + 1 file changed, 1 insertion(+) create mode 100644 extra_version/name diff --git a/extra_version/name b/extra_version/name new file mode 100644 index 00000000..b595f337 --- /dev/null +++ b/extra_version/name @@ -0,0 +1 @@ +EfficiOS - Backport - Revision 1 -- 2.34.1