Re: [lttng-dev] [PATCH lttng-tools] Copyright ownership transfer
On 2022-01-14 3:48 p.m., Jérémie Galarneau wrote: Apply copyright ownership transfer from David Goulet, Julien Desfossez, and Simon Marchi to EfficiOS Inc. Link: https://lists.lttng.org/pipermail/lttng-dev/2022-January/030087.html Link: https://lists.lttng.org/pipermail/lttng-dev/2022-January/030092.html Signed-off-by: Jérémie Galarneau Cc: David Goulet Cc: Julien Desfossez Cc: Simon Marchi Change-Id: Id13575afd4a2a09bb91a8d2b7a12dc3db8dc329f --- extras/lttng-bash_completion | 2 +- include/lttng/lttng.h | 2 +- src/bin/lttng-consumerd/lttng-consumerd.cpp| 2 +- src/bin/lttng-consumerd/lttng-consumerd.h | 4 ++-- src/bin/lttng-crash/lttng-crash.cpp| 2 +- src/bin/lttng-sessiond/channel.cpp | 2 +- src/bin/lttng-sessiond/channel.h | 2 +- src/bin/lttng-sessiond/client.cpp | 2 +- src/bin/lttng-sessiond/client.h| 2 +- src/bin/lttng-sessiond/context.cpp | 2 +- src/bin/lttng-sessiond/context.h | 2 +- src/bin/lttng-sessiond/dispatch.cpp| 2 +- src/bin/lttng-sessiond/dispatch.h | 2 +- src/bin/lttng-sessiond/event.cpp | 2 +- src/bin/lttng-sessiond/event.h | 2 +- src/bin/lttng-sessiond/globals.cpp | 2 +- src/bin/lttng-sessiond/kernel.cpp | 2 +- src/bin/lttng-sessiond/kernel.h| 2 +- src/bin/lttng-sessiond/lttng-sessiond.h| 2 +- src/bin/lttng-sessiond/main.cpp| 2 +- src/bin/lttng-sessiond/manage-apps.cpp | 2 +- src/bin/lttng-sessiond/manage-apps.h | 2 +- src/bin/lttng-sessiond/manage-consumer.cpp | 2 +- src/bin/lttng-sessiond/manage-consumer.h | 2 +- src/bin/lttng-sessiond/manage-kernel.cpp | 2 +- src/bin/lttng-sessiond/manage-kernel.h | 2 +- src/bin/lttng-sessiond/process-utils.cpp | 2 +- src/bin/lttng-sessiond/register.cpp| 2 +- src/bin/lttng-sessiond/register.h | 2 +- src/bin/lttng-sessiond/session.cpp | 2 +- src/bin/lttng-sessiond/session.h | 2 +- src/bin/lttng-sessiond/thread-utils.cpp| 2 +- src/bin/lttng-sessiond/trace-kernel.cpp| 2 +- src/bin/lttng-sessiond/trace-kernel.h | 2 +- src/bin/lttng-sessiond/trace-ust.cpp | 2 +- src/bin/lttng-sessiond/trace-ust.h | 2 +- src/bin/lttng-sessiond/ust-app.cpp | 2 +- src/bin/lttng-sessiond/ust-app.h | 2 +- src/bin/lttng-sessiond/ust-consumer.cpp| 2 +- src/bin/lttng-sessiond/ust-consumer.h | 2 +- src/bin/lttng-sessiond/ust-ctl-internal.h | 2 +- src/bin/lttng-sessiond/ust-error-internal.h| 3 +-- src/bin/lttng-sessiond/utils.cpp | 2 +- src/bin/lttng-sessiond/utils.h | 2 +- src/bin/lttng/command.h| 2 +- src/bin/lttng/commands/add_context.cpp | 2 +- src/bin/lttng/commands/create.cpp | 2 +- src/bin/lttng/commands/destroy.cpp | 2 +- src/bin/lttng/commands/disable_channels.cpp| 2 +- src/bin/lttng/commands/disable_events.cpp | 2 +- src/bin/lttng/commands/enable_channels.cpp | 2 +- src/bin/lttng/commands/enable_events.cpp | 2 +- src/bin/lttng/commands/list.cpp| 2 +- src/bin/lttng/commands/set_session.cpp | 2 +- src/bin/lttng/commands/start.cpp | 2 +- src/bin/lttng/commands/stop.cpp| 2 +- src/bin/lttng/commands/track-untrack.cpp | 2 +- src/bin/lttng/commands/version.cpp | 2 +- src/bin/lttng/conf.cpp | 2 +- src/bin/lttng/conf.h | 2 +- src/bin/lttng/lttng.cpp| 2 +- src/bin/lttng/utils.cpp| 2 +- src/bin/lttng/utils.h | 2 +- src/common/common.h| 2 +- src/common/compat/poll.cpp | 2 +- src/common/compat/poll.h | 2 +- src/common/consumer/consumer-stream.cpp| 2 +- src/common/consumer/consumer-timer.h | 2 +- src/common/consumer/consumer.cpp | 2 +- src/common/consumer/consumer.h | 2 +- src/common/defaults.cpp| 2 +- src/common/defaults.h | 2 +- src/common/error.h | 2 +- src/common/futex.cpp | 2 +- src/common/futex.h | 2 +- src/common/hashtable/hashtable.cpp | 2 +- src/common/hashtable/hashtable.h | 2 +- src/common/hashtable/utils.cpp | 2 +- src/common/hashtable/utils.h | 2 +- src/common/kernel-consumer/kernel-consumer.cpp | 2 +- src/common/kernel-consumer/kernel-consumer.h | 2
Re: [lttng-dev] [PATCH lttng-ust] Copyright ownership transfer
On 2022-01-14 3:14 p.m., Mathieu Desnoyers wrote: Apply copyright ownership transfer from David Goulet and Julien Desfossez to EfficiOS Inc. Link: https://lists.lttng.org/pipermail/lttng-dev/2022-January/030087.html Link: https://lists.lttng.org/pipermail/lttng-dev/2022-January/030092.html Signed-off-by: Mathieu Desnoyers Cc: David Goulet Cc: Julien Desfossez Change-Id: Ibc6bb52296406e68466d44ae991a7ab70134dd76 --- include/lttng/ust-ctl.h| 2 +- include/lttng/ust-error.h | 3 +-- src/common/ustcomm.c | 2 +- src/common/ustcomm.h | 3 +-- src/common/utils.c | 2 +- src/lib/lttng-ust-ctl/ustctl.c | 2 +- src/lib/lttng-ust/lttng-ust-comm.c | 2 +- src/lib/lttng-ust/strerror.c | 2 +- 8 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/lttng/ust-ctl.h b/include/lttng/ust-ctl.h index 360bb09a..25e588b3 100644 --- a/include/lttng/ust-ctl.h +++ b/include/lttng/ust-ctl.h @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: GPL-2.0-only * - * Copyright (C) 2011 Julien Desfossez + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011-2013 Mathieu Desnoyers */ diff --git a/include/lttng/ust-error.h b/include/lttng/ust-error.h index 543c894a..49045bab 100644 --- a/include/lttng/ust-error.h +++ b/include/lttng/ust-error.h @@ -1,8 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet - * Copyright (C) 2011 Julien Desfossez + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011 Mathieu Desnoyers */ diff --git a/src/common/ustcomm.c b/src/common/ustcomm.c index 6dfec5ea..252ed4f2 100644 --- a/src/common/ustcomm.c +++ b/src/common/ustcomm.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011-2013 Mathieu Desnoyers */ diff --git a/src/common/ustcomm.h b/src/common/ustcomm.h index 734757c3..d1e9af13 100644 --- a/src/common/ustcomm.h +++ b/src/common/ustcomm.h @@ -1,8 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet - * Copyright (C) 2011 Julien Desfossez + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011 Mathieu Desnoyers */ diff --git a/src/common/utils.c b/src/common/utils.c index 108f76db..0c95b06c 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011 Mathieu Desnoyers */ diff --git a/src/lib/lttng-ust-ctl/ustctl.c b/src/lib/lttng-ust-ctl/ustctl.c index 8c60bdb2..94d84843 100644 --- a/src/lib/lttng-ust-ctl/ustctl.c +++ b/src/lib/lttng-ust-ctl/ustctl.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: GPL-2.0-only * - * Copyright (C) 2011 Julien Desfossez + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011-2013 Mathieu Desnoyers */ diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index d6755079..caba7452 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011 Mathieu Desnoyers */ diff --git a/src/lib/lttng-ust/strerror.c b/src/lib/lttng-ust/strerror.c index 1fa7fc3a..5a671a07 100644 --- a/src/lib/lttng-ust/strerror.c +++ b/src/lib/lttng-ust/strerror.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: LGPL-2.1-only * - * Copyright (C) 2011 David Goulet + * Copyright (C) 2011 EfficiOS Inc. * Copyright (C) 2011-2013 Mathieu Desnoyers */ Signed-off-by: Julien Desfossez ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-modules] Copyright ownership transfer
On 2022-01-14 3:13 p.m., Mathieu Desnoyers wrote: Apply copyright ownership transfer from Julien Desfossez to EfficiOS Inc. Link: https://lists.lttng.org/pipermail/lttng-dev/2022-January/030092.html Signed-off-by: Mathieu Desnoyers Cc: Julien Desfossez Change-Id: Ida168b1fbe6589cb371a549ef14d9b4b28b221b3 --- .../lttng-syscalls-extractor/lttng-syscalls-extractor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c b/include/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c index 0f683750..8670d25f 100644 --- a/include/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c +++ b/include/instrumentation/syscalls/lttng-syscalls-extractor/lttng-syscalls-extractor.c @@ -5,7 +5,7 @@ * Dump syscall metadata to console. * * Copyright 2011 Mathieu Desnoyers - * Copyright 2011 Julien Desfossez + * Copyright 2011 EfficiOS Inc. */ #include Signed-off-by: Julien Desfossez ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Transfer of LTTng copyright ownership: Julien Desfossez
On 2022-01-14 2:49 p.m., Mathieu Desnoyers wrote: Hi Julien, In order to facilitate maintenance of the LTTng project, would you agree to transfer your copyright ownership for code authored outside of your employment at EfficiOS to EfficiOS Inc. ? This particularly affects the lttng-tools, lttng-ust and lttng-modules files with copyright: Copyright (C) 201N Julien Desfossez Yes, no problem ! Thanks for all your contributions to LTTng ! Mathieu Thanks ! Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Lacking instrumentation for threaded IRQs
[...] >>> For 2- >>> >>> * Instrument the kernel: Add tracepoints to the beginning and end of the >>> irq_thread_fn function. Those events would indicate the context of a >>> threaded IRQ so all events inside can be considered the results of an IRQ. >>> >>> * Instrument LTTng: Add a field to the lttng_statedump_interrupt >>> tracepoint to add the thread handling this IRQ if available. That would >>> give this thread a special state: instead of running, whatever happens >>> there would be considered as the result of an IRQ. But only LTTng traces >>> would benefit from this tracepoint, and only if there's a statedump (so >>> not snapshot). It's sad... But would make a quick win for now. >>> >>> >>> Here's a pad showing those possible options: >>> https://hebdo.framapad.org/p/threadedirqlttnglinux8gjkh51yhfha [...] >> For #2, I am not exactly sure why we need special events for those >> kernel threads, with the fix for #1, we know they are interrupt-related >> threads, but they are not interrupts in the sense of "doing work while >> the current task is interrupted". To me, everything this thread does is >> related to the previous source of wakeup and I would imagine every chunk >> of work it does is between an irq_thread_fn_entry/return block. >> I am not against adding this information (or the statedump approach if >> we are sure there is a 1 to 1 mapping), but I would like to understand >> more precisely what this information would add to our understanding of >> the trace. >> > We need to know that those threads are really interrupt thread for the > dependency analysis. Look at the following sequence of events: > > [12:02:17.779984311] (+0.02224) dorsallaptop *sched_waking*: { > cpu_id = 3 }, { comm = "irq/130-iwlwifi", tid = *639*, prio = -51, > target_cpu = 3 } > [12:02:17.779985668] (+0.00565) dorsallaptop *do_IRQ_return*: { > cpu_id = 3 }, { ip = 0x89A01C30, parent_ip = 0x89A0098F } > [12:02:17.779986575] (+0.00907) dorsallaptop *sched_switch*: { > cpu_id = 3 }, { prev_comm = "swapper/3", prev_tid = 0, prev_prio = 20, > prev_state = 0, next_comm = "irq/130-iwlwifi", next_tid = *639*, > next_prio = -51 } > [12:02:17.779998608] (+0.11174) dorsallaptop net_if_receive_skb: { > cpu_id = 3 }, { ... } > [12:02:17.780019468] (+0.20860) dorsallaptop sched_waking: { cpu_id > = 3 }, { comm = "wget", tid = 2430, prio = 20, target_cpu = 0 } > > If we do the critical path of the wget process, with the irq/130-iwlwifi > thread considered a normal thread, we see it is woken up by an hardware > interrupt, that we know if iwlwifi, but we don't know anything else > about it, so the critical path ends up following the swapper process... > Now if we consider the irq/130-iwlwifi thread as an interrupt-running > process, we see that wget is actually woken up by the net_if_receive_skb > event and we can follow this to the packet sent by another machine. > Of course this can all be done at analysis time: if (ret = 2 and a > wakeup inside the do_IRQ but outside the irq_handler) { assume the woken > thread will be handling the interrupt } But it's the "assume" part that > I don't like. With instrumentation, we can clarify this. In this example, assuming we have the do_IRQ event, the critical path seems clear to me: - irq wakes up task 639 - task 639 runs, receives a packet and wakes up another task So wget has been woken up by a thread that was itself woken up by an interrupt, I don't see how swapper could end up in this chain if we have the do_IRQ event. I think the distinction with your explanation is that I see the receive_skb as context around the wake up, but the source of wake up (the transition in the dependency graph) is the wakeup occurring while process 639 running, and that trace backs to the IRQ. Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Lacking instrumentation for threaded IRQs
On 10/01/2018 01:25 PM, Geneviève Bastien wrote: > Hi, > > > I was writing a tutorial on distributed critical path in Trace Compass. > I was tracing a client (my laptop on wifi) and a server. And to my > surprise, it didn't work! After further investigation, here's the issue: > > > The critical path assumes that a network packet is received in a softirq > that wakes up the process to whom the packet is meant. This is right for > ethernet network, but not wifi. Wifi packets are handled by a threaded > IRQ. Here's the flow: > > > 1- There's an irq that is handled with a return value of 2 (IRQ_WAKE_THREAD) > > 2- The 2 means to wake up a process _after_ the irq_handler_exit > tracepoint is hit > > 3- The IRQ thread is woken up, scheduled in and is running > > 4- The packet is received during that time > > 5- The packet reception is hence not on the critical path! > > > The issue we have here with the critical path for network will also be > an issue for all threaded irqs and there is some additional > instrumentation needed to be able to automatically take those into > account in analyses. > > There's additional instrumentation needed > > 1- To associate the wakeup of the IRQ thread to the actual IRQ. The way > it is now, the wakeup happens in the context of whatever else was > running before the IRQ handler. > > 2- To make it obvious that the IRQ thread is really an IRQ thread, so > whatever is running there should be considered in the context of a > threaded IRQ and not a simple running process. > > > Here are some options for each, not mutually exclusive: > > For 1- > > * Instrument the kernel: Add tracepoints to the beginning and end of > do_IRQ, to show the full IRQ duration, not just the handler and all > events happening during that time can be associated with the IRQ. > > * Instrument the kernel: Add tracepoints before and after waking > processes if the return value of the handler is IRQ_WAKE_THREAD. Those > tracepoints would be hit only if a process needs to be woken and would > not add overhead otherwise > > * At analysis time: Look at the return value of irq_handler_exit and if > 2, wait for the next waking on that CPU and associate it with the last > IRQ. But could there be more than one process to wakeup? Looking at the > kernel code, it seems that not. But this is more error-prone. > > > For 2- > > * Instrument the kernel: Add tracepoints to the beginning and end of the > irq_thread_fn function. Those events would indicate the context of a > threaded IRQ so all events inside can be considered the results of an IRQ. > > * Instrument LTTng: Add a field to the lttng_statedump_interrupt > tracepoint to add the thread handling this IRQ if available. That would > give this thread a special state: instead of running, whatever happens > there would be considered as the result of an IRQ. But only LTTng traces > would benefit from this tracepoint, and only if there's a statedump (so > not snapshot). It's sad... But would make a quick win for now. > > > Here's a pad showing those possible options: > https://hebdo.framapad.org/p/threadedirqlttnglinux8gjkh51yhfha > > What do you think? I'm mostly interested to know if there's a case to > add instrumentation to the kernel and where. For #1, I think adding the do_IRQ begin/end instrumentation, would be very valuable, we did it with a kretprobe in the latency-tracker, but I think this deserves a real tracepoint. In your example trace, we can see with the do_IRQ event that the whole interruption lasted 5.2 micro-seconds, whereas the interrupt handler only lasted 482ns, so without this event we are clearly missing long periods of interruption. Using the "ret = 2" would work as a temporary fix, but there are some corner cases where it could lead us into wrong assumptions (the process to be woken up is exiting somehow and the interrupt arrived during a syscall that needed to wake another process), so I think the real fix is the do_IRQ instrumentation. For #2, I am not exactly sure why we need special events for those kernel threads, with the fix for #1, we know they are interrupt-related threads, but they are not interrupts in the sense of "doing work while the current task is interrupted". To me, everything this thread does is related to the previous source of wakeup and I would imagine every chunk of work it does is between an irq_thread_fn_entry/return block. I am not against adding this information (or the statedump approach if we are sure there is a 1 to 1 mapping), but I would like to understand more precisely what this information would add to our understanding of the trace. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [RFC PATCH lttng-modules v2 1/2] 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 <jdesfos...@efficios.com> --- 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 2cd2df0..b08f0bf 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 d202b72..ea746c2 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -56,6 +56,7 @@ #include #include #include +#include #include /* @@ -1771,6 +1772,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, _fops, NULL); @@ -1783,6 +1790,7 @@ int __init lttng_abi_init(void) return 0; error: + lttng_tp_mempool_destroy(); lttng_clock_unref(); return ret; } @@ -1790,6 +1798,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 000..d984bd4 --- /dev/null +++ b/lttng-tp-mempool.c @@ -0,0 +1,172 @@ +/* + * lttng-tp-mempool.c + * + * Copyright (C) 2018 Julien Desfossez <jdesfos...@efficios.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#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(_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)
[lttng-dev] [RFC PATCH lttng-modules 2/2] 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 <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 33 +- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index 184f3a9..01576d9 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 = 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 = 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 = 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); + tp_mempool_free(tp_locvar->fds_in); \ + tp_mempool_free(tp_locvar->fds_out);\ + 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 = tp_mempool_allo
[lttng-dev] [RFC PATCH lttng-modules 1/2] 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 if the GFP_ATOMIC and GFP_NOWAIT flags are set. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- Makefile | 3 +- lttng-abi.c | 9 ++ probes/lttng-tracepoint-event-impl.h | 1 + tp-mempool.c | 175 +++ tp-mempool.h | 48 ++ 5 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 tp-mempool.c create mode 100644 tp-mempool.h diff --git a/Makefile b/Makefile index 2cd2df0..78f6661 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 \ + 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 d202b72..9c29612 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -56,6 +56,7 @@ #include #include #include +#include #include /* @@ -1771,6 +1772,12 @@ int __init lttng_abi_init(void) wrapper_vmalloc_sync_all(); lttng_clock_ref(); + + ret = tp_mempool_init(); + if (ret) { + goto error; + } + lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL, _fops, NULL); @@ -1784,6 +1791,7 @@ int __init lttng_abi_init(void) error: lttng_clock_unref(); + tp_mempool_destroy(); return ret; } @@ -1793,4 +1801,5 @@ void lttng_abi_exit(void) lttng_clock_unref(); if (lttng_proc_dentry) remove_proc_entry("lttng", NULL); + tp_mempool_destroy(); } diff --git a/probes/lttng-tracepoint-event-impl.h b/probes/lttng-tracepoint-event-impl.h index 61f1c2d..2a8fe58 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)" diff --git a/tp-mempool.c b/tp-mempool.c new file mode 100644 index 000..38df26f --- /dev/null +++ b/tp-mempool.c @@ -0,0 +1,175 @@ +/* + * tp-mempool.c + * + * Copyright (C) 2018 Julien Desfossez <jdesfos...@efficios.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include + +#define BUF_SIZE 4 * 1024 +#define NR_BUF_PER_CPU 4 + +struct tp_buf_entry { + int cpu; /* To make sure we return the entry to the right pool. */ + char buf[BUF_SIZE]; + struct list_head list; +}; + +struct per_cpu_buf { + struct list_head free_list; /* Free struct tp_buf_entry. */ + struct list_head allocated_list; /* Allocated struct tp_buf_entry. */ +}; + +static struct per_cpu_buf __percpu *pool = NULL; /* Per-cpu buffer. */ + +int 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) { + int i; + struct per_cpu_buf *cpu_buf = per_cpu_ptr(pool, cpu); + + INIT_LIST_HEAD(_buf->free_list); + INIT_LIST_HEAD(_buf->allocated_list); + + for (i = 0; i < NR_BUF_PER_CPU; i++) { + struct tp_buf_entry *entry; + + entry = kzalloc(sizeof(struct tp_buf_entry),
[lttng-dev] [PATCH lttng-tools v2] Fix: error out on leftover arguments
All the commands currently ignore leftover arguments, this can lead to wrong usage of the commands and waste of time debugging. For example, this command enables the vpid context on all channels instead of only on the "mychan" channel: $ lttng add-context -u mychan -t vpid The correct usage is: $ lttng add-context -u -c mychan -t vpid We now output an error on leftover arguments: $ lttng add-context -u mychan -t vpid Error: Unknown argument: mychan Error: Command error Some commands accept one leftover argument (create, start, stop, destroy), so we check if there are other leftovers: $ lttng create mysess allo Error: Unknown argument: allo Error: Command error Only the snapshot command is not handled since it has a second level of command and does not consume the popt arguments. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng/commands/add_context.c | 8 src/bin/lttng/commands/create.c | 8 src/bin/lttng/commands/destroy.c | 9 + src/bin/lttng/commands/disable_channels.c | 8 src/bin/lttng/commands/disable_events.c | 8 src/bin/lttng/commands/enable_channels.c | 9 + src/bin/lttng/commands/enable_events.c| 8 src/bin/lttng/commands/list.c | 9 - src/bin/lttng/commands/load.c | 8 src/bin/lttng/commands/save.c | 9 - src/bin/lttng/commands/start.c| 8 src/bin/lttng/commands/stop.c | 8 src/bin/lttng/commands/view.c | 8 13 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/bin/lttng/commands/add_context.c b/src/bin/lttng/commands/add_context.c index 209a9f4..d9121b0 100644 --- a/src/bin/lttng/commands/add_context.c +++ b/src/bin/lttng/commands/add_context.c @@ -898,6 +898,7 @@ int cmd_add_context(int argc, const char **argv) static poptContext pc; struct ctx_type *type, *tmptype; char *session_name = NULL; + const char *leftover = NULL; if (argc < 2) { ret = CMD_ERROR; @@ -944,6 +945,13 @@ int cmd_add_context(int argc, const char **argv) } } + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + goto end; + } + ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace + opt_jul + opt_log4j); if (ret) { diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index d075f64..faf9f3e 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -625,6 +625,7 @@ int cmd_create(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; char *opt_arg = NULL; + const char *leftover = NULL; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -719,6 +720,13 @@ int cmd_create(int argc, const char **argv) } opt_session_name = (char*) poptGetArg(pc); + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + goto end; + } + command_ret = create_session(); if (command_ret) { success = 0; diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index 02c7139..6878aaa 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -174,6 +174,7 @@ int cmd_destroy(int argc, const char **argv) int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; + const char *leftover = NULL; struct lttng_session *sessions; int count; @@ -280,6 +281,14 @@ int cmd_destroy(int argc, const char **argv) } } + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + success = 0; + goto mi_closing; + } + mi_closing: /* Mi closing */ if (lttng_opt_mi) { diff --git a/src/bin/lttng/commands/disable_channels.c b/src/bin/lttng/commands/disable_channels.c index 775ff89..936884e 100644 --- a/src/bin/lttng/commands/disable_channels.c +++ b/src/bin/lttng/commands/disable_channels.c @@ -216,6 +216,7 @@ int cmd_disable_channels(int argc, const char **argv) int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; + const char *leftover = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -250,6 +251,13 @@ int
[lttng-dev] [PATCH lttng-tools 1/2] Fix: error handling on relay version check
If we have a network error while performing the version check between the session daemon and the relay, we should not report to the user that there is a version mismatch. We now return LTTNG_ERR_RELAYD_VERSION_FAIL on relayd_version_check() when the daemons are not compatible and the negative value from sendmsg/recvmsg on network errors. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng-sessiond/cmd.c | 7 +-- src/common/relayd/relayd.c | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 1edcffe..0317d52 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -877,8 +877,11 @@ static int create_connect_relayd(struct lttng_uri *uri, /* Check relayd version */ ret = relayd_version_check(rsock); - if (ret < 0) { - ret = LTTNG_ERR_RELAYD_VERSION_FAIL; + if (ret == LTTNG_ERR_RELAYD_VERSION_FAIL) { + goto close_sock; + } else if (ret < 0) { + ERR("Unable to reach lttng-relayd"); + ret = LTTNG_ERR_RELAYD_CONNECT_FAIL; goto close_sock; } consumer->relay_major_version = rsock->major; diff --git a/src/common/relayd/relayd.c b/src/common/relayd/relayd.c index 2adcbe4..4cb1c1f 100644 --- a/src/common/relayd/relayd.c +++ b/src/common/relayd/relayd.c @@ -378,7 +378,8 @@ end: * If major versions are compatible, we assign minor_to_use to the * minor version of the procotol we are going to use for this session. * - * Return 0 if compatible else negative value. + * Return 0 if the two daemons are compatible, LTTNG_ERR_RELAYD_VERSION_FAIL + * otherwise, or a negative value on network errors. */ int relayd_version_check(struct lttcomm_relayd_sock *rsock) { @@ -420,7 +421,7 @@ int relayd_version_check(struct lttcomm_relayd_sock *rsock) */ if (msg.major != rsock->major) { /* Not compatible */ - ret = -1; + ret = LTTNG_ERR_RELAYD_VERSION_FAIL; DBG2("Relayd version is NOT compatible. Relayd version %u != %u (us)", msg.major, rsock->major); goto error; -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools 2/2] Fix: reply to version check even on protocol mismatch
In the relay, we currently put the connection when we detect the major version from the session daemon is not compatible. We don't reply to the version check message. The relay still holds a reference on the connection so it is not closed and the session daemon is left blocking in recvmsg. The relay now replies to the version check so the session daemon knows it is not compatible, and the relay completely closes the connection on its side and removes the FD from the poll set. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng-relayd/main.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 61f206f..cd4f058 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -1601,6 +1601,7 @@ static int relay_send_version(struct lttcomm_relayd_hdr *recv_hdr, { int ret; struct lttcomm_relayd_version reply, msg; + bool compatible = true; conn->version_check_done = 1; @@ -1625,9 +1626,7 @@ static int relay_send_version(struct lttcomm_relayd_hdr *recv_hdr, if (reply.major != be32toh(msg.major)) { DBG("Incompatible major versions (%u vs %u), deleting session", reply.major, be32toh(msg.major)); - connection_put(conn); - ret = 0; - goto end; + compatible = false; } conn->major = reply.major; @@ -1646,6 +1645,11 @@ static int relay_send_version(struct lttcomm_relayd_hdr *recv_hdr, ERR("Relay sending version"); } + if (!compatible) { + ret = -1; + goto end; + } + DBG("Version check done using protocol %u.%u", conn->major, conn->minor); -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: error out on leftover arguments
All the commands currently ignore leftover arguments, this can lead to wrong usage of the commands and waste of time debugging. For example, this command enables the vpid context on all channels instead of only on the "mychan" channel: $ lttng add-context -u mychan -t vpid The correct usage is: $ lttng add-context -u -c mychan -t vpid We now output an error on leftover arguments: $ lttng add-context -u bbb -t vpid Error: Unknown argument: bbb Error: Command error Some commands accept one leftover argument (create, start, stop, destroy), so we check if there are other leftovers: $ lttng create mysess allo Error: Unknown argument: allo Error: Command error Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng/commands/add_context.c | 8 src/bin/lttng/commands/create.c | 8 src/bin/lttng/commands/destroy.c | 9 + src/bin/lttng/commands/disable_channels.c | 8 src/bin/lttng/commands/disable_events.c | 8 src/bin/lttng/commands/enable_channels.c | 9 + src/bin/lttng/commands/enable_events.c| 8 src/bin/lttng/commands/list.c | 9 - src/bin/lttng/commands/load.c | 8 src/bin/lttng/commands/save.c | 9 - src/bin/lttng/commands/snapshot.c | 8 src/bin/lttng/commands/start.c| 8 src/bin/lttng/commands/stop.c | 8 src/bin/lttng/commands/view.c | 8 14 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/bin/lttng/commands/add_context.c b/src/bin/lttng/commands/add_context.c index 209a9f4..d9121b0 100644 --- a/src/bin/lttng/commands/add_context.c +++ b/src/bin/lttng/commands/add_context.c @@ -898,6 +898,7 @@ int cmd_add_context(int argc, const char **argv) static poptContext pc; struct ctx_type *type, *tmptype; char *session_name = NULL; + const char *leftover = NULL; if (argc < 2) { ret = CMD_ERROR; @@ -944,6 +945,13 @@ int cmd_add_context(int argc, const char **argv) } } + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + goto end; + } + ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace + opt_jul + opt_log4j); if (ret) { diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index d075f64..faf9f3e 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -625,6 +625,7 @@ int cmd_create(int argc, const char **argv) { int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; char *opt_arg = NULL; + const char *leftover = NULL; static poptContext pc; pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -719,6 +720,13 @@ int cmd_create(int argc, const char **argv) } opt_session_name = (char*) poptGetArg(pc); + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + goto end; + } + command_ret = create_session(); if (command_ret) { success = 0; diff --git a/src/bin/lttng/commands/destroy.c b/src/bin/lttng/commands/destroy.c index 02c7139..6878aaa 100644 --- a/src/bin/lttng/commands/destroy.c +++ b/src/bin/lttng/commands/destroy.c @@ -174,6 +174,7 @@ int cmd_destroy(int argc, const char **argv) int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; + const char *leftover = NULL; struct lttng_session *sessions; int count; @@ -280,6 +281,14 @@ int cmd_destroy(int argc, const char **argv) } } + leftover = poptGetArg(pc); + if (leftover) { + ERR("Unknown argument: %s", leftover); + ret = CMD_ERROR; + success = 0; + goto mi_closing; + } + mi_closing: /* Mi closing */ if (lttng_opt_mi) { diff --git a/src/bin/lttng/commands/disable_channels.c b/src/bin/lttng/commands/disable_channels.c index 775ff89..936884e 100644 --- a/src/bin/lttng/commands/disable_channels.c +++ b/src/bin/lttng/commands/disable_channels.c @@ -216,6 +216,7 @@ int cmd_disable_channels(int argc, const char **argv) int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1; static poptContext pc; char *session_name = NULL; + const char *leftover = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptReadDefaultConfig(pc, 0); @@ -250,6 +251,13 @@ int cmd_disable_channels(int argc, const char **argv) goto
[lttng-dev] [lttng-tools GIT PULL] Session rotation
Hi, Please pull from https://github.com/jdesfossez/lttng-tools-dev.git rotate-squash This branch implements the session rotation feature. For UST, no patches are required, for kernel tracing it depends on this patch: https://github.com/jdesfossez/lttng-modules-dev/commit/43336e7da5ac77ba06c24eb923cf94ccc5385ffc The "lttng rotate" command can be called at any time while the session is running. This flushes the current content of the ring-buffers memory to disk or network, and create new tracefiles in a separate folder to continue writing the active trace, a new metadata file is produced in the new folder as well, so each invocation of the command effectively creates new standalone traces. When the rotate command returns, it outputs the path of the previous chunk of trace (the one that was active up to the moment the rotation started), the user has then complete access to this trace directory and can safely process and/or delete it. The MI interface (lttng --mi xml rotate) also contains the path for automated processing. It is also possible to configure a session to rotate automatically based on a timer or its total size (see the lttng enable-rotation command). Rotations are supported locally and on the relay, the behavior is the same. The only difference is the path output. Locally we output the absolute path of the chunk, on the relay we output the relative path under the relayd output directory. The tests for this feature are in tests/regression/tools/rotation, the complete documentation is currently being written. On top of this branch is going to be added soon the feature the receive notifications when a rotation starts and when it completes. This is a big feature, that modifies a lot of the internals in lttng-tools, so all testing and reviewing is appreciated ! Julien Desfossez (37): Fix: use a free running channel key between sessiond and kernel consumer Fix: lttng logs nanoseconds Fix: stream_per_chan_id_ht should allow duplicates Make kernel tracer version global Change trace_path to session_root_path and chunk_path Keep the base directory of a relay session separate Command to make a directory on the consumer or relay Create the session and domain directories on start Command to rename a folder Fix: kernel snapshot handling of EAGAIN Fix: keep the number of pipes used by poll in a variable Keep read-only copies of fields from the channel to the stream Dedicated function to wakeup the consumer metadata pipe Common consumer functions to read current positions Add ustctl_flush_buffer to the consumer API Support to dump the kernel metadata cache for the beginning Channel rotate pipe between sessiond and the consumers Rotation on the relay Rotate pending support on the relay Consumer rotate stream Consumer perform the rotation when extracting a packet Consumer rotate a channel Sessiond rotation thread Sessiond timer thread Rotate command Relay rotate pending command lttng rotate command Rotate timer Session consumed size notification Size-based rotation Save, restore and list the rotation parameters Example client to use the session rotation API Fix validate_trace_empty test check Tests for the session rotation feature Prevent manual session rotation when auto rotation is configured Fix consumed pos for overwrite mode Add the GMT offset in the rotated chunk path Jérémie Galarneau (14): ht utils are unnecessarily non-const Bump minor notification protocol version Typo fixes in notification thread comments Separate session info from channel info in notification thread Add likely/unlikely annotations on channel sample handling path Fix: previous channel total is not updated Remove unneeded forward declaration in condition headers Docs: wrong enum value used in evaluation API description Remove unneeded domain.h include Fix: circular inclusion of lttng.h results in warning Docs: typo in notification channel header Fix: channel lock must be taken to check for pending notifications Add lttng_notification_channel_has_pending_notification() Check for pending notification on notification channel activity configure.ac | 1 + doc/examples/rotation/rotate-client-compress.sh | 14 ++ doc/examples/rotation/rotate-client-example.c| 345 include/Makefile.am | 4 + include/lttng/condition/buffer-usage.h | 11 +- include/lttng/condition/condition.h | 3 +- include/lttng/condition/session-consumed-size-internal.h | 65 ++ include/lttng/condition/session-consumed-size.h | 138 + include/lttng/ltt
Re: [lttng-dev] Latency tracing using LTTng
ot;, as it was hung, > the system just rebooted without panic. > > > This is from the syslog, and I see the same output on console > > 1613 Dec 27 16:53:37 kernel: [12566.627939] ring buffer > relay-metadata: 0 records written, 0 records overrun > 1614 Dec 27 16:53:37 kernel: [12566.634983] ring buffer > relay-metadata, cpu -1: non-consumed data > 1615 Dec 27 16:53:37 kernel: [12566.634983] [ 12288 bytes > written, 8192 bytes read ] > 1616 Dec 27 16:53:37 kernel: [12566.646189] ring buffer: > relay-metadata, cpu -1: 8192 bytes committed > 1617 Dec 27 16:53:37 kernel: [12566.652780] ring buffer > relay-discard, cpu 0: 0 records written, 0 records overrun > 1618 Dec 27 16:53:38 kernel: [12566.660865] ring buffer > relay-discard, cpu 1: 0 records written, 0 records overrun > 1619 Dec 27 16:53:38 kernel: [12566.668924] ring buffer > relay-discard, cpu 2: 0 records written, 0 records overrun > 1620 Dec 27 16:53:38 kernel: [12566.676897] ring buffer > relay-discard, cpu 3: 0 records written, 0 records overrun > 1621 Dec 27 16:53:38 kernel: [12566.684809] ring buffer > relay-discard, cpu 4: 0 records written, 0 records overrun > 1622 Dec 27 16:53:38 kernel: [12566.692681] ring buffer > relay-discard, cpu 5: 0 records written, 0 records overrun > 1623 Dec 27 16:54:16 avahi-daemon[948]: Registering new address > record for 10.31.33.48 on eth0.IPv4. > 1624 Dec 27 16:54:16 rsyslogd-2007: action 'action 9' suspended, > next retry is Wed Dec 27 16:55:46 2017 [v8.16.0 t ry > http://www.rsyslog.com/e/2007 ] > 1625 Dec 27 16:54:16 systemd-timesyncd[816]: Network configuration > changed, trying to establish connection. > 1626 Dec 27 16:54:16 systemd-timesyncd[816]: Synchronized to time > server 91.189.94.4:123 <http://91.189.94.4:123> (ntp.ubuntu.com > <http://ntp.ubuntu.com>). > 1627 Dec 27 16:54:17 rsyslogd: [origin software="rsyslogd" > swVersion="8.16.0" x-pid="924" x-info="http://www.rsysl og.com > <http://og.com>"] start > 1628 Dec 27 16:54:17 rsyslogd-: command > 'KLogPermitNonKernelFacility' is currently not permitted - did you > alr eady set it via a RainerScript command (v6+ config)? > [v8.16.0 try http://www.rsyslog.com/e/ ] > 1629 Dec 27 16:54:17 rsyslogd: rsyslogd's groupid changed to 115 > 1630 Dec 27 16:54:17 rsyslogd: rsyslogd's userid changed to 108 > 1631 Dec 27 16:54:17 kernel: [ 0.00] Booting Linux on > physical CPU 0x100 > 1632 Dec 27 16:54:17 kernel: [ 0.00] Initializing cgroup > subsys cpuset > 1633 Dec 27 16:54:17 kernel: [ 0.00] Initializing cgroup > subsys cpu > 1634 Dec 27 16:54:17 kernel: [ 0.00] Initializing cgroup > subsys cpuacct > 1635 Dec 27 16:54:17 kernel: [ 0.00] Linux version > 4.4.38-rt49-tegra (anup.pemmaiah@anup-pemmaiah) (gcc ver sion > 4.9.2 (GCC) ) #1 SMP PREEMPT RT Thu Nov 30 17:12:21 PST 2017 > 1636 Dec 27 16:54:17 kernel: [ 0.00] Boot CPU: AArch64 > Processor [411fd073] > 1637 Dec 27 16:54:17 kernel: [ 0.00] earlycon: Early serial > console at MMIO32 > > > > > > > Not sure how updated the above pasted links are, because I notice > there is > > no more usec_threshold parameter and I use the threshold > > in /sys/kernel/debug/latency/syscalls/default/threshold > > > > I understand each situation is different, but was curious if any > of you > > have comments/suggestions that would help in debugging latency > related > > issues using LTTng. I have looked many places to get required info > but of > > not much help. > > Most of the maintainers are on vacation during this part of the > year so it might > take some time to get answers. I'm sure that Julien Desfossez > will be > interested in your use case. > > Cheers > > > I undersatnd and any suggestions will be very helpful > > > > > > Your comments/suggestions will be greatly appreciated. > > > > Thanks > > Anup > > > ___ > > lttng-dev mailing list > > lttng-dev@lists.lttng.org <mailto:lttng-dev@lists.lttng.org> > > https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > <https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev> > > > -- > Jonathan Rajotte-Julien > EfficiOS > > > > > > ___ > lttng-dev mailing list > lttng-dev@lists.lttng.org > https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2] Test for lttng-logger
Basic test to write in /proc/lttng-logger and /dev/lttng-logger and ensure we have the right amount of events in the trace resulting trace. We also test the 1024 characters limit for the payload. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am | 2 +- tests/regression/kernel/test_lttng_logger | 138 ++ tests/root_regression | 1 + tests/utils/utils.sh | 2 +- 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100755 tests/regression/kernel/test_lttng_logger diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index c4ee443..a0abc7b 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = test_event_basic test_all_events test_syscall \ test_clock_override test_rotation_destroy_flush \ - test_select_poll_epoll + test_select_poll_epoll test_lttng_logger noinst_PROGRAMS = select_poll_epoll select_poll_epoll_SOURCES = select_poll_epoll.c diff --git a/tests/regression/kernel/test_lttng_logger b/tests/regression/kernel/test_lttng_logger new file mode 100755 index 000..b0a53fe --- /dev/null +++ b/tests/regression/kernel/test_lttng_logger @@ -0,0 +1,138 @@ +#!/bin/bash +# +# Copyright (C) - 2017 Julien Desfossez <jdesfos...@efficios.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +TEST_DESC="Kernel tracer - lttng-logger" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../.. +NUM_TESTS=30 +PAYLOAD="test_logger" +SESSION_NAME="kernel_event_basic" + +source $TESTDIR/utils/utils.sh + +function test_proc_logger() +{ + diag "Test /proc/lttng-logger" + + TRACE_PATH=$(mktemp -d) + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_event $SESSION_NAME "lttng_logger" + + start_lttng_tracing_ok + + test -e /proc/lttng-logger + if test $? = 0; then + pass "/proc/lttng-logger exists" + echo -n "$PAYLOAD proc" > /proc/lttng-logger + ok $? "Write in /proc/lttng-logger" + else + fail "No /proc/lttng-logger" + fi + + stop_lttng_tracing_ok + + validate_trace_count "lttng_logger" $TRACE_PATH 1 + validate_trace_only_exp "$PAYLOAD" $TRACE_PATH + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_dev_logger() +{ + diag "Test /dev/lttng-logger" + + TRACE_PATH=$(mktemp -d) + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_event $SESSION_NAME "lttng_logger" + + start_lttng_tracing_ok + + test -c /dev/lttng-logger + if test $? = 0; then + pass "/dev/lttng-logger is a character device" + echo -n "$PAYLOAD dev" > /dev/lttng-logger + ok $? "Write in /dev/lttng-logger" + else + fail "No /dev/lttng-logger" + fi + + stop_lttng_tracing_ok + + validate_trace_count "lttng_logger" $TRACE_PATH 1 + validate_trace_only_exp "$PAYLOAD" $TRACE_PATH + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_payload_limit() +{ + diag "Test lttng-logger payload limit" + + TRACE_PATH=$(mktemp -d) + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_event $SESSION_NAME "lttng_logger" + + start_lttng_tracing_ok + + # Write 100 times "test_logger", which generates 1200 characters, we expect + # the tracer to write 2 events from that string because it limits the + # input to 1024 strings. + printf "%.s $PAYLOAD" {1..100} > /proc/lttng-logger + printf "%.s $PAYLOAD" {1..100} > /dev/lttng-logger + + stop_lttng_tracing_ok + + validate_trace_count "lttng_logger" $TRACE_PATH 4 + validate_trace_only_exp "$PAYLOAD" $TRACE_PATH + + destroy_lttng_session_ok $SESSION_NAME + +
[lttng-dev] [PATCH babeltrace] Fix: lttng-live discarded event count after inactivity
When a stream is inactive, the consumer produces fake indexes which are beacons to let the viewer know a stream has not produced any data up to a certain timestamp. These beacon are actually real packet indexes with all the fields set to 0 except for the timestamp_end. Currently we keep these beacons just like we keep real indexes. The problem is that when we switch packet, we compare the events_discarded field in the index we just received with the same field in the previous index. In the case where a stream has been inactive, we have received inactivity beacons, and set the discarded_event field to 0, so the difference with the next real index might be wrong. In fact, since the inactivity beacons are only used to push the timestamp end of a stream, we don't need to keep them and we actually need to keep most of the data from the real previous index. So we now copy the entire prev_index into the cur_index when we receive an inactivity beacon. We could refactor the code to avoid performing the pointer swap of cur and prev indexes, but this implies a redesign of much of the packet switching code which would affect other code paths. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- formats/lttng-live/lttng-live-comm.c | 16 1 file changed, 16 insertions(+) diff --git a/formats/lttng-live/lttng-live-comm.c b/formats/lttng-live/lttng-live-comm.c index 77bf34a..3ffa257 100644 --- a/formats/lttng-live/lttng-live-comm.c +++ b/formats/lttng-live/lttng-live-comm.c @@ -1275,6 +1275,7 @@ retry: pos->offset = 0; } + /* Beacon packet index */ if (cur_index->content_size == 0) { if (file_stream->parent.stream_class) { file_stream->parent.cycles_timestamp = @@ -1282,8 +1283,23 @@ retry: file_stream->parent.real_timestamp = ctf_get_real_timestamp( _stream->parent, cur_index->ts_cycles.timestamp_end); + + /* +* Duplicate the data from the previous index, because +* the one we just received is only a beacon with no +* relevant information except the timestamp_end. We +* don't need to keep this timestamp_end because we already +* updated the file_stream timestamps, so we only need +* to keep the last real index data as prev_index. That +* way, we keep the original prev timestamps and +* discarded events counter. This is the same behaviour +* as if we were reading a local trace, we would not +* have fake indexes between real indexes. +*/ + memcpy(cur_index, prev_index, sizeof(struct packet_index)); } } else { + /* Real packet index */ if (file_stream->parent.stream_class) { /* Convert the timestamps and append to the real_index. */ cur_index->ts_real.timestamp_begin = ctf_get_real_timestamp( -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Test for lttng-logger
Basic test to write in /proc/lttng-logger and /dev/lttng-logger and ensure we have the right amount of events in the trace resulting trace. We also test the 1024 characters limit for the payload. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am | 2 +- tests/regression/kernel/test_lttng_logger | 85 +++ tests/root_regression | 1 + tests/utils/utils.sh | 2 +- 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100755 tests/regression/kernel/test_lttng_logger diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index c4ee443..a0abc7b 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = test_event_basic test_all_events test_syscall \ test_clock_override test_rotation_destroy_flush \ - test_select_poll_epoll + test_select_poll_epoll test_lttng_logger noinst_PROGRAMS = select_poll_epoll select_poll_epoll_SOURCES = select_poll_epoll.c diff --git a/tests/regression/kernel/test_lttng_logger b/tests/regression/kernel/test_lttng_logger new file mode 100755 index 000..54fd1c3 --- /dev/null +++ b/tests/regression/kernel/test_lttng_logger @@ -0,0 +1,85 @@ +#!/bin/bash +# +# Copyright (C) - 2017 Julien Desfossez <jdesfos...@efficios.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +TEST_DESC="Kernel tracer - lttng-logger" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../.. +NUM_TESTS=13 + +source $TESTDIR/utils/utils.sh + +function test_logger_normal() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_event_basic" + + PAYLOAD="test_logger" + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_event $SESSION_NAME "lttng_logger" + + start_lttng_tracing_ok + + test -e /proc/lttng-logger + ok $? "/proc/lttng-logger exists" + echo -n "$PAYLOAD proc" > /proc/lttng-logger + + test -c /dev/lttng-logger + if test $? = 0; then + pass "/dev/lttng-logger is a character device" + echo -n "$PAYLOAD dev" > /dev/lttng-logger + ok $? "Write in /dev/lttng-logger" + else + fail "No /dev/lttng-logger" + fi + + # Write 100 times "test_logger", which generates 1200 characters, we expect + # the tracer to write 2 events from that string because it limits the + # input to 1024 strings. + printf "%.s $PAYLOAD" {1..100} >/proc/lttng-logger + + stop_lttng_tracing_ok + + validate_trace_count "lttng_logger" $TRACE_PATH 4 + validate_trace_only_exp "$PAYLOAD" $TRACE_PATH + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH +} + +# MUST set TESTDIR before calling those functions +plan_tests $NUM_TESTS + +print_test_banner "$TEST_DESC" + +if [ "$(id -u)" == "0" ]; then + isroot=1 +else + isroot=0 +fi + +skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS || +{ + start_lttng_sessiond + + test_logger_normal + + stop_lttng_sessiond +} diff --git a/tests/root_regression b/tests/root_regression index 7639c18..f17ac97 100644 --- a/tests/root_regression +++ b/tests/root_regression @@ -4,6 +4,7 @@ regression/kernel/test_syscall regression/kernel/test_clock_override regression/kernel/test_rotation_destroy_flush regression/kernel/test_select_poll_epoll +regression/kernel/test_lttng_logger regression/tools/live/test_kernel regression/tools/live/test_lttng_kernel regression/tools/streaming/test_high_throughput_limits diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index e8dfcda..50b5db1 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -1480,7 +1480,7 @@ function validate_trace_only_exp() local total=$($BABELTRACE_BIN $trace_path | wc -l) if [ "$count" -ne 0 ] && [ "$total" -eq "$count" ]; then - pass "Trace match with $total for expression '${event_exp}" + pass &q
Re: [lttng-dev] Problem in Tracing C Program
On 2017-11-30 12:51 PM, MMM wrote: > Dear Julien, > > Thanks for your response. Is the mentioned task easier in Java or C program? > indeed, I think it can be easier in Java program. If it is true, I can > switch to Java language. No, your test program should be in C because it will be easy to link the open()/read() calls from your C program to the open/read system calls. Julien > > On Thursday, November 30, 2017, 7:15:21 PM GMT+3:30, Julien Desfossez > <jdesfos...@efficios.com> wrote: > > > On 2017-11-30 10:13 AM, MMM via lttng-dev wrote: > >> Dear Users, >> >> I have posted a couple of email about my problem in the past, while >> nobody response those. It may be true that my question is amateurish, >> but due to the fact that I am a beginner, I can not find the sufficient >> document for solving my problem. I am going to trace a C program that >> read from a file and show the ratio of reads from page cache vs reads >> from disk. I read document of LTTng website, but I can not find >> appropriate explanation for this task. I just need a simple guidance to >> show me the right way for doing it. Could you please help me. >> >> Regards, >> Mehdi. > > > Hi, > > This is a really non-trivial task to do. Basically, you need to > distinguish the read() syscalls that lead to FS/disk access with the > ones that don't (for the same FD). > The main difficulty is to make the link between the syscall and the > lower-level events and I am not sure we have all the data needed to > establish this link from the payload of the events we have (something > like FD -> FS inode -> block). > > I added Houssem to this thread because I think I remember he did some > work around that, he may have more information. > > Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Problem in Tracing C Program
On 2017-11-30 10:13 AM, MMM via lttng-dev wrote: > Dear Users, > > I have posted a couple of email about my problem in the past, while > nobody response those. It may be true that my question is amateurish, > but due to the fact that I am a beginner, I can not find the sufficient > document for solving my problem. I am going to trace a C program that > read from a file and show the ratio of reads from page cache vs reads > from disk. I read document of LTTng website, but I can not find > appropriate explanation for this task. I just need a simple guidance to > show me the right way for doing it. Could you please help me. > > Regards, > Mehdi. Hi, This is a really non-trivial task to do. Basically, you need to distinguish the read() syscalls that lead to FS/disk access with the ones that don't (for the same FD). The main difficulty is to make the link between the syscall and the lower-level events and I am not sure we have all the data needed to establish this link from the payload of the events we have (something like FD -> FS inode -> block). I added Houssem to this thread because I think I remember he did some work around that, he may have more information. Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: wrong parameter to fcntl in pipe_set_flag
Depending on the flags passed, fcntl must be called with F_SETFD or F_SETFL. This fix checks the flag passed and ensure it is valid and calls fcntl with the right parameter. Also, for CLOEXEC, we need to pass FD_CLOEXEC, not O_CLOEXEC. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng-sessiond/notification-thread.c | 2 +- src/common/pipe.c| 25 ++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/bin/lttng-sessiond/notification-thread.c b/src/bin/lttng-sessiond/notification-thread.c index c47b365..3ef7df1 100644 --- a/src/bin/lttng-sessiond/notification-thread.c +++ b/src/bin/lttng-sessiond/notification-thread.c @@ -96,7 +96,7 @@ struct notification_thread_handle *notification_thread_handle_create( goto end; } - event_pipe = lttng_pipe_open(O_CLOEXEC); + event_pipe = lttng_pipe_open(FD_CLOEXEC); if (!event_pipe) { ERR("event_pipe creation"); goto error; diff --git a/src/common/pipe.c b/src/common/pipe.c index 4220a40..4fe45ef 100644 --- a/src/common/pipe.c +++ b/src/common/pipe.c @@ -154,9 +154,28 @@ static int _pipe_set_flags(struct lttng_pipe *pipe, int flags) } for (i = 0; i < 2; i++) { - ret = fcntl(pipe->fd[i], F_SETFD, flags); - if (ret < 0) { - PERROR("fcntl lttng pipe %d", flags); + if (flags & O_NONBLOCK) { + ret = fcntl(pipe->fd[i], F_SETFL, O_NONBLOCK); + if (ret < 0) { + PERROR("fcntl lttng pipe %d", flags); + goto end; + } + } + if (flags & FD_CLOEXEC) { + ret = fcntl(pipe->fd[i], F_SETFD, FD_CLOEXEC); + if (ret < 0) { + PERROR("fcntl lttng pipe %d", flags); + goto end; + } + } + /* +* We only check for O_NONBLOCK or FD_CLOEXEC, if another flag is +* needed, we can add it, but for now just make sure we don't make +* mistakes with the parameters we pass. +*/ + if (!(flags & O_NONBLOCK) && !(flags & FD_CLOEXEC)) { + fprintf(stderr, "Unsupported flag\n"); + ret = -1; goto end; } } -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] Videos from the Tracing Summit 2017
Hi, The videos from the Tracing Summit 2017 are now online: https://www.youtube.com/watch?v=m8gig4BBGP0=1=PLuo4E47p5_7bfeZyYIyNYM-f-2tmr0neu You can also access them from the schedule here: http://tracingsummit.org/wiki/TracingSummit2017#Schedule Enjoy, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-modules] Command to dump the metadata cache again
This command allows the consumer to ask for the metadata cache to be dumped entirely another time. This is used by the session rotation feature to get a new copy of what was in the metadata cache without regenerating it and re-sampling the offset from epoch. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- lib/ringbuffer/vfs.h | 5 + lttng-abi.c | 44 lttng-events.c | 2 -- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/ringbuffer/vfs.h b/lib/ringbuffer/vfs.h index b2e5b1c..e2bc401 100644 --- a/lib/ringbuffer/vfs.h +++ b/lib/ringbuffer/vfs.h @@ -123,6 +123,11 @@ ssize_t vfs_lib_ring_buffer_splice_read(struct file *in, loff_t *ppos, #define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS _IO(0xF6, 0x0E) /* Flush the current sub-buffer, even if empty. */ #define RING_BUFFER_FLUSH_EMPTY_IO(0xF6, 0x0F) +/* + * Reset the position of what has been consumed from the metadata cache to 0 + * so it can be read again. + */ +#define RING_BUFFER_METADATA_CACHE_DUMP_IO(0xF6, 0x10) #ifdef CONFIG_COMPAT /* Get a snapshot of the current ring buffer producer and consumer positions */ diff --git a/lttng-abi.c b/lttng-abi.c index 77e5e98..d202b72 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -654,6 +654,38 @@ void lttng_metadata_ring_buffer_ioctl_put_next_subbuf(struct file *filp, stream->metadata_out = stream->metadata_in; } +/* + * Reset the counter of how much metadata has been consumed to 0. That way, + * the consumer receives the content of the metadata cache unchanged. This is + * different from the metadata_regenerate where the offset from epoch is + * resampled, here we want the exact same content as the last time the metadata + * was generated. This command is only possible if all the metadata written + * in the cache has been output to the metadata stream to avoid corrupting the + * metadata file. + * + * Return 0 on success, a negative value on error. + */ +static +int lttng_metadata_cache_dump(struct lttng_metadata_stream *stream) +{ + int ret; + struct lttng_metadata_cache *cache = stream->metadata_cache; + + mutex_lock(>lock); + if (stream->metadata_out != cache->metadata_written) { + ret = -EBUSY; + goto end; + } + stream->metadata_out = 0; + stream->metadata_in = 0; + wake_up_interruptible(>read_wait); + ret = 0; + +end: + mutex_unlock(>lock); + return ret; +} + static long lttng_metadata_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) @@ -706,6 +738,12 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, return put_u64(stream->version, arg); } + case RING_BUFFER_METADATA_CACHE_DUMP: + { + struct lttng_metadata_stream *stream = filp->private_data; + + return lttng_metadata_cache_dump(stream); + } default: break; } @@ -783,6 +821,12 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, return put_u64(stream->version, arg); } + case RING_BUFFER_METADATA_CACHE_DUMP: + { + struct lttng_metadata_stream *stream = filp->private_data; + + return lttng_metadata_cache_dump(stream); + } default: break; } diff --git a/lttng-events.c b/lttng-events.c index 21c4113..8719173 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -342,8 +342,6 @@ end: return ret; } - - int lttng_channel_enable(struct lttng_channel *channel) { int ret = 0; -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] Tracing Summit 2017 Schedule
The schedule for the Tracing Summit 2017 that will be held in Prague, Czech Republic on October 27th, 2017 is now available online: http://tracingsummit.org/wiki/TracingSummit2017#Schedule If you want to attend and are not yet registered, please do it quickly as the room is already almost full. See the wiki for the details. We are still accepting discussion topic proposals. Thanks, Julien Desfossez & Mathieu Desnoyers ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [RFC PATCH lttng-tools v2] Fix: path of snapshots with a relay and default URI
When recording a snapshot to a relay without custom URI (ex: net://localhost vs net://localhost/custom), the snapshots end up being stored in ~/lttng-traces//snapshot-XXX instead of being inside the folder like on local snapshots. We would expect the path to be: ~/lttng-traces///snapshot-XXX So there is a discrepancy between the local and remote behaviour. This behaviour has been there since at least v2.6, maybe earlier. Moreover, there is nothing that informs the user about the default snapshot name, so it is not possible to know where a snapshot has been stored. After parsing the URI provided by the user, we now check if a custom name was provided or copy the session name there. This is the same operation performed in _lttng_create_session_ext. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/lib/lttng-ctl/lttng-ctl.c | 13 + 1 file changed, 13 insertions(+) diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index a1e10f2..3db9b89 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -2485,9 +2485,22 @@ int lttng_create_session_snapshot(const char *name, const char *snapshot_url) lsm.u.uri.size = size; + /* +* If the user does not specify a custom subdir, use the session name. +*/ + if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) { + ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name); + if (ret < 0) { + PERROR("snprintf uri subdir"); + ret = -LTTNG_ERR_FATAL; + goto error; + } + } + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(, uris, sizeof(struct lttng_uri) * size, NULL); +error: free(uris); return ret; } -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools] Fix: path of snapshots with a relay and default URI
I found a way to store this information only in the case of snapshots instead of for all session created, see v2. ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: path of snapshots with a relay and default URI
When recording a snapshot to a relay without custom URI (ex: net://localhost vs net://localhost/custom), the snapshots end up being stored in ~/lttng-traces//snapshot-XXX instead of being inside the folder like on local snapshots. We would expect the path to be: ~/lttng-traces///snapshot-XXX So there is a discrepancy between the local and remote behaviour. This behaviour has been there since at least v2.6, maybe earlier. Moreover, there is nothing that informs the user about the default snapshot name, so it is not possible to know where a snapshot has been stored. The subdir variable when using a relay is the path on the relay (after ~/lttng-traces/). We then prepend the hostname and append the domain-specific name (/kernel or /ust). A lot of counter-intuitive manipulations, but this ends up being the correct path. A patch to simplify this is on its way later. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/bin/lttng-sessiond/cmd.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index a295059..c91d649 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2635,6 +2635,12 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris, } session->output_traces = 1; } else { + /* +* For snapshots to a relay with the default session name, +* we have to store the session name here since it becomes the +* base of the path and we only append to this path afterwards. +*/ + snprintf(session->consumer->subdir, PATH_MAX, "%s", name); session->output_traces = 0; DBG2("Session %s created with no output", session->name); } -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools v2] Fix: wrong use of the relay_streams_sent in snapshot
>>> If you remove this, I think the streams will never get published >>> within the relayd. (publish_connection_local_streams()). Is this >>> an expected side-effect ? It should be documented in the changelog. >>> My guess is that we indeed don't want to publish the snapshot >>> streams to the viewers. >> Indeed, a snapshot session cannot be a live session, so we don't >> want/need to publish those streams. Also, sending this message every >> time we send a stream is a wrong usage of the command. > > You'll need to ensure that we are not freeing the streams too > quickly or leaking them in relayd after your change. Publishing the stream does not take a new reference on the stream, it just adds it in the stream_list so it becomes visible in the viewer thread. So it does not change the lifetime of the stream. And if the stream is not published when we remove it we don't try to unpublish it. >>> The reason for doing this change should also be documented. What >>> behavior is unwanted here from a relayd perspective ? >> We are sending this message to the relay (and waiting for the >> confirmation) before taking the snapshot of each stream. So, in addition >> to being wrong and useless, it adds a considerable delay before taking >> the snapshot of each stream. >> >> Do you agree ? > > It looks like a good idea to remove it. I just want us to make sure the > snapshot mode does not somehow expect the streams to be published > within other parts of the relayd code. It looks good. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools v2] Fix: wrong use of the relay_streams_sent in snapshot
> If you remove this, I think the streams will never get published > within the relayd. (publish_connection_local_streams()). Is this > an expected side-effect ? It should be documented in the changelog. > My guess is that we indeed don't want to publish the snapshot > streams to the viewers. Indeed, a snapshot session cannot be a live session, so we don't want/need to publish those streams. Also, sending this message every time we send a stream is a wrong usage of the command. > The reason for doing this change should also be documented. What > behavior is unwanted here from a relayd perspective ? We are sending this message to the relay (and waiting for the confirmation) before taking the snapshot of each stream. So, in addition to being wrong and useless, it adds a considerable delay before taking the snapshot of each stream. Do you agree ? Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools] Fix: wrong use of the relay_streams_sent in snapshot
Missing the change from ust-consumer.c, see v2. ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: the return code of lttcomm_send_unix_sock is signed
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/common/kernel-consumer/kernel-consumer.c | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 7bcb86a..a5dcc66 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -983,7 +983,8 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, } case LTTNG_CONSUMER_DISCARDED_EVENTS: { - uint64_t ret; + ssize_t ret; + uint64_t count; struct lttng_consumer_channel *channel; uint64_t id = msg.u.discarded_events.session_id; uint64_t key = msg.u.discarded_events.channel_key; @@ -995,15 +996,15 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, if (!channel) { ERR("Kernel consumer discarded events channel %" PRIu64 " not found", key); - ret = 0; + count = 0; } else { - ret = channel->discarded_events; + count = channel->discarded_events; } health_code_update(); /* Send back returned value to session daemon */ - ret = lttcomm_send_unix_sock(sock, , sizeof(ret)); + ret = lttcomm_send_unix_sock(sock, , sizeof(count)); if (ret < 0) { PERROR("send discarded events"); goto error_fatal; @@ -1013,7 +1014,8 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, } case LTTNG_CONSUMER_LOST_PACKETS: { - uint64_t ret; + ssize_t ret; + uint64_t count; struct lttng_consumer_channel *channel; uint64_t id = msg.u.lost_packets.session_id; uint64_t key = msg.u.lost_packets.channel_key; @@ -1025,15 +1027,15 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, if (!channel) { ERR("Kernel consumer lost packets channel %" PRIu64 " not found", key); - ret = 0; + count = 0; } else { - ret = channel->lost_packets; + count = channel->lost_packets; } health_code_update(); /* Send back returned value to session daemon */ - ret = lttcomm_send_unix_sock(sock, , sizeof(ret)); + ret = lttcomm_send_unix_sock(sock, , sizeof(count)); if (ret < 0) { PERROR("send lost packets"); goto error_fatal; -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2] Fix: wrong use of the relay_streams_sent in snapshot
The relay_streams_sent message is only useful in live sessions and should only be sent after all the streams of a channel have been sent. Here we were sending this message every time we sent a stream to the relay during a snapshot which makes no sense. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/common/kernel-consumer/kernel-consumer.c | 8 src/common/ust-consumer/ust-consumer.c | 6 -- 2 files changed, 14 deletions(-) diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index a5dcc66..1c2751b 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -187,14 +187,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path, DBG("Kernel consumer snapshot stream %s/%s (%" PRIu64 ")", path, stream->name, stream->key); } - if (relayd_id != -1ULL) { - ret = consumer_send_relayd_streams_sent(relayd_id); - if (ret < 0) { - ERR("sending streams sent to relayd"); - goto end_unlock; - } - channel->streams_sent_to_relayd = true; - } ret = kernctl_buffer_flush_empty(stream->wait_fd); if (ret < 0) { diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 366f855..bce7db8 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -1101,12 +1101,6 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id, DBG("UST consumer snapshot stream %s/%s (%" PRIu64 ")", path, stream->name, stream->key); } - if (relayd_id != -1ULL) { - ret = consumer_send_relayd_streams_sent(relayd_id); - if (ret < 0) { - goto error_unlock; - } - } /* * If tracing is active, we want to perform a "full" buffer flush. -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: wrong use of the relay_streams_sent in snapshot
The relay_streams_sent message is only useful in live sessions and should only be sent after all the streams of a channel have been sent. Here we were sending this message every time we sent a stream to the relay during a snapshot which makes no sense. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/common/kernel-consumer/kernel-consumer.c | 8 1 file changed, 8 deletions(-) diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index a5dcc66..1c2751b 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -187,14 +187,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path, DBG("Kernel consumer snapshot stream %s/%s (%" PRIu64 ")", path, stream->name, stream->key); } - if (relayd_id != -1ULL) { - ret = consumer_send_relayd_streams_sent(relayd_id); - if (ret < 0) { - ERR("sending streams sent to relayd"); - goto end_unlock; - } - channel->streams_sent_to_relayd = true; - } ret = kernctl_buffer_flush_empty(stream->wait_fd); if (ret < 0) { -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Fix: lost packet accounting always lost on snapshot
Because of the continue when we fail to get a subbuff, the lost_packet count is always reset to 0 before we can account it in the channel. Now we account it directly before the continue. Reported-by: Jonathan Rajotte <jonathan.rajotte-jul...@efficios.com> Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- src/common/kernel-consumer/kernel-consumer.c | 11 +-- src/common/ust-consumer/ust-consumer.c | 11 +-- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 8d00a0d..7686356 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -249,7 +249,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path, while (consumed_pos < produced_pos) { ssize_t read_len; unsigned long len, padded_len; - int lost_packet = 0; health_code_update(); @@ -270,7 +269,7 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path, * content of the final snapshot). */ if (!before_first_packet) { - lost_packet = 1; + stream->chan->lost_packets++; } continue; } @@ -313,14 +312,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path, } consumed_pos += stream->max_sb_size; - /* -* Only account lost packets located between -* succesfully extracted packets (do not account before -* and after since they are not visible in the -* resulting snapshot). -*/ - stream->chan->lost_packets += lost_packet; - lost_packet = 0; before_first_packet = false; } diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 4297d60..74853cd 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -1150,7 +1150,6 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id, while (consumed_pos < produced_pos) { ssize_t read_len; unsigned long len, padded_len; - int lost_packet = 0; health_code_update(); @@ -1171,7 +1170,7 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id, * content of the final snapshot). */ if (!before_first_packet) { - lost_packet = 1; + stream->chan->lost_packets++; } continue; } @@ -1209,14 +1208,6 @@ static int snapshot_channel(uint64_t key, char *path, uint64_t relayd_id, } consumed_pos += stream->max_sb_size; - /* -* Only account lost packets located between -* succesfully extracted packets (do not account before -* and after since they are not visible in the -* resulting snapshot). -*/ - stream->chan->lost_packets += lost_packet; - lost_packet = 0; before_first_packet = false; } -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [CFP/CFD] Tracing Summit 2017 Call for Presentations and Discussions, October 27th, 2017, Prague, Czech Republic
Hi, This is a call for presentations for the Tracing Summit which will be held in Prague, Czech Republic, on October 27th, 2017, at the Hilton Prague. This event is co-located with the Open Source Summit Europe 2017. The Tracing Summit is organized by the Linux Foundation Diagnostic and Monitoring Workgroup (http://diamon.org). This event focuses on the tracing area, gathering people involved in development and end-users of tracing tools as well as trace analysis tools. The main target of this Tracing Summit is to provide room for discussion between people in the various areas that benefit from tracing, namely parallel, distributed and/or real-time systems, as well as kernel development. New in the 2017 edition: half the day will be reserved for presentations and the other half will be reserved for discussions (more in the style of Linux Plumbers Conference) between users and developers of the tracing infrastructures. Steven Rostedt will run the discussion part. If you are interested to present, please submit a proposal to submiss...@tracingsummit.org before September 1st, 2017, at 23:59 EST. Please specify if it is a presentation or a discussion topic, provide a title, an abstract describing the proposed presentation or discussion topic (900 characters maximum), a short biography (900 characters maximum), and describe the targeted audience (900 characters maximum). We are welcoming presentations from both end users and developers, on topics covering, but not limited to: * Investigation workflow of Real-Time, latency, and throughput issues, * Trace collection and extraction, * Trace filtering, * Trace aggregation, * Trace formats, * Tracing multi-core systems, * Trace abstraction, * Trace modeling, * Automated trace analysis (e.g. dependency analysis), * Tracing large clusters and distributed systems, * Hardware-level tracing (e.g. DSP, GPU, bare-metal), * Trace visualisation, * Interaction between debugging and tracing, * Tracing remote control, * Analysis of large trace datasets, * Cloud trace collection and analysis, * Integration between trace tools, * Live tracing & monitoring. Those can cover recently available technologies, ongoing work, and yet non-existing technologies (which are compellingly interesting to end-users). Please understand that this open forum is not the proper place to present sales or marketing pitches, nor technologies which are prevented from being freely used in open source. There is a single track, containing presentations between 30 and 45 minutes per subject with discussion. This year, attending the Tracing Summit is free of charge, and attendees are not required to register to other events. The registration will soon be available on the Open Source Summit website, the room is limited to 100 persons, so don't wait too long before registering. The Tracing Summit is currently sponsored by EfficiOS. We are welcoming additional sponsors. Please let us know if your company is interested in sponsoring this event or next year's Tracing Summit. See the Tracing Summit 2017 wiki at http://www.tracingsummit.org/wiki/TracingSummit2017 for details. Thank you, On behalf of the Diagnostic and Monitoring Workgroup, Julien Desfossez & Mathieu Desnoyers ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Writing from a trace to a new one with Babeltrace 2.0.0-pre1 C API
Hi, On 2017-06-29 01:37 PM, Marie Martin wrote: > Hi everyone! > > I'm trying to use Babeltrace 2.0.0-pre1 C API to copy some events of an > existing CTF trace (generated with LTTng) into a new one. So I was > wondering how I should open the existing trace and iterate over its > events, as there is no method bt_ctf_iter_create, bt_ctf_iter_read_event > and such, anymore. > > Before, with the 1.5 API, I was reading the trace like this : > struct bt_context *ctx = bt_context_create(); > int trace_id = bt_context_add_trace(ctx, read_trace_path, "ctf", > NULL, NULL, NULL); > struct bt_ctf_iter *iter = bt_ctf_iter_create(ctx, NULL, NULL); > while ((ctf_event = bt_ctf_iter_read_event(iter))) { ... } > > I'm not sure about the proper way to do it now. I tried to replicate > some of the code from babeltrace.c (especially the cmd_run function) and > I'm able to print metadata from the trace (using > bt_component_class_query(src_component_class, "metadata-info", params) > after gettting the ctf plugin and the source component). Can I use > queries in a similar way to access trace events data ? > > I also tried to instantiate a new graph, add the ctf plugin components > to the graph and run it, but I don't know how to collect events. > > Also, should I define my own custom plugin for that purpose ? Yes, plugins is probably the simplest way to do it right now, let the main Babeltrace executable handle the trace opening and handling, and connect a filter (or a sink if your plugin needs a custom output) to manipulate the traces and events from there. From the plugin point of view, you receive and handle notifications (new stream, new packet, new event, etc). If you need to embed this into your own executable, you have to connect the graph yourself, but I'm not sure exactly how to do it, others on this list can answer. So I think, the easiest way to start, would be to look at the already existing plugins. When simply running babeltrace on a trace, it automatically connects the following chain of plugins : - ctf/fs-src input - utils/muxer filter - lttng-utils/debug-info filter - text/pretty sink The ctf/fs-sink sink plugin takes traces as input, performs some manipulations if needed on the trace structure and writes CTF as output. In there you should see how to create a new trace, new streams, manipulate stream classes, event classes, etc. The API documentation is very well explained, but I don't think there is a higher level documentation that details how to manipulate traces and events, so the existing plugins should help. You can also look at the debug-info filter plugin which takes traces as input, creates new traces with additional fields and forwards the result to the rest of the chain (which can be the ctf.fs-sink to output the result in a CTF trace). The plugin/libctfcopytrace internal library has some helper functions to copy the main parts of a CTF trace. It is not currently a public library installed on the system, but it only uses public API functions from the Babeltrace library, so if you need to build your plugin out-of-tree, you can just copy it. It might become part of the public API if it becomes more used. Connecting your plugins to the graph can then be done on the command line with the --component parameter. I hopes this helps you start, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH babeltrace] Fix: text output missing separator when printing the domain
With the "-f all" option, we expect to see ::, but instead we see :. Judging from the pattern of the other printed fields, the check for "dom_print" variable seems to be missing when printing the domain. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- formats/ctf-text/ctf-text.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c index f615161..69450cf 100644 --- a/formats/ctf-text/ctf-text.c +++ b/formats/ctf-text/ctf-text.c @@ -350,6 +350,8 @@ int ctf_text_write_event(struct bt_stream_pos *ppos, struct ctf_stream_definitio set_field_names_print(pos, ITEM_HEADER); if (pos->print_names) { fprintf(pos->fp, "trace:domain = "); + } else if (dom_print) { + fprintf(pos->fp, ":"); } fprintf(pos->fp, "%s", stream_class->trace->env.domain); if (pos->print_names) -- 2.7.4 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] Videos from the Tracing Summit 2016
Hi, Here are the videos recorded at the tracing summit this year in Berlin: https://www.youtube.com/watch?v=gfqzWPimMKI=PLuo4E47p5_7YAUQ8o3eQwgwLMdi-wzx4w You can also access them from the schedule here: http://tracingsummit.org/wiki/TracingSummit2016 Enjoy, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [RELEASE] LTTng-analyses v0.6
Hi, We are glad to announce a new release of lttng-analyses ! https://github.com/lttng/lttng-analyses This project is a collection of tools to extract metrics and high-level informations from offline LTTng traces to investigate complex problems. The main addition in this release is the new "period" mechanism which allows users to define directly on the command line what events constitute the beginning and the end of a period in their trace, and which field(s) to use to match the two events. Periods can also be fully nested within each other. A visual example of a period and how to define it can be found in [1]. Once the period is defined on the command line, the new lttng-period{top,log,freq,stats} scripts can be used to extract relevant data from the trace put in the form of periods, so a lot of automated statistics can be computed. The README on the github page has examples of some possible outputs. Since the user now defines the periods on the command line, all CTF traces can be used as input, so this is the first release that supports LTTng-UST traces in addition to LTTng kernel traces. Defining a new period is not necessarily a trivial task at first, but it is the same principle as reading a trace manually, you match events and fields (and parent events/fields), once you understand the syntax, you will start making very powerful analyses ! All these new analyses also output the LAMI format, and can be used directly in TraceCompass (daily build or 2.3 release) to make interactive graphs. As always, we appreciate all kinds of feedback, use-cases and real-world experiences, so please test it and let us know what you think about it. Thanks, Julien [1] https://imgur.com/a/bZCgR ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] Tracing a sequence of events through an application
Hi, > All, > I'm wondering if this is something anyone has ever done before: > We have a financial trading application for which we'd like to trace the > timing of a sequence of related events with low impact. For example, tracing > a market data feed packet from its reception on the NIC, to its processing in > the Market Data portion of the code, and on & on via other layers of the > application until it finally reaches the Order Execution portion of the code > where it sends out an Order on the stock exchange. We're wondering if > there's a proven reference for using LTTng-UST to enable session tracing > which would link related activities in this way, as opposed to just providing > aggregate timestamps at various tracepoints within our code. > Has something like this ever been done before using LTTng-UST? If so, is > there a reference available? For this use-case, you will probably be interested in the "period" mechanism of lttng-analyses [1]. It gives you a way to express relationships between events (how to link the beginning and the end of a period), and have nested periods as well. When you have written the periods definition, it gives you statistics, logs and frequency distributions, based on the duration and number of periods encountered. It also outputs the same statistics and frequency distribution for each period in relationship with its parent(s), and will very soon support grouping these results based on the payload (for example: latency frequency distribution of a particular request when fieldX = 42). If you want a quick example, you can have a look at [2]. The limitation of this feature, is that all sub-periods need to be fully nested within their parents, so your instrumentation needs to be in the form of "begin A, begin B, end B, end A" where you have a way to link "begin B" with "begin A" (compared to "state A -> state B"). It works for both cases, but the first one provides much more context information since you can link the periods together. So it's not exactly for sequences of events, but the advantage of working with periods is that it gives you a lot of automatic analyses and the end. This feature is currently only in the master branch of lttng-analyses, but we expect a release by the end of the year, so now is a good time to start playing with it. After that, we will do blog posts to illustrate more all that can be done with it. This is a very powerful feature, but is not necessarily easy to grasp, so take the time to play with it. Basically, if you can manually follow a period from a trace, you can express it with this feature. Otherwise, I know TraceCompass provides a way to define a state machine to follow sequences of events, but I'm not that familiar with it, someone else on this ML will be able to give more details. For your use-case of tracing from the time the packet arrives on the NIC and follow the request up to user-space, we have developed a tracker for this problem in the latency-tracker [3]. It only works "online", so it's not a post-processing solution, but it can be used to detect latencies at run-time and trigger the capture of tracing snapshots to investigate further. As far as I know, it is the only solution that can compute the delay from an interrupt to user-space at run-time, and with a little help from user-space, it can continue following the processing in user-space. We did a presentation with Mathieu this year at LinuxCon, you can watch it here [4]. This project is also still in development in the master branch, but if you are interested in more details, let me know. We would like to have the same analysis in our offline analyses in lttng-analyses, but haven't had the time/funding for that yet. I hope this helps, let us know if you have more questions and if it solves the problem. Thanks, Julien [1] https://github.com/lttng/lttng-analyses#period-options [2] http://imgur.com/a/bZCgR [3] https://github.com/efficios/latency-tracker [4] https://www.youtube.com/watch?v=fTgD7sKoa_g ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] LTTng-UST and LTTng-modules filtering code relicensing to MIT license
On 28-Nov-2016 05:47:56 PM, Mathieu Desnoyers wrote: > Hi, > > I'm relicensing LTTng-UST and LTTng-modules filtering code to MIT > license in the master branch of the respective projects. It will > make it easier to integrate filtering capabilities into Babeltrace, > and exchange code between those projects filtering area in the > future. > > This affects the following files: > > LTTng-UST: > > LICENSE |4 ++-- > liblttng-ust/filter-bytecode.h | 27 --- > liblttng-ust/lttng-filter-interpreter.c | 28 > liblttng-ust/lttng-filter-specialize.c | 28 > liblttng-ust/lttng-filter-validator.c | 28 > liblttng-ust/lttng-filter.c | 28 > liblttng-ust/lttng-filter.h | 28 > 7 files changed, 98 insertions(+), 73 deletions(-) > > LTTng-modules: > > LICENSE|6 ++ > filter-bytecode.h | 27 --- > lttng-filter-interpreter.c | 28 > lttng-filter-specialize.c | 28 > lttng-filter-validator.c | 28 > lttng-filter.c | 28 > lttng-filter.h | 28 > 7 files changed, 102 insertions(+), 71 deletions(-) > > Thanks, > > Mathieu Acked-by: Julien Desfossez <jdesfos...@efficios.com> Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [video] Talk on trace aggregation + buffering, LinuxCon North America 2016
Hi, The talk we gave with Mathieu Desnoyers at LinuxCon Toronto 2016 is now available online. Latency Outliers Root Cause Analysis in the Field by Combining Aggregation and Tracing Tools https://www.youtube.com/watch?v=fTgD7sKoa_g Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [lttng-ust] [babeltrace] use case question - field names in event classes
On 12-Oct-2016 08:51:46 AM, Staffan Tjernstrom wrote: > > > > In the code, before calling the associated `two_ints_and_string` > > tracepoint, and only once: > > > > tracepoint(my_app, log_statement_field_names, 1, > >"widget_height", "widget_width", "widget_name", ""); > > > > Then: > > > > tracepoint(my_app, two_ints_and_string, 1, height, width, name); > > > > Then in your Python script you can register the dynamic field names > > when > > you get a `log_statement_field_names` event and use them when you get > > a > > "real" event (not tested): > > > > id_to_field_names = {} > > > > # open trace, etc. > > > > # some loop over the trace's events: > > if evt.name == 'log_statement_field_names': > > field_names = (evt['arg1'], evt['arg2'], evt['arg3'], > > evt['arg4']) > > id_to_field_names[evt['id']] = field_names > > elif evt.name == 'two_ints_and_string': > > field_names = id_to_field_names[evt['id']] > > print('{}: {}'.format(field_names[0], evt['value1'])) > > print('{}: {}'.format(field_names[1], evt['value2'])) > > print('{}: {}'.format(field_names[2], evt['value3'])) > > print() > > > > Now this is a great use case for future extensions of LTTng-UST and/or > > the upcoming CTF 2. > > > > Phil > > > Thanks - I hadn't thought of the Python bindings - I think we could > make that work (maybe wrapping the two tracepoint incantations into a > single macro definition). If you want some help generating the boiler plate Python code for parsing your trace, I recommend the parser_generator.py script from lttng-analyses: https://github.com/lttng/lttng-analyses/blob/master/parser_generator.py Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-modules] Add throughput test to LTTng
Hi, See comments below On 08-Sep-2016 01:27:42 PM, Mohamad Gebai wrote: > - Create the lttng-test subdirectory under /proc for testing purposes. > > - Create the procfs throughput file. Start a throughput test by writing > the number of iterations for the test. Read from this file to get the > result in nanoseconds. Note that the test automatically tries to reach > a steady state before benchmarking. > > Signed-off-by: Mohamad Gebai> --- > instrumentation/events/lttng-module/lttng-test.h | 8 ++ > tests/probes/lttng-test.c| 118 > +-- > 2 files changed, 116 insertions(+), 10 deletions(-) > > diff --git a/instrumentation/events/lttng-module/lttng-test.h > b/instrumentation/events/lttng-module/lttng-test.h > index 05d028c..54b4404 100644 > --- a/instrumentation/events/lttng-module/lttng-test.h > +++ b/instrumentation/events/lttng-module/lttng-test.h > @@ -48,6 +48,14 @@ LTTNG_TRACEPOINT_EVENT(lttng_test_filter_event, > ) > ) > > +LTTNG_TRACEPOINT_EVENT(lttng_test_throughput, > +TP_PROTO(int anint), > +TP_ARGS(anint), > +TP_FIELDS( > +ctf_integer(int, intfield, anint) > +) > +) > + > #endif /* LTTNG_TRACE_LTTNG_TEST_H */ > > /* This part must be outside protection */ > diff --git a/tests/probes/lttng-test.c b/tests/probes/lttng-test.c > index 54be4c7..dc59680 100644 > --- a/tests/probes/lttng-test.c > +++ b/tests/probes/lttng-test.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > #include > > #include > @@ -39,12 +40,18 @@ > #include > > DEFINE_TRACE(lttng_test_filter_event); > +DEFINE_TRACE(lttng_test_throughput); > > -#define LTTNG_TEST_FILTER_EVENT_FILE "lttng-test-filter-event" Note that a patch to update all the tests that use this file in lttng-tools will be needed if we change the path of lttng-test-filter-event. > +#define LTTNG_TEST_PROCFS_DIR "lttng-test" > +#define LTTNG_TEST_FILTER_EVENT_FILE"filter-event" > +/* Do a throughput benchmark by writing to this file the number of events. > + * Read the results in nanoseconds. */ > +#define LTTNG_TEST_THROUGHPUT_FILE "throughput" > > #define LTTNG_WRITE_COUNT_MAX64 > > -static struct proc_dir_entry *lttng_test_filter_event_dentry; > +static struct proc_dir_entry *lttng_test_dentry; > +static u64 latest_throughput_results = 0; > > static > void trace_test_event(unsigned int nr_iter) > @@ -60,6 +67,24 @@ void trace_test_event(unsigned int nr_iter) > } > } > > +static > +void lttng_throughput_test(unsigned int nr_iter) > +{ > + int i; > + ktime_t start_time, end_time; > + > + /* Warm up and get to a steady state */ > + for(i = 0; i < nr_iter / 2; i++) for (i =... > + trace_lttng_test_throughput(i); > + > + start_time = ktime_get(); Do we really want to use ktime_get() directly and not the trace_clock_read64 wrapper instead ? It might be easier to correlate the aggregated result from latest_throughput_results with the generated events list if they use the same clock. > + for(i = 0; i < nr_iter; i++) for (i =... > + trace_lttng_test_throughput(i); > + end_time = ktime_get(); > + > + latest_throughput_results = ktime_to_ns(end_time) - > ktime_to_ns(start_time); > +} > + > /** > * lttng_filter_event_write - trigger a lttng_test_filter_event > * @file: file pointer > @@ -90,10 +115,72 @@ end: > return written; > } > > +/** > + * lttng_throughput_test_write - trigger a lttng_throughput_test > + * @file: file pointer > + * @user_buf: user string > + * @count: length to copy > + * > + * Return -1 on error, with EFAULT errno. Returns count on success. > + */ > +static > +ssize_t lttng_throughput_test_write(struct file *file, > +const char __user *user_buf, > +size_t count, loff_t *ppos) > +{ > + unsigned int nr_iter; > + ssize_t written; > + int ret; > + > + /* Get the number of iterations */ > + ret = lttng_kstrtouint_from_user(user_buf, count, 10, _iter); > + if (ret) { > + written = ret; > + goto end; > + } > + /* Do throughput test */ > + lttng_throughput_test(nr_iter); > + written = count; > + *ppos += written; add new line here > +end: > +return written; > +} > + > +/** > + * lttng_throughput_test_read - read latest results of throughput test > + * @file: file pointer > + * @user_buf: user string > + * @count: length to copy > + * > + * Return -1 on error, with EFAULT errno. Returns count on success. > + */ > +static > +ssize_t lttng_throughput_test_read(struct file *file, char __user *user_buf, > + size_t count, loff_t *ppos) > +{ > + char buf[count]; > + ssize_t read_count = 0; > + > + if(latest_throughput_results == 0) if (latest_... > + goto end; > + > + read_count += snprintf(buf,
Re: [lttng-dev] [PATCH latency-tracker] Fix: use local ops for freelist per-cpu counter
Merged, thanks ! Julien On 23-Aug-2016 11:44:45 PM, Mathieu Desnoyers wrote: > Signed-off-by: Mathieu Desnoyers> --- > tracker_private.h | 3 ++- > wrapper/freelist-ll.h | 21 +++-- > 2 files changed, 17 insertions(+), 7 deletions(-) > > diff --git a/tracker_private.h b/tracker_private.h > index 03386b8..fc27f80 100644 > --- a/tracker_private.h > +++ b/tracker_private.h > @@ -7,6 +7,7 @@ > > #include > #include > +#include > > //#include "wrapper/ht.h" > //#include "rculfhash-internal.h" > @@ -18,7 +19,7 @@ struct numa_pool { > }; > > struct per_cpu_ll { > - int current_count; > + local_t current_count; > struct numa_pool *pool; > struct llist_head llist; > }; > diff --git a/wrapper/freelist-ll.h b/wrapper/freelist-ll.h > index 5e4d18e..44db722 100644 > --- a/wrapper/freelist-ll.h > +++ b/wrapper/freelist-ll.h > @@ -242,8 +242,8 @@ int free_per_cpu_llist(struct latency_tracker *tracker) > if (!list) > continue; > cnt = free_event_list(list); > - printk("freed %d on cpu %d (%d)\n", cnt, cpu, > - ll->current_count); > + printk("freed %d on cpu %d (%ld)\n", cnt, cpu, > + local_read(>current_count)); > total_cnt += cnt; > } > > @@ -284,10 +284,14 @@ struct llist_node *per_cpu_get(struct latency_tracker > *tracker) > struct per_cpu_ll *ll; > > ll = lttng_this_cpu_ptr(tracker->per_cpu_ll); > + /* > + * Decrement the current count after we successfully remove an > + * element from the list. > + */ > node = llist_del_first(>llist); > if (node) { > - ll->current_count--; > - WARN_ON_ONCE(ll->current_count < 0); > + local_dec(>current_count); > + WARN_ON_ONCE(local_read(>current_count) < 0); > return node; > } > return llist_del_first(>pool->llist); > @@ -336,12 +340,17 @@ void __wrapper_freelist_put_event(struct > latency_tracker *tracker, > if (e->pool != ll->pool) { > // printk("DEBUG cross-pool put_event\n"); > llist_add(>llist, >pool->llist); > - } else if (ll->current_count < FREELIST_PERCPU_CACHE) { > + } else if (local_read(>current_count) < FREELIST_PERCPU_CACHE) { > /* >* Fill our local cache if needed. > + * We need to increment current_count before we add the > + * element to the list, because when we successfully > + * remove an element from the list, we expect that the > + * counter is never negative. An interrupt can observe > + * the intermediate state. >*/ > + local_inc(>current_count); > llist_add(>llist, >llist); > - ll->current_count++; > } else { > /* >* Add to our NUMA pool. > -- > 2.1.4 > ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH latency-tracker] Fix: sizeof() bug, state tracking merge issue, PID 0
Merged, big thanks ! Julien On 23-Aug-2016 07:37:01 PM, Mathieu Desnoyers wrote: > - 3 sizeof() issues (using pointer size rather than object size), > - state tracking merge issue on switch in: the get following the > insertion may not get the same node when there are duplicates, > - also features a refactoring of keys: add a "p" parent field for the > type. > - PID 0 needs to be compared with its cpu ID too. > > Signed-off-by: Mathieu Desnoyers> --- > examples/rt.c | 164 > +++--- > latency_tracker.h | 7 +++ > tracker.c | 20 ++- > 3 files changed, 120 insertions(+), 71 deletions(-) > > diff --git a/examples/rt.c b/examples/rt.c > index f9703ca..7b3b2b3 100644 > --- a/examples/rt.c > +++ b/examples/rt.c > @@ -139,53 +139,59 @@ enum event_out_types { > OUT_NO_CB = 4, > }; > > +struct generic_key_t { > + enum rt_key_type type; > +} __attribute__((__packed__)); > + > struct do_irq_key_t { > + struct generic_key_t p; > unsigned int cpu; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct local_timer_key_t { > + struct generic_key_t p; > unsigned int cpu; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct hrtimer_key_t { > + struct generic_key_t p; > unsigned int cpu; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct hardirq_key_t { > + struct generic_key_t p; > unsigned int cpu; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct raise_softirq_key_t { > + struct generic_key_t p; > unsigned int cpu; > unsigned int vector; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct softirq_key_t { > + struct generic_key_t p; > unsigned int cpu; > int pid; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct waking_key_t { > + struct generic_key_t p; > + int cpu; > int pid; > - enum rt_key_type type; > } __attribute__((__packed__)); > > struct switch_key_t { > + struct generic_key_t p; > + int cpu; > int pid; > - enum rt_key_type type; > } __attribute__((__packed__)); > > #define MAX_COOKIE_SIZE 32 > struct work_begin_key_t { > + struct generic_key_t p; > char cookie[MAX_COOKIE_SIZE]; > int cookie_size; > - enum rt_key_type type; > } __attribute__((__packed__)); > > /* Keep up-to-date with a list of all key structs. */ > @@ -445,6 +451,7 @@ static > int entry_do_irq(struct kretprobe_instance *p, struct pt_regs *regs) > { > enum latency_tracker_event_in_ret ret; > + struct latency_tracker_event *s; > struct do_irq_key_t key; > u64 now; > > @@ -452,26 +459,20 @@ int entry_do_irq(struct kretprobe_instance *p, struct > pt_regs *regs) > return 0; > > now = trace_clock_monotonic_wrapper(); > + key.p.type = KEY_DO_IRQ; > key.cpu = smp_processor_id(); > - key.type = KEY_DO_IRQ; > - ret = _latency_tracker_event_in(tracker, , sizeof(key), 1, now, > - NULL); > + ret = _latency_tracker_event_in_get(tracker, , sizeof(key), 1, now, > + NULL, ); > if (ret != LATENCY_TRACKER_OK) { > failed_event_in++; > return 0; > } > + WARN_ON_ONCE(!s); > > if (config.text_breakdown) { > - struct latency_tracker_event *s; > - > - s = latency_tracker_get_event(tracker, , sizeof(key)); > - if (!s) { > - BUG_ON(1); > - return 0; > - } > append_delta_ts(s, KEY_DO_IRQ, "do_IRQ", now, 0, NULL, 0); > - latency_tracker_put_event(s); > } > + latency_tracker_put_event(s); > > #ifdef DEBUG > printk("%llu do_IRQ (cpu %u)\n", trace_clock_monotonic_wrapper(), > @@ -488,8 +489,8 @@ int exit_do_irq(struct kretprobe_instance *p, struct > pt_regs *regs) > > if (!config.irq_tracing) > return 0; > + key.p.type = KEY_DO_IRQ; > key.cpu = smp_processor_id(); > - key.type = KEY_DO_IRQ; > latency_tracker_event_out(tracker, , > sizeof(key), OUT_IRQHANDLER_NO_CB, 0); > > @@ -618,15 +619,13 @@ struct latency_tracker_event *event_transition(void > *key_in, int key_in_len, > } > orig_ts = latency_tracker_event_get_start_ts(event_in); > > - ret = _latency_tracker_event_in(tracker, key_out, > - key_out_len, unique, orig_ts, NULL); > + ret = _latency_tracker_event_in_get(tracker, key_out, > + key_out_len, unique, orig_ts, NULL, _out); > if (ret != LATENCY_TRACKER_OK) { > - goto end_del; > failed_event_in++; > - } > - event_out = latency_tracker_get_event(tracker, key_out, key_out_len); > - if
Re: [lttng-dev] [PATCH lttng-tools v3 3/3] Create a dedicated test suite for Perf
> >> have_libpfm should be used to set an automake variable and enable the test > >> conditionally. Similar to what is done here: > >> > >> https://github.com/lttng/lttng-tools/blob/master/tests/regression/Makefile.am#L44 > > > > Hum, the intent here is to make the tests fail if the dependency is not > > available, but we do not want to enforce it as a dependency since most > > deployments cannot run these tests. What we want here if for the test to > > fail if a user tries to run it without the dependency installed, then > > they will install the dependency and run it again. Having a transparent > > way to disable these tests would render them useless because we will > > think they passed. > > Agreed to not include them in the standard test suite. However, the > test should be skipped if the dependency is not found on the system, > along with a message explaining why. > > Currently the test will fail with the following output if run without > libpfm4 installed on the system. > > $ ./tests/perf/test_perf_raw > 1..20 > # Perf counters > ok 1 - Start session daemon > ./tests/perf/test_perf_raw: line 50: ./tests/perf//find_event: No such > file or directory > not ok 2 - Find PMU UNHALTED_REFERENCE_CYCLES [...] > > This does't make it obvious why the test is failing. > > > > > There may be a better way of doing it, but we should avoid using magical > > "skip" in this case, these tests should fail if the target architecture > > does not support all the Perf-related features we support. > > I want to make it clear to the user that the test is failing because > of a missing dependency, and not because his HW doesn't have the > capabilities needed. > > Skip with a clear error message seems appropriate here, especially > since the test will not be run automatically. How about having a first step in the test that checks if the dependency is present and fails if not ? This would make it clear that the dependency is needed to run the test, and it would not magically pass if run in the background or in batch. I am really worried that skipping here will confuse users, I see this test suite as a way to guarantee that perf-related features all work on their system if the test returns 0 at the end. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools v3 3/3] Create a dedicated test suite for Perf
On 16-07-08 03:56 PM, Jérémie Galarneau wrote: > The first two patches look good to me. See comments on this one below > (and your own reply). > > On Tue, Jul 5, 2016 at 11:50 AM, Julien Desfossez > <jdesfos...@efficios.com> wrote: >> Introduce the perf_regression test suite that must be run manually to >> check if the support for the Perf-related features are available on the >> current machine. This test cannot be run automatically since there are >> some platforms where it can fail. > > Is this still true given lttng-ust's new "read()" fallback? Yes, the test tries to enable a raw context and it depends on the hardware (which CPU, SoC, etc), so there are many places where it can fail, including in VM in the CI. >> For now, the test only makes sure that we can trace events with perf >> contexts enabled by raw ID in kernel and user-space. The test only works >> if libpfm is installed on the system and fails if it is not installed. >> >> Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> >> --- >> .gitignore | 1 + >> README.md| 2 + >> configure.ac | 8 +++ >> tests/Makefile.am| 8 +-- >> tests/perf/Makefile.am | 6 +++ >> tests/perf/find_event.c | 83 ++ >> tests/perf/test_perf_raw | 129 >> +++ >> tests/perf_regression| 1 + >> 8 files changed, 234 insertions(+), 4 deletions(-) >> create mode 100644 tests/perf/Makefile.am >> create mode 100644 tests/perf/find_event.c >> create mode 100755 tests/perf/test_perf_raw >> create mode 100644 tests/perf_regression >> >> diff --git a/.gitignore b/.gitignore >> index ac78292..c31dbc5 100644 >> --- a/.gitignore >> +++ b/.gitignore >> @@ -106,6 +106,7 @@ tests/regression/ust/python-logging/test_python_logging >> /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef >> /tests/regression/tools/live/live_test >> /tests/unit/ini_config/ini_config >> +/tests/perf/find_event >> >> # man pages >> /doc/man/*.1 >> diff --git a/README.md b/README.md >> index 22de252..3156a15 100644 >> --- a/README.md >> +++ b/README.md >> @@ -57,6 +57,8 @@ The following items are _optional_ dependencies: >> pages with the `--help` option or with the `lttng help` command. >> Note that without `man`, you cannot get offline help with >> LTTng-tools commands, not even their usage. >> + - **`libpfm`**: needed to run the perf regression test suite. >> +- Debian/Ubuntu package: `libpfm4-dev` > > Which version is required? > >> >> LTTng-tools supports both the [LTTng Linux Kernel tracer](https://lttng.org) >> and [LTTng user space tracer](https://lttng.org) released as part of the >> same >> diff --git a/configure.ac b/configure.ac >> index fb2b013..f96d25b 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -467,6 +467,13 @@ AC_CHECK_LIB([c], [open_memstream], >> ] >> ) >> >> +# check for libpfm >> +AC_CHECK_LIB([pfm], [pfm_initialize], >> +[ >> + have_libpfm=yes >> + ]) >> +AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBPFM], [test "x$have_libpfm" = >> "xyes"]) >> + >> AC_ARG_ENABLE([git-version], >>[AC_HELP_STRING([--disable-git-version], >>[Do not use the git version for the build])], >> @@ -1008,6 +1015,7 @@ AC_CONFIG_FILES([ >> tests/stress/Makefile >> tests/unit/Makefile >> tests/unit/ini_config/Makefile >> + tests/perf/Makefile > > have_libpfm should be used to set an automake variable and enable the test > conditionally. Similar to what is done here: > > https://github.com/lttng/lttng-tools/blob/master/tests/regression/Makefile.am#L44 Hum, the intent here is to make the tests fail if the dependency is not available, but we do not want to enforce it as a dependency since most deployments cannot run these tests. What we want here if for the test to fail if a user tries to run it without the dependency installed, then they will install the dependency and run it again. Having a transparent way to disable these tests would render them useless because we will think they passed. There may be a better way of doing it, but we should avoid using magical "skip" in this case, these tests should fail if the target architecture does not support all the Perf-related features we support. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-tools v3 3/3] Create a dedicated test suite for Perf
> diff --git a/tests/perf/find_event.c b/tests/perf/find_event.c > new file mode 100644 > index 000..ae63800 > --- /dev/null > +++ b/tests/perf/find_event.c > @@ -0,0 +1,83 @@ > +/* > + * Copyright (c) 2016 Julien Desfossez <jdesfos...@efficios.com> > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * as published by the Free Software Foundation; only version 2 > + * of the License. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include > +#include > +#include > + > +int main(int argc, char **argv) > +{ > + int ret, i; > + unsigned int j; > + pfm_pmu_info_t pinfo; > + > + if (argc != 2) { > + fprintf(stderr, "Usage: %s \n" > + "ex: %s UNHALTED_REFERENCE_CYCLES\n" > + "Returns the first occurence it finds with " > + "return code 0.\n" > + "If not found returns 1, on error returns -1\n", > + argv[0], argv[0]); > + ret = -1; > + goto end; > + } > + > + memset(, 0, sizeof(pinfo)); > + pinfo.size = sizeof(pinfo); > + > + ret = pfm_initialize(); > + if (ret != PFM_SUCCESS) { > + fprintf(stderr, "Failed to initialise libpfm: %s", > + pfm_strerror(ret)); > + ret = -1; > + goto end; > + } > + > + pfm_for_all_pmus(j) { > + ret = pfm_get_pmu_info(j, ); > + if (ret != PFM_SUCCESS) { > + continue; > + } > + > + for (i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) > { > + pfm_event_info_t info; > + > + ret = pfm_get_event_info(i, PFM_OS_NONE, ); > + if (ret != PFM_SUCCESS) { > + fprintf(stderr, "Cannot get event info: %s\n", > + pfm_strerror(ret)); > + ret = -1; > + goto end; > + } > + > + if (info.pmu != j) > + continue; > + > + if (strcmp(info.name, argv[1]) == 0) { > + fprintf(stdout, "r%lx\n", info.code); This should be: fprintf(stdout, "r%" PRIx64 "\n", info.code); I will wait for other comments if any before resubmitting a new version (or you can directly apply the fix when you merge). Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v3 2/3] Test the parsing of perf raw context
Only test the parsing of the new option in fast_regression since the real integration test requires particular hardware and kernel configuration which might not be available. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/fast_regression| 1 + tests/regression/ust/test_event_perf | 47 ++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/tests/fast_regression b/tests/fast_regression index 0c4f079..ab5521f 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -30,3 +30,4 @@ regression/ust/clock-override/test_clock_override regression/ust/rotation-destroy-flush/test_rotation_destroy_flush regression/ust/test_event_basic regression/ust/test_event_tracef +regression/ust/test_event_perf diff --git a/tests/regression/ust/test_event_perf b/tests/regression/ust/test_event_perf index 7dc2168..133dafa 100755 --- a/tests/regression/ust/test_event_perf +++ b/tests/regression/ust/test_event_perf @@ -23,7 +23,7 @@ TESTDIR=$CURDIR/../.. LTTNG_BIN="lttng" SESSION_NAME="perf_counters" EVENT_NAME="tp:tptest" -NUM_TESTS=10 +NUM_TESTS=24 NR_ITER=1 NR_USEC_WAIT=1 TESTAPP_PATH="$TESTDIR/utils/testapp" @@ -42,14 +42,33 @@ function enable_ust_lttng_event_per_chan() ok $? "Enable event $event_name for session $sess_name in channel $chan_name" } -function add_ust_lttng_context() +# Only test parsing of the enabling by raw ID +function test_parsing_raw() { - sess_name="$1" - chan_name="$2" - type="$3" + TRACE_PATH=$(mktemp -d) + SESSION_NAME="ust_event_basic" + CHAN_NAME="mychan" + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + enable_ust_lttng_channel_ok $SESSION_NAME $CHAN_NAME + + enable_ust_lttng_event_per_chan $SESSION_NAME $EVENT_NAME $CHAN_NAME - $TESTDIR/../src/bin/lttng/$LTTNG_BIN add-context -s $sess_name -c $chan_name -t $type -u >/dev/null 2>&1 - ok $? "Add context $type for session $sess_name in channel $chan_name" + add_context_ust_ok $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:test" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:rZZZ:test" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:b0110:test" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110::" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r:test" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r::" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw::" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw" + add_context_ust_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:test:wrong" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH } function test_event_basic() @@ -64,7 +83,7 @@ function test_event_basic() enable_ust_lttng_event_per_chan $SESSION_NAME $EVENT_NAME $CHAN_NAME - add_ust_lttng_context $SESSION_NAME $CHAN_NAME "perf:thread:page-fault" + add_context_ust_ok $SESSION_NAME $CHAN_NAME "perf:thread:page-fault" start_lttng_tracing_ok @@ -96,11 +115,13 @@ else isroot=0 fi -skip $isroot "Root access is needed. Skipping UST perf tests." ${NUM_TESTS} || -{ - start_lttng_sessiond +start_lttng_sessiond - test_event_basic +test_parsing_raw - stop_lttng_sessiond +skip $isroot "Root access is needed. Skipping UST perf tests." 8 || +{ + test_event_basic } + +stop_lttng_sessiond -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v3 3/3] Create a dedicated test suite for Perf
Introduce the perf_regression test suite that must be run manually to check if the support for the Perf-related features are available on the current machine. This test cannot be run automatically since there are some platforms where it can fail. For now, the test only makes sure that we can trace events with perf contexts enabled by raw ID in kernel and user-space. The test only works if libpfm is installed on the system and fails if it is not installed. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .gitignore | 1 + README.md| 2 + configure.ac | 8 +++ tests/Makefile.am| 8 +-- tests/perf/Makefile.am | 6 +++ tests/perf/find_event.c | 83 ++ tests/perf/test_perf_raw | 129 +++ tests/perf_regression| 1 + 8 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 tests/perf/Makefile.am create mode 100644 tests/perf/find_event.c create mode 100755 tests/perf/test_perf_raw create mode 100644 tests/perf_regression diff --git a/.gitignore b/.gitignore index ac78292..c31dbc5 100644 --- a/.gitignore +++ b/.gitignore @@ -106,6 +106,7 @@ tests/regression/ust/python-logging/test_python_logging /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef /tests/regression/tools/live/live_test /tests/unit/ini_config/ini_config +/tests/perf/find_event # man pages /doc/man/*.1 diff --git a/README.md b/README.md index 22de252..3156a15 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ The following items are _optional_ dependencies: pages with the `--help` option or with the `lttng help` command. Note that without `man`, you cannot get offline help with LTTng-tools commands, not even their usage. + - **`libpfm`**: needed to run the perf regression test suite. +- Debian/Ubuntu package: `libpfm4-dev` LTTng-tools supports both the [LTTng Linux Kernel tracer](https://lttng.org) and [LTTng user space tracer](https://lttng.org) released as part of the same diff --git a/configure.ac b/configure.ac index fb2b013..f96d25b 100644 --- a/configure.ac +++ b/configure.ac @@ -467,6 +467,13 @@ AC_CHECK_LIB([c], [open_memstream], ] ) +# check for libpfm +AC_CHECK_LIB([pfm], [pfm_initialize], +[ + have_libpfm=yes + ]) +AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBPFM], [test "x$have_libpfm" = "xyes"]) + AC_ARG_ENABLE([git-version], [AC_HELP_STRING([--disable-git-version], [Do not use the git version for the build])], @@ -1008,6 +1015,7 @@ AC_CONFIG_FILES([ tests/stress/Makefile tests/unit/Makefile tests/unit/ini_config/Makefile + tests/perf/Makefile tests/utils/Makefile tests/utils/tap/Makefile tests/utils/testapp/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index 3600e99..d460fb6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,8 +1,8 @@ SUBDIRS = -DIST_SUBDIRS = utils regression unit stress destructive +DIST_SUBDIRS = utils regression unit stress destructive perf if BUILD_TESTS -SUBDIRS += . utils regression unit stress destructive +SUBDIRS += . utils regression unit stress destructive perf if HAS_PGREP check-am: $(top_srcdir)/tests/utils/warn_processes.sh $(PGREP) @@ -14,8 +14,8 @@ else endif -dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests -EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests +dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests perf_regression +EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests perf_regression all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/perf/Makefile.am b/tests/perf/Makefile.am new file mode 100644 index 000..40bb754 --- /dev/null +++ b/tests/perf/Makefile.am @@ -0,0 +1,6 @@ +if LTTNG_TOOLS_BUILD_WITH_LIBPFM +LIBS += -lpfm + +noinst_PROGRAMS = find_event +find_event_SOURCES = find_event.c +endif diff --git a/tests/perf/find_event.c b/tests/perf/find_event.c new file mode 100644 index 000..ae63800 --- /dev/null +++ b/tests/perf/find_event.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Julien Desfossez <jdesfos...@efficios.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You s
[lttng-dev] [PATCH lttng-tools v3 5/6] Tests for the regenerate statedump command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> Reviewed-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> --- configure.ac | 1 + tests/fast_regression | 1 + tests/regression/tools/Makefile.am | 2 +- tests/regression/tools/regen-statedump/Makefile.am | 16 tests/regression/tools/regen-statedump/test_kernel | 80 +++ tests/regression/tools/regen-statedump/test_ust| 89 ++ tests/root_regression | 1 + tests/utils/utils.sh | 54 + 8 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 tests/regression/tools/regen-statedump/Makefile.am create mode 100755 tests/regression/tools/regen-statedump/test_kernel create mode 100755 tests/regression/tools/regen-statedump/test_ust diff --git a/configure.ac b/configure.ac index 89a7858..6222e2b 100644 --- a/configure.ac +++ b/configure.ac @@ -981,6 +981,7 @@ AC_CONFIG_FILES([ tests/regression/tools/wildcard/Makefile tests/regression/tools/crash/Makefile tests/regression/tools/regen-metadata/Makefile + tests/regression/tools/regen-statedump/Makefile tests/regression/ust/Makefile tests/regression/ust/nprocesses/Makefile tests/regression/ust/high-throughput/Makefile diff --git a/tests/fast_regression b/tests/fast_regression index 262c846..8edbeca 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -17,6 +17,7 @@ regression/tools/mi/test_mi regression/tools/wildcard/test_event_wildcard regression/tools/crash/test_crash regression/tools/regen-metadata/test_ust +regression/tools/regen-statedump/test_ust regression/ust/before-after/test_before_after regression/ust/buffers-pid/test_buffers_pid regression/ust/multi-session/test_multi_session diff --git a/tests/regression/tools/Makefile.am b/tests/regression/tools/Makefile.am index 91820ad..76374c7 100644 --- a/tests/regression/tools/Makefile.am +++ b/tests/regression/tools/Makefile.am @@ -1,2 +1,2 @@ SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load mi \ - wildcard crash regen-metadata + wildcard crash regen-metadata regen-statedump diff --git a/tests/regression/tools/regen-statedump/Makefile.am b/tests/regression/tools/regen-statedump/Makefile.am new file mode 100644 index 000..d4a92eb --- /dev/null +++ b/tests/regression/tools/regen-statedump/Makefile.am @@ -0,0 +1,16 @@ +noinst_SCRIPTS = test_ust test_kernel +EXTRA_DIST = test_ust test_kernel + +all-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + cp -f $(srcdir)/$$script $(builddir); \ + done; \ + fi + +clean-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + rm -f $(builddir)/$$script; \ + done; \ + fi diff --git a/tests/regression/tools/regen-statedump/test_kernel b/tests/regression/tools/regen-statedump/test_kernel new file mode 100755 index 000..85afe76 --- /dev/null +++ b/tests/regression/tools/regen-statedump/test_kernel @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Copyright (C) - 2016 Julien Desfossez <jdesfos...@efficios.com> +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; 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 +TEST_DESC="Regenerate the statedump - Kernel tracing" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../../.. +EVENT_NAME="lttng_test_filter_event" +PID_RELAYD=0 +SESSION_NAME="" +EVENT_NAME="lttng_statedump_start,lttng_statedump_end" + +TRACE_PATH=$(mktemp -d) + +NUM_TESTS=11 + +source $TESTDIR/utils/utils.sh + +# LTTng kernel modules check +out=`ls /lib/modules/$(uname -r)/extra | grep lttng` +if [ -z "$out" ]; then + BAIL_OUT "LTTng modules not detected." +fi + +function test_kernel_local () +{ + diag "Test kernel local with statedump regeneration" + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + lttng_enable_kernel_event $SESSION_NAME $EVENT_NAME + start_lttng_tracing_ok $SESSION_NAME + echo -n
[lttng-dev] [PATCH lttng-tools v3 1/6] Rename the "metadata regenerate" command to "regenerate metadata"
Prepare the deprecation of the "metadata regenerate" command since we need to regenerate the statedump as well, so it is more convenient to have one command to regenerate various session's attributes. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 2 +- doc/man/Makefile.am | 3 +- doc/man/lttng-metadata.1.txt | 17 +- doc/man/lttng-regenerate.1.txt| 63 + include/lttng/lttng.h | 8 +- src/bin/lttng-sessiond/cmd.c | 15 +- src/bin/lttng-sessiond/cmd.h | 2 +- src/bin/lttng-sessiond/main.c | 6 +- src/bin/lttng/Makefile.am | 1 + src/bin/lttng/command.h | 1 + src/bin/lttng/commands/metadata.c | 2 +- src/bin/lttng/commands/regenerate.c | 266 ++ src/bin/lttng/lttng.c | 1 + src/common/kernel-ctl/kernel-ctl.c| 2 +- src/common/kernel-ctl/kernel-ctl.h| 2 +- src/common/mi-lttng.c | 2 + src/common/mi-lttng.h | 2 + src/common/sessiond-comm/sessiond-comm.h | 4 +- src/lib/lttng-ctl/lttng-ctl.c | 12 +- tests/destructive/metadata-regeneration | 8 +- tests/fast_regression | 2 +- tests/regression/Makefile.am | 2 +- tests/regression/tools/Makefile.am| 2 +- tests/regression/tools/metadata-regen/Makefile.am | 16 -- tests/regression/tools/metadata-regen/test_kernel | 109 - tests/regression/tools/metadata-regen/test_ust| 208 - tests/regression/tools/mi/test_mi | 4 +- tests/regression/tools/regen-metadata/Makefile.am | 16 ++ tests/regression/tools/regen-metadata/test_kernel | 109 + tests/regression/tools/regen-metadata/test_ust| 208 + tests/root_regression | 2 +- tests/utils/utils.sh | 14 +- 32 files changed, 724 insertions(+), 387 deletions(-) create mode 100644 doc/man/lttng-regenerate.1.txt create mode 100644 src/bin/lttng/commands/regenerate.c delete mode 100644 tests/regression/tools/metadata-regen/Makefile.am delete mode 100755 tests/regression/tools/metadata-regen/test_kernel delete mode 100755 tests/regression/tools/metadata-regen/test_ust create mode 100644 tests/regression/tools/regen-metadata/Makefile.am create mode 100755 tests/regression/tools/regen-metadata/test_kernel create mode 100755 tests/regression/tools/regen-metadata/test_ust diff --git a/configure.ac b/configure.ac index fb2b013..89a7858 100644 --- a/configure.ac +++ b/configure.ac @@ -980,7 +980,7 @@ AC_CONFIG_FILES([ tests/regression/tools/mi/Makefile tests/regression/tools/wildcard/Makefile tests/regression/tools/crash/Makefile - tests/regression/tools/metadata-regen/Makefile + tests/regression/tools/regen-metadata/Makefile tests/regression/ust/Makefile tests/regression/ust/nprocesses/Makefile tests/regression/ust/high-throughput/Makefile diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 1090f1a..f75db6e 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -30,7 +30,8 @@ MAN1_NAMES = \ lttng-enable-event \ lttng-disable-event \ lttng-crash \ - lttng-metadata + lttng-metadata \ + lttng-regenerate MAN3_NAMES = MAN8_NAMES = lttng-sessiond lttng-relayd MAN1_NO_ASCIIDOC_NAMES = diff --git a/doc/man/lttng-metadata.1.txt b/doc/man/lttng-metadata.1.txt index 0fa240e..5348916 100644 --- a/doc/man/lttng-metadata.1.txt +++ b/doc/man/lttng-metadata.1.txt @@ -15,21 +15,8 @@ SYNOPSIS DESCRIPTION --- -The `lttng metadata` command manages a tracing session's metadata -generation options. - -As of this version, only the `regenerate` command's action is available. -Regenerating a tracing session's metadata can be used to -resample the offset between the system's monotonic clock and -the wall-clock time. - -This command is meant to be used to resample the wall-clock time -following a major -link:https://en.wikipedia.org/wiki/Network_Time_Protocol[NTP] -correction. As such, a system booting with an incorrect wall time can be -traced before its wall time is NTP-corrected. Regenerating the tracing -session's metadata ensures that trace viewers can accurately determine -the events time relative to Unix Epoch. +WARNING: This command is **deprecated**; it has been replaced by the *lttng +regenerate metadata* command (see man:lttng-regenerate(1)). include::common-cmd-options-head.txt[] diff --git a/doc/man/lttng-regenerate.1.txt b/doc/man/lttng-regenerate.1.txt new file m
[lttng-dev] [PATCH lttng-tools v3 4/6] Allow regenerating the statedump of a running session
The "lttng regenerate statedump" command can be used to regenerate the statedump of a running session whenever needed. This is particularly useful in snapshot and trace-file rotation modes where the original statedump may be lost. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- include/lttng/lttng-error.h | 2 + include/lttng/lttng.h| 9 + src/bin/lttng-sessiond/cmd.c | 55 ++ src/bin/lttng-sessiond/cmd.h | 1 + src/bin/lttng-sessiond/main.c| 6 +++ src/bin/lttng-sessiond/ust-app.c | 66 src/bin/lttng-sessiond/ust-app.h | 6 +++ src/bin/lttng/commands/regenerate.c | 19 + src/common/error.c | 2 + src/common/kernel-ctl/kernel-ctl.c | 5 +++ src/common/kernel-ctl/kernel-ctl.h | 1 + src/common/sessiond-comm/sessiond-comm.h | 1 + src/lib/lttng-ctl/lttng-ctl.c| 30 +++ 13 files changed, 203 insertions(+) diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h index 72194ef..df59f8f 100644 --- a/include/lttng/lttng-error.h +++ b/include/lttng/lttng-error.h @@ -142,6 +142,8 @@ enum lttng_error_code { LTTNG_ERR_LIVE_SESSION = 119, /* Live session unsupported */ LTTNG_ERR_PER_PID_SESSION= 120, /* Per-PID sessions unsupported */ LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE = 121, /* Context unavailable on this kernel */ + LTTNG_ERR_REGEN_STATEDUMP_FAIL = 122, /* Failed to regenerate the state dump */ + LTTNG_ERR_REGEN_STATEDUMP_NOMEM = 123, /* Failed to regenerate the state dump, not enough memory */ /* MUST be last element */ LTTNG_ERR_NR, /* Last element */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 09aa969..d37d6c0 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -173,6 +173,15 @@ extern int lttng_metadata_regenerate(const char *session_name); */ extern int lttng_regenerate_metadata(const char *session_name); +/* + * Trigger the regeneration of the statedump for a session. The new statedump + * information is appended to the currently active trace, the session needs to + * be active. + * + * Return 0 on success, a negative LTTng error code on error. + */ +extern int lttng_regenerate_statedump(const char *session_name); + #ifdef __cplusplus } #endif diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index bd63389..a57afe2 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -3540,6 +3540,61 @@ end: } /* + * Command LTTNG_REGENERATE_STATEDUMP from the lttng-ctl library. + * + * Ask the tracer to regenerate a new statedump. + * + * Return 0 on success or else a LTTNG_ERR code. + */ +int cmd_regenerate_statedump(struct ltt_session *session) +{ + int ret; + + assert(session); + + if (!session->active) { + ret = LTTNG_ERR_SESSION_NOT_STARTED; + goto end; + } + ret = 0; + + if (session->kernel_session) { + ret = kernctl_session_regenerate_statedump( + session->kernel_session->fd); + /* +* Currently, the statedump in kernel can only fail if out +* of memory. +*/ + if (ret < 0) { + if (ret == -ENOMEM) { + ret = LTTNG_ERR_REGEN_STATEDUMP_NOMEM; + } else { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + } + ERR("Failed to regenerate the kernel statedump"); + goto end; + } + } + + if (session->ust_session) { + ret = ust_app_regenerate_statedump_all(session->ust_session); + /* +* Currently, the statedump in UST always returns 0. +*/ + if (ret < 0) { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + ERR("Failed to regenerate the UST statedump"); + goto end; + } + } + DBG("Cmd regenerate statedump for session %s", session->name); + ret = LTTNG_OK; + +end: + return ret; +} + +/* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination. * diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 320d717..975a7f1 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -111,5 +111,6 @@ int cmd_snapshot_record(struct ltt_session *session, int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path); int cmd_regene
[lttng-dev] [PATCH lttng-tools v3 2/6] UST command to regenerate the statedump
From: Mathieu DesnoyersSigned-off-by: Mathieu Desnoyers --- src/bin/lttng-sessiond/lttng-ust-abi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/lttng-sessiond/lttng-ust-abi.h b/src/bin/lttng-sessiond/lttng-ust-abi.h index 7bec0c9..9ef7b9a 100644 --- a/src/bin/lttng-sessiond/lttng-ust-abi.h +++ b/src/bin/lttng-sessiond/lttng-ust-abi.h @@ -275,6 +275,7 @@ struct lttng_ust_event_exclusion { _UST_CMDW(0x51, struct lttng_ust_channel) #define LTTNG_UST_SESSION_START_UST_CMD(0x52) #define LTTNG_UST_SESSION_STOP _UST_CMD(0x53) +#define LTTNG_UST_SESSION_STATEDUMP_UST_CMD(0x54) /* Channel FD commands */ #define LTTNG_UST_STREAM _UST_CMD(0x60) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v3 6/6] Manpage for the regenerate statedump command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- doc/man/lttng-regenerate.1.txt | 46 -- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/doc/man/lttng-regenerate.1.txt b/doc/man/lttng-regenerate.1.txt index dbbfa4d..a3af401 100644 --- a/doc/man/lttng-regenerate.1.txt +++ b/doc/man/lttng-regenerate.1.txt @@ -9,35 +9,51 @@ lttng-regenerate - Manage an LTTng tracing session's data regeneration SYNOPSIS -Regenerate the metadata of a session +Regenerate the metadata of a session: [verse] *lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate metadata* [option:--session='SESSION'] +Regenerate the state dump of a session: + +[verse] +*lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate statedump* [option:--session='SESSION'] + DESCRIPTION --- -The `lttng regenerate` command manages a tracing session's data regeneration -options. +The `lttng regenerate` command regenerates specific data of a tracing session. + +As of this version, the `metadata` and `statedump` actions are +available. + + +Regenerating a tracing session's metadata +~ +The `lttng regenerate metadata` action can be used to resample the offset +between the system's monotonic clock and the wall-clock time. + +This action is meant to be used to resample the wall-clock time following a +major link:https://en.wikipedia.org/wiki/Network_Time_Protocol[NTP] correction. +As such, a system booting with an incorrect wall time can be traced before its +wall time is NTP-corrected. Regenerating the tracing session's metadata ensures +that trace viewers can accurately determine the events time relative to Unix +Epoch. -As of this version, only the `metadata` command's action is available. -Regenerating a tracing session's metadata can be used to -resample the offset between the system's monotonic clock and -the wall-clock time. -This command is meant to be used to resample the wall-clock time -following a major -link:https://en.wikipedia.org/wiki/Network_Time_Protocol[NTP] -correction. As such, a system booting with an incorrect wall time can be -traced before its wall time is NTP-corrected. Regenerating the tracing -session's metadata ensures that trace viewers can accurately determine -the events time relative to Unix Epoch. +Regenerating a tracing session's state dump +~~~ +The `lttng regenerate statedump` action can be used to collect up-to-date state +dump information during the tracing session. This is particularly useful in +snapshot (see man:lttng-snapshot(1)) or trace file rotation (see +man:lttng-enable-channel(1)) modes where the state dump information may be +lost. include::common-cmd-options-head.txt[] option:-s, option:--session='SESSION':: -Manage the metadata generation of the tracing session named 'SESSION' +Regenerate the data of the tracing session named 'SESSION' instead of the current tracing session. -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2 3/6] Kernel ioctl to regenerate the statedump
From: Mathieu DesnoyersSigned-off-by: Mathieu Desnoyers --- src/common/kernel-ctl/kernel-ioctl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index 68056dc..805de02 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -134,6 +134,8 @@ */ #define LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS _IO(0xF6, 0x58) #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) /* Channel FD ioctl */ #define LTTNG_KERNEL_STREAM_IO(0xF6, 0x62) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2 6/6] Manpage for the regenerate statedump command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> Reviewed-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> --- doc/man/lttng-regenerate.1.txt | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/man/lttng-regenerate.1.txt b/doc/man/lttng-regenerate.1.txt index dbbfa4d..80bae20 100644 --- a/doc/man/lttng-regenerate.1.txt +++ b/doc/man/lttng-regenerate.1.txt @@ -14,12 +14,19 @@ Regenerate the metadata of a session [verse] *lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate metadata* [option:--session='SESSION'] +Regenerate the statedump of a session + +[verse] +*lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate statedump* [option:--session='SESSION'] + DESCRIPTION --- The `lttng regenerate` command manages a tracing session's data regeneration options. -As of this version, only the `metadata` command's action is available. +As of this version, the `metadata` and `statedump` command's action are +available. + Regenerating a tracing session's metadata can be used to resample the offset between the system's monotonic clock and the wall-clock time. @@ -32,12 +39,16 @@ traced before its wall time is NTP-corrected. Regenerating the tracing session's metadata ensures that trace viewers can accurately determine the events time relative to Unix Epoch. +Regenerating a tracing session's statedump can be used to collect up-to-date +statedump informations during the trace session. This is particularly useful in +snapshot or trace-file rotation modes where the statedump information may be +lost. include::common-cmd-options-head.txt[] option:-s, option:--session='SESSION':: -Manage the metadata generation of the tracing session named 'SESSION' +Manage the data regeneration of the tracing session named 'SESSION' instead of the current tracing session. -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2 4/6] Allow regenerating the statedump of a running session
The "lttng regenerate statedump" command can be used to regenerate the statedump of a running session whenever needed. This is particularly useful in snapshot and trace-file rotation modes where the original statedump may be lost. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- include/lttng/lttng-error.h | 1 + include/lttng/lttng.h| 9 + src/bin/lttng-sessiond/cmd.c | 44 + src/bin/lttng-sessiond/cmd.h | 1 + src/bin/lttng-sessiond/main.c| 6 +++ src/bin/lttng-sessiond/ust-app.c | 66 src/bin/lttng-sessiond/ust-app.h | 6 +++ src/bin/lttng/commands/regenerate.c | 19 + src/common/error.c | 1 + src/common/kernel-ctl/kernel-ctl.c | 5 +++ src/common/kernel-ctl/kernel-ctl.h | 1 + src/common/sessiond-comm/sessiond-comm.h | 1 + src/lib/lttng-ctl/lttng-ctl.c| 30 +++ 13 files changed, 190 insertions(+) diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h index 72194ef..52ce333 100644 --- a/include/lttng/lttng-error.h +++ b/include/lttng/lttng-error.h @@ -142,6 +142,7 @@ enum lttng_error_code { LTTNG_ERR_LIVE_SESSION = 119, /* Live session unsupported */ LTTNG_ERR_PER_PID_SESSION= 120, /* Per-PID sessions unsupported */ LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE = 121, /* Context unavailable on this kernel */ + LTTNG_ERR_REGEN_STATEDUMP_FAIL = 122, /* Failed to regenerate the statdump */ /* MUST be last element */ LTTNG_ERR_NR, /* Last element */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 09aa969..b81a01c 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -173,6 +173,15 @@ extern int lttng_metadata_regenerate(const char *session_name); */ extern int lttng_regenerate_metadata(const char *session_name); +/* + * Trigger the regeneration of the statedump for a session. The new statedump + * information is appended to the currently active trace, the session needs to + * be started. + * + * Return 0 on success, a negative LTTng error code on error. + */ +extern int lttng_regenerate_statedump(const char *session_name); + #ifdef __cplusplus } #endif diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index bd63389..480333d 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -3540,6 +3540,50 @@ end: } /* + * Command LTTNG_REGENERATE_STATEDUMP from the lttng-ctl library. + * + * Ask the tracer to regenerate a new statedump. + * + * Return 0 on success or else a LTTNG_ERR code. + */ +int cmd_regenerate_statedump(struct ltt_session *session) +{ + int ret; + + assert(session); + + if (!session->active) { + ret = LTTNG_ERR_SESSION_NOT_STARTED; + goto end; + } + ret = 0; + + if (session->kernel_session) { + ret = kernctl_session_regenerate_statedump( + session->kernel_session->fd); + if (ret < 0) { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + ERR("Failed to regenerate the kernel statedump"); + goto end; + } + } + + if (session->ust_session) { + ret = ust_app_regenerate_statedump_all(session->ust_session); + if (ret < 0) { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + ERR("Failed to regenerate the UST statedump"); + goto end; + } + } + DBG("Cmd regenerate statedump for session %s", session->name); + ret = LTTNG_OK; + +end: + return ret; +} + +/* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination. * diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 320d717..975a7f1 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -111,5 +111,6 @@ int cmd_snapshot_record(struct ltt_session *session, int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path); int cmd_regenerate_metadata(struct ltt_session *session); +int cmd_regenerate_statedump(struct ltt_session *session); #endif /* CMD_H */ diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 3623e5d..8309c3f 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -3004,6 +3004,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_SAVE_SESSION: case LTTNG_SET_SESSION_SHM_PATH: case LTTNG_REGENERATE_METADATA: + case LTTNG_REGENERATE_STATEDUMP
[lttng-dev] [PATCH lttng-tools v2 2/6] UST command to regenerate the statedump
From: Mathieu DesnoyersSigned-off-by: Mathieu Desnoyers --- src/bin/lttng-sessiond/lttng-ust-abi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/lttng-sessiond/lttng-ust-abi.h b/src/bin/lttng-sessiond/lttng-ust-abi.h index 7bec0c9..9ef7b9a 100644 --- a/src/bin/lttng-sessiond/lttng-ust-abi.h +++ b/src/bin/lttng-sessiond/lttng-ust-abi.h @@ -275,6 +275,7 @@ struct lttng_ust_event_exclusion { _UST_CMDW(0x51, struct lttng_ust_channel) #define LTTNG_UST_SESSION_START_UST_CMD(0x52) #define LTTNG_UST_SESSION_STOP _UST_CMD(0x53) +#define LTTNG_UST_SESSION_STATEDUMP_UST_CMD(0x54) /* Channel FD commands */ #define LTTNG_UST_STREAM _UST_CMD(0x60) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools 1/6] Rename the "metadata regenerate" command to "regenerate metadata"
Prepare the deprecation of the "metadata regenerate" command since we need to regenerate the statedump as well, so it is more convenient to have one command to regenerate various session's attributes. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 2 +- doc/man/Makefile.am | 3 +- doc/man/lttng-metadata.1.txt | 28 +-- doc/man/lttng-regenerate.1.txt| 63 + include/lttng/lttng.h | 7 +- src/bin/lttng-sessiond/cmd.c | 15 +- src/bin/lttng-sessiond/cmd.h | 2 +- src/bin/lttng-sessiond/main.c | 6 +- src/bin/lttng/Makefile.am | 1 + src/bin/lttng/command.h | 1 + src/bin/lttng/commands/metadata.c | 2 +- src/bin/lttng/commands/regenerate.c | 266 ++ src/bin/lttng/lttng.c | 1 + src/common/kernel-ctl/kernel-ctl.c| 2 +- src/common/kernel-ctl/kernel-ctl.h| 2 +- src/common/mi-lttng.c | 2 + src/common/mi-lttng.h | 2 + src/common/sessiond-comm/sessiond-comm.h | 4 +- src/lib/lttng-ctl/lttng-ctl.c | 12 +- tests/destructive/metadata-regeneration | 8 +- tests/fast_regression | 2 +- tests/regression/Makefile.am | 2 +- tests/regression/tools/Makefile.am| 2 +- tests/regression/tools/metadata-regen/Makefile.am | 16 -- tests/regression/tools/metadata-regen/test_kernel | 109 - tests/regression/tools/metadata-regen/test_ust| 208 - tests/regression/tools/mi/test_mi | 4 +- tests/regression/tools/regen-metadata/Makefile.am | 16 ++ tests/regression/tools/regen-metadata/test_kernel | 109 + tests/regression/tools/regen-metadata/test_ust| 208 + tests/root_regression | 2 +- tests/utils/utils.sh | 14 +- 32 files changed, 723 insertions(+), 398 deletions(-) create mode 100644 doc/man/lttng-regenerate.1.txt create mode 100644 src/bin/lttng/commands/regenerate.c delete mode 100644 tests/regression/tools/metadata-regen/Makefile.am delete mode 100755 tests/regression/tools/metadata-regen/test_kernel delete mode 100755 tests/regression/tools/metadata-regen/test_ust create mode 100644 tests/regression/tools/regen-metadata/Makefile.am create mode 100755 tests/regression/tools/regen-metadata/test_kernel create mode 100755 tests/regression/tools/regen-metadata/test_ust diff --git a/configure.ac b/configure.ac index fb2b013..89a7858 100644 --- a/configure.ac +++ b/configure.ac @@ -980,7 +980,7 @@ AC_CONFIG_FILES([ tests/regression/tools/mi/Makefile tests/regression/tools/wildcard/Makefile tests/regression/tools/crash/Makefile - tests/regression/tools/metadata-regen/Makefile + tests/regression/tools/regen-metadata/Makefile tests/regression/ust/Makefile tests/regression/ust/nprocesses/Makefile tests/regression/ust/high-throughput/Makefile diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 1090f1a..f75db6e 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -30,7 +30,8 @@ MAN1_NAMES = \ lttng-enable-event \ lttng-disable-event \ lttng-crash \ - lttng-metadata + lttng-metadata \ + lttng-regenerate MAN3_NAMES = MAN8_NAMES = lttng-sessiond lttng-relayd MAN1_NO_ASCIIDOC_NAMES = diff --git a/doc/man/lttng-metadata.1.txt b/doc/man/lttng-metadata.1.txt index 0fa240e..3410183 100644 --- a/doc/man/lttng-metadata.1.txt +++ b/doc/man/lttng-metadata.1.txt @@ -15,33 +15,9 @@ SYNOPSIS DESCRIPTION --- -The `lttng metadata` command manages a tracing session's metadata -generation options. - -As of this version, only the `regenerate` command's action is available. -Regenerating a tracing session's metadata can be used to -resample the offset between the system's monotonic clock and -the wall-clock time. - -This command is meant to be used to resample the wall-clock time -following a major -link:https://en.wikipedia.org/wiki/Network_Time_Protocol[NTP] -correction. As such, a system booting with an incorrect wall time can be -traced before its wall time is NTP-corrected. Regenerating the tracing -session's metadata ensures that trace viewers can accurately determine -the events time relative to Unix Epoch. - - -include::common-cmd-options-head.txt[] - - -option:-s, option:--session='SESSION':: -Manage the metadata generation of the tracing session named 'SESSION' -instead of the current tracing session. - - -include::common-cmd-help-options.txt[] +Depr
[lttng-dev] [PATCH lttng-tools 4/6] Allow regenerating the statedump of a running session
The "lttng regenerate statedump" command can be used to regenerate the statedump of a running session whenever needed. This is particularly useful in snapshot and trace-file rotation modes where the original statedump may be lost. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- include/lttng/lttng-error.h | 1 + include/lttng/lttng.h| 9 + src/bin/lttng-sessiond/cmd.c | 44 +++ src/bin/lttng-sessiond/cmd.h | 1 + src/bin/lttng-sessiond/main.c| 6 src/bin/lttng-sessiond/ust-app.c | 62 src/bin/lttng-sessiond/ust-app.h | 6 src/bin/lttng/commands/regenerate.c | 19 ++ src/common/error.c | 1 + src/common/kernel-ctl/kernel-ctl.c | 5 +++ src/common/kernel-ctl/kernel-ctl.h | 1 + src/common/sessiond-comm/sessiond-comm.h | 1 + src/lib/lttng-ctl/lttng-ctl.c| 31 13 files changed, 187 insertions(+) diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h index 72194ef..52ce333 100644 --- a/include/lttng/lttng-error.h +++ b/include/lttng/lttng-error.h @@ -142,6 +142,7 @@ enum lttng_error_code { LTTNG_ERR_LIVE_SESSION = 119, /* Live session unsupported */ LTTNG_ERR_PER_PID_SESSION= 120, /* Per-PID sessions unsupported */ LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE = 121, /* Context unavailable on this kernel */ + LTTNG_ERR_REGEN_STATEDUMP_FAIL = 122, /* Failed to regenerate the statdump */ /* MUST be last element */ LTTNG_ERR_NR, /* Last element */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index ed03bdb..7f9fa9d 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -172,6 +172,15 @@ extern int lttng_metadata_regenerate(const char *session_name); */ extern int lttng_regenerate_metadata(const char *session_name); +/* + * Trigger the regeneration of the statedump for a session. The new statedump + * information is appended to the currently active trace, the session needs to + * be started. + * + * Return 0 on success, a negative LTTng error code on error. + */ +extern int lttng_regenerate_statedump(const char *session_name); + #ifdef __cplusplus } #endif diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index bd63389..480333d 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -3540,6 +3540,50 @@ end: } /* + * Command LTTNG_REGENERATE_STATEDUMP from the lttng-ctl library. + * + * Ask the tracer to regenerate a new statedump. + * + * Return 0 on success or else a LTTNG_ERR code. + */ +int cmd_regenerate_statedump(struct ltt_session *session) +{ + int ret; + + assert(session); + + if (!session->active) { + ret = LTTNG_ERR_SESSION_NOT_STARTED; + goto end; + } + ret = 0; + + if (session->kernel_session) { + ret = kernctl_session_regenerate_statedump( + session->kernel_session->fd); + if (ret < 0) { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + ERR("Failed to regenerate the kernel statedump"); + goto end; + } + } + + if (session->ust_session) { + ret = ust_app_regenerate_statedump_all(session->ust_session); + if (ret < 0) { + ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL; + ERR("Failed to regenerate the UST statedump"); + goto end; + } + } + DBG("Cmd regenerate statedump for session %s", session->name); + ret = LTTNG_OK; + +end: + return ret; +} + +/* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination. * diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 320d717..975a7f1 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -111,5 +111,6 @@ int cmd_snapshot_record(struct ltt_session *session, int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path); int cmd_regenerate_metadata(struct ltt_session *session); +int cmd_regenerate_statedump(struct ltt_session *session); #endif /* CMD_H */ diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 3623e5d..8309c3f 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -3004,6 +3004,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_SAVE_SESSION: case LTTNG_SET_SESSION_SHM_PATH: case LTTNG_REGENERATE_METADATA: + case LTTNG_REGENERATE_STATEDUMP
[lttng-dev] [PATCH lttng-tools 3/6] Kernel ioctl to regenerate the statedump
From: Mathieu Desnoyers--- src/common/kernel-ctl/kernel-ioctl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index 68056dc..805de02 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -134,6 +134,8 @@ */ #define LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS _IO(0xF6, 0x58) #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) /* Channel FD ioctl */ #define LTTNG_KERNEL_STREAM_IO(0xF6, 0x62) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools 2/6] UST command to regenerate the statedump
From: Mathieu Desnoyers--- src/bin/lttng-sessiond/lttng-ust-abi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/lttng-sessiond/lttng-ust-abi.h b/src/bin/lttng-sessiond/lttng-ust-abi.h index 7bec0c9..9ef7b9a 100644 --- a/src/bin/lttng-sessiond/lttng-ust-abi.h +++ b/src/bin/lttng-sessiond/lttng-ust-abi.h @@ -275,6 +275,7 @@ struct lttng_ust_event_exclusion { _UST_CMDW(0x51, struct lttng_ust_channel) #define LTTNG_UST_SESSION_START_UST_CMD(0x52) #define LTTNG_UST_SESSION_STOP _UST_CMD(0x53) +#define LTTNG_UST_SESSION_STATEDUMP_UST_CMD(0x54) /* Channel FD commands */ #define LTTNG_UST_STREAM _UST_CMD(0x60) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools 5/6] Tests for the regenerate statedump command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 1 + tests/fast_regression | 1 + tests/regression/tools/Makefile.am | 2 +- tests/regression/tools/regen-statedump/Makefile.am | 16 tests/regression/tools/regen-statedump/test_kernel | 80 +++ tests/regression/tools/regen-statedump/test_ust| 89 ++ tests/root_regression | 1 + tests/utils/utils.sh | 54 + 8 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 tests/regression/tools/regen-statedump/Makefile.am create mode 100755 tests/regression/tools/regen-statedump/test_kernel create mode 100755 tests/regression/tools/regen-statedump/test_ust diff --git a/configure.ac b/configure.ac index 89a7858..6222e2b 100644 --- a/configure.ac +++ b/configure.ac @@ -981,6 +981,7 @@ AC_CONFIG_FILES([ tests/regression/tools/wildcard/Makefile tests/regression/tools/crash/Makefile tests/regression/tools/regen-metadata/Makefile + tests/regression/tools/regen-statedump/Makefile tests/regression/ust/Makefile tests/regression/ust/nprocesses/Makefile tests/regression/ust/high-throughput/Makefile diff --git a/tests/fast_regression b/tests/fast_regression index 262c846..8edbeca 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -17,6 +17,7 @@ regression/tools/mi/test_mi regression/tools/wildcard/test_event_wildcard regression/tools/crash/test_crash regression/tools/regen-metadata/test_ust +regression/tools/regen-statedump/test_ust regression/ust/before-after/test_before_after regression/ust/buffers-pid/test_buffers_pid regression/ust/multi-session/test_multi_session diff --git a/tests/regression/tools/Makefile.am b/tests/regression/tools/Makefile.am index 91820ad..76374c7 100644 --- a/tests/regression/tools/Makefile.am +++ b/tests/regression/tools/Makefile.am @@ -1,2 +1,2 @@ SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load mi \ - wildcard crash regen-metadata + wildcard crash regen-metadata regen-statedump diff --git a/tests/regression/tools/regen-statedump/Makefile.am b/tests/regression/tools/regen-statedump/Makefile.am new file mode 100644 index 000..d4a92eb --- /dev/null +++ b/tests/regression/tools/regen-statedump/Makefile.am @@ -0,0 +1,16 @@ +noinst_SCRIPTS = test_ust test_kernel +EXTRA_DIST = test_ust test_kernel + +all-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + cp -f $(srcdir)/$$script $(builddir); \ + done; \ + fi + +clean-local: + @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ + for script in $(EXTRA_DIST); do \ + rm -f $(builddir)/$$script; \ + done; \ + fi diff --git a/tests/regression/tools/regen-statedump/test_kernel b/tests/regression/tools/regen-statedump/test_kernel new file mode 100755 index 000..85afe76 --- /dev/null +++ b/tests/regression/tools/regen-statedump/test_kernel @@ -0,0 +1,80 @@ +#!/bin/bash +# +# Copyright (C) - 2016 Julien Desfossez <jdesfos...@efficios.com> +# +# This library is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; 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 +TEST_DESC="Regenerate the statedump - Kernel tracing" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../../.. +EVENT_NAME="lttng_test_filter_event" +PID_RELAYD=0 +SESSION_NAME="" +EVENT_NAME="lttng_statedump_start,lttng_statedump_end" + +TRACE_PATH=$(mktemp -d) + +NUM_TESTS=11 + +source $TESTDIR/utils/utils.sh + +# LTTng kernel modules check +out=`ls /lib/modules/$(uname -r)/extra | grep lttng` +if [ -z "$out" ]; then + BAIL_OUT "LTTng modules not detected." +fi + +function test_kernel_local () +{ + diag "Test kernel local with statedump regeneration" + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + lttng_enable_kernel_event $SESSION_NAME $EVENT_NAME + start_lttng_tracing_ok $SESSION_NAME + echo -n "100" > /proc/lttng-test-filter-event + regenerate_statedump_ok
[lttng-dev] [PATCH lttng-tools 6/6] Manpage for the regenerate statedump command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- doc/man/lttng-regenerate.1.txt | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/man/lttng-regenerate.1.txt b/doc/man/lttng-regenerate.1.txt index dbbfa4d..80bae20 100644 --- a/doc/man/lttng-regenerate.1.txt +++ b/doc/man/lttng-regenerate.1.txt @@ -14,12 +14,19 @@ Regenerate the metadata of a session [verse] *lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate metadata* [option:--session='SESSION'] +Regenerate the statedump of a session + +[verse] +*lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *regenerate statedump* [option:--session='SESSION'] + DESCRIPTION --- The `lttng regenerate` command manages a tracing session's data regeneration options. -As of this version, only the `metadata` command's action is available. +As of this version, the `metadata` and `statedump` command's action are +available. + Regenerating a tracing session's metadata can be used to resample the offset between the system's monotonic clock and the wall-clock time. @@ -32,12 +39,16 @@ traced before its wall time is NTP-corrected. Regenerating the tracing session's metadata ensures that trace viewers can accurately determine the events time relative to Unix Epoch. +Regenerating a tracing session's statedump can be used to collect up-to-date +statedump informations during the trace session. This is particularly useful in +snapshot or trace-file rotation modes where the statedump information may be +lost. include::common-cmd-options-head.txt[] option:-s, option:--session='SESSION':: -Manage the metadata generation of the tracing session named 'SESSION' +Manage the data regeneration of the tracing session named 'SESSION' instead of the current tracing session. -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v4] Test for select, poll and epoll syscall overrides
This test for root_regression checks if the syscall overrides for select, pselect6, poll, ppoll, epoll_ctl, epoll_wait and epoll_pwait work as expected on arm and x86 (32 and 64-bit). There are 11 test cases that check for normal and abnormal behaviour. If the test system has the Babeltrace python bindings, the test validates the content of the events, otherwise only the presence of the generated events is checked. We also check if kernel OOPS, WARNING or BUG were generated during the test. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am| 8 +- tests/regression/kernel/select_poll_epoll.c| 921 + tests/regression/kernel/test_select_poll_epoll | 412 + .../kernel/validate_select_poll_epoll.py | 758 + tests/root_regression | 1 + 5 files changed, 2099 insertions(+), 1 deletion(-) create mode 100644 tests/regression/kernel/select_poll_epoll.c create mode 100755 tests/regression/kernel/test_select_poll_epoll create mode 100755 tests/regression/kernel/validate_select_poll_epoll.py diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index a8c397a..cfdeeb9 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,5 +1,11 @@ EXTRA_DIST = test_event_basic test_all_events test_syscall \ - test_clock_override test_rotation_destroy_flush + test_clock_override test_rotation_destroy_flush \ + test_select_poll_epoll + +noinst_PROGRAMS = select_poll_epoll +select_poll_epoll_SOURCES = select_poll_epoll.c +select_poll_epoll_LDADD = -lpthread -lpopt +select_poll_epoll_CFLAGS = -fno-stack-protector -D_FORTIFY_SOURCE=0 all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/kernel/select_poll_epoll.c b/tests/regression/kernel/select_poll_epoll.c new file mode 100644 index 000..2a69d5e --- /dev/null +++ b/tests/regression/kernel/select_poll_epoll.c @@ -0,0 +1,921 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 +#define NB_FD 1 +#define MAX_FDS 2047 +#define NR_ITER 1000 /* for stress-tests */ + +#define MIN_NR_FDS 5 /* the minimum number of open FDs required for the test to run */ +#define BIG_SELECT_FD 1022 + +#define MSEC_PER_USEC 1000 +#define MSEC_PER_NSEC (MSEC_PER_USEC * 1000) + +static int timeout; /* seconds, -1 to disable */ +volatile static int stop_thread; +static int wait_fd; + +struct ppoll_thread_data { + struct pollfd *ufds; + int value; +}; + +void test_select_big(void) +{ + fd_set rfds, wfds, exfds; + struct timeval tv; + int ret; + int fd2; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_ZERO(); + FD_ZERO(); + + fd2 = dup2(wait_fd, BIG_SELECT_FD); + if (fd2 < 0) { + perror("dup2"); + goto end; + } + FD_SET(fd2, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * MSEC_PER_USEC; + + if (timeout > 0) { + ret = select(fd2 + 1, , , , ); + } else { + ret = select(fd2 + 1, , , , NULL); + } + + if (ret == -1) { + perror("select()"); + } else if (ret) { + printf("# [select] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[select] read"); + } + } else { + printf("# [select] timeout\n"); + } + + ret = close(BIG_SELECT_FD); + if (ret) { + perror("close"); + } + +end: + return; +} + +void test_pselect(void) +{ + fd_set rfds; + struct timespec tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_nsec = timeout * MSEC_PER_NSEC; + + if (timeout > 0) { + ret = pselect(1, , NULL, NULL, , NULL); + } else { + ret = pselect(1, , NULL, NULL, NULL, NULL); + } + + if (ret == -1) { + perror("pselect()"); + } else if (ret) { + printf("# [pselect] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[pselect] read"); + } + } else { + printf("# [pselect] timeout\n"); + } + +} + +void test_select(void) +{ + fd_set rfds; + struct timeval tv; + int ret; + char buf[BUF_SIZE]; + +
[lttng-dev] [PATCH lttng-ust v4 2/2] Add perf context support for ARMv7
Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call every time a counter needs to be read which has a significant performance impact. ARMv7 does not have way to read PMU from userspace because it requires write access to the debug coprocessor to select which PMU counter to read which defeats user-space/kernel protection. For that reason, the bits required to allow user-space access to those registers are not enabled in the kernel and Perf does not expose any information in the shared mmap page, so we do not know what is the counter index. Also, for ARMv7 we cannot set the exclude_kernel flag, so the counter stays active even when the process is executing in kernel context (system calls mainly). This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 1 + liblttng-ust-ctl/ustctl.c | 2 +- liblttng-ust/lttng-context-perf-counters.c | 89 ++ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 105b46f..a966732 100644 --- a/configure.ac +++ b/configure.ac @@ -222,6 +222,7 @@ AS_CASE([$host_cpu], [i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], + [armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no]) AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS]) diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 0165786..97445d5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream, return client_cb->instance_id(buf, handle, id); } -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) int ustctl_has_perf_counters(void) { diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index db756d6..dda6737 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -96,17 +96,13 @@ static bool arch_perf_use_read(void) return false; } -#else /* defined(__x86_64__) || defined(__i386__) */ - -#error "Perf event counters are only supported on x86 so far." - -#endif /* #else defined(__x86_64__) || defined(__i386__) */ - static -uint64_t read_perf_counter(struct perf_event_mmap_page *pc) +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) { uint32_t seq, idx; uint64_t count; + struct perf_event_mmap_page *pc = thread_field->pc; if (caa_unlikely(!pc)) return 0; @@ -127,6 +123,35 @@ uint64_t read_perf_counter(struct perf_event_mmap_page *pc) return count; } +#elif defined (__ARM_ARCH_7A__) + +static bool arch_perf_use_read(void) +{ + return true; +} + +static +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) +{ + uint64_t count; + + if (caa_unlikely(thread_field->fd < 0)) + return 0; + + if (caa_unlikely(read(thread_field->fd, , sizeof(count)) + < sizeof(count))) + return 0; + + return count; +} + +#else /* defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + +#error "Perf event counters are only supported on x86 and ARMv7 so far." + +#endif /* #else defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, @@ -149,6 +174,20 @@ int open_perf_fd(struct perf_event_attr *attr) } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) { + perror("Error closing LTTng-UST perf memory mapping FD"); + } +} + +static struct perf_event_mmap_page *setup_perf( struct lttng_perf_counter_thread_field *thread_field) { @@ -164,24 +203,10 @@ struct perf_event_mmap_page *setup_perf( thread_field->fd = -1; } -end: return perf_addr; } static -void close_perf_fd(int fd) -{ - int ret; - - if (fd < 0) - return; - - ret = close(fd); - if (ret) - perror("Error closing LTTng-UST perf memory mapping FD"); -} - -static void unmap_perf_page(struct p
[lttng-dev] [PATCH lttng-ust v4 1/2] Keep perf context FD open for other architectures
Instead of closing the perf context after the page has been mapped, keep it open so it can be used with the read() system call if the architecture does not support direct access from user-space. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- liblttng-ust/lttng-context-perf-counters.c | 65 +++--- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 97ddf97..db756d6 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -55,6 +55,7 @@ struct lttng_perf_counter_thread_field { struct perf_event_mmap_page *pc; struct cds_list_head thread_field_node; /* Per-field list of thread fields (node) */ struct cds_list_head rcu_field_node;/* RCU per-thread list of fields (node) */ + int fd; /* Perf FD */ }; struct lttng_perf_counter_thread { @@ -90,6 +91,11 @@ uint64_t rdpmc(unsigned int counter) return low | ((uint64_t) high) << 32; } +static bool arch_perf_use_read(void) +{ + return false; +} + #else /* defined(__x86_64__) || defined(__i386__) */ #error "Perf event counters are only supported on x86 so far." @@ -131,27 +137,51 @@ int sys_perf_event_open(struct perf_event_attr *attr, } static -struct perf_event_mmap_page *setup_perf(struct perf_event_attr *attr) +int open_perf_fd(struct perf_event_attr *attr) { - void *perf_addr; - int fd, ret; + int fd; fd = sys_perf_event_open(attr, 0, -1, -1, 0); if (fd < 0) - return NULL; + return -1; + + return fd; +} + +static +struct perf_event_mmap_page *setup_perf( + struct lttng_perf_counter_thread_field *thread_field) +{ + void *perf_addr; perf_addr = mmap(NULL, sizeof(struct perf_event_mmap_page), - PROT_READ, MAP_SHARED, fd, 0); + PROT_READ, MAP_SHARED, thread_field->fd, 0); if (perf_addr == MAP_FAILED) - return NULL; - ret = close(fd); - if (ret) { - perror("Error closing LTTng-UST perf memory mapping FD"); + perf_addr = NULL; + + if (!arch_perf_use_read()) { + close_perf_fd(thread_field->fd); + thread_field->fd = -1; } + +end: return perf_addr; } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) + perror("Error closing LTTng-UST perf memory mapping FD"); +} + +static void unmap_perf_page(struct perf_event_mmap_page *pc) { int ret; @@ -221,8 +251,13 @@ struct lttng_perf_counter_thread_field * if (!thread_field) abort(); thread_field->field = perf_field; - thread_field->pc = setup_perf(_field->attr); - /* Note: thread_field->pc can be NULL if setup_perf() fails. */ + thread_field->fd = open_perf_fd(_field->attr); + if (thread_field->fd >= 0) + thread_field->pc = setup_perf(thread_field); + /* +* Note: thread_field->pc can be NULL if setup_perf() fails. +* Also, thread_field->fd can be -1 if open_perf_fd fails. +*/ ust_lock_nocheck(); cds_list_add_rcu(_field->rcu_field_node, _thread->rcu_field_list); @@ -293,6 +328,7 @@ static void lttng_destroy_perf_thread_field( struct lttng_perf_counter_thread_field *thread_field) { + close_perf_fd(thread_field->fd); unmap_perf_page(thread_field->pc); cds_list_del_rcu(_field->rcu_field_node); cds_list_del(_field->thread_field_node); @@ -341,7 +377,6 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, { struct lttng_ctx_field *field; struct lttng_perf_counter_field *perf_field; - struct perf_event_mmap_page *tmp_pc; char *name_alloc; int ret; @@ -389,12 +424,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->u.perf_counter = perf_field; /* Ensure that this perf counter can be used in this process. */ - tmp_pc = setup_perf(_field->attr); - if (!tmp_pc) { + ret = open_perf_fd(_field->attr); + if (ret < 0) { ret = -ENODEV; goto setup_error; } - unmap_perf_page(tmp_pc); + close_perf_fd(ret); /* * Contexts can only be added before tracing is started, so we -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] [PATCH lttng-ust v3 2/2] Add perf context support for ARMv7
Please disregard that, wrong patch sent, wait for v4... ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-ust v3 2/2] Add perf context support for ARMv7
Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call every time a counter needs to be read which has a significant performance impact. ARMv7 does not have way to read PMU from userspace because it requires write access to the debug coprocessor to select which PMU counter to read which defeats user-space/kernel protection. For that reason, the bits required to allow user-space access to those registers are not enabled in the kernel and Perf does not expose any information in the shared mmap page, so we do not know what is the counter index. Also, for ARMv7 we cannot set the exclude_kernel flag, so the counter stays active even when the process is executing in kernel context (system calls mainly). This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 1 + liblttng-ust-ctl/ustctl.c | 2 +- liblttng-ust/lttng-context-perf-counters.c | 79 ++ 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 105b46f..a966732 100644 --- a/configure.ac +++ b/configure.ac @@ -222,6 +222,7 @@ AS_CASE([$host_cpu], [i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], + [armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no]) AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS]) diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 0165786..97445d5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream, return client_cb->instance_id(buf, handle, id); } -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) int ustctl_has_perf_counters(void) { diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index e546aee..1af1509 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -96,17 +96,13 @@ static bool arch_perf_use_read(void) return false; } -#else /* defined(__x86_64__) || defined(__i386__) */ - -#error "Perf event counters are only supported on x86 so far." - -#endif /* #else defined(__x86_64__) || defined(__i386__) */ - static -uint64_t read_perf_counter(struct perf_event_mmap_page *pc) +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) { uint32_t seq, idx; uint64_t count; + struct perf_event_mmap_page *pc = thread_field->pc; if (caa_unlikely(!pc)) return 0; @@ -127,6 +123,35 @@ uint64_t read_perf_counter(struct perf_event_mmap_page *pc) return count; } +#elif defined (__ARM_ARCH_7A__) + +static bool arch_perf_use_read(void) +{ + return true; +} + +static +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) +{ + uint64_t count; + + if (caa_unlikely(thread_field->fd < 0)) + return 0; + + if (caa_unlikely(read(thread_field->fd, , sizeof(count)) + < sizeof(count))) + return 0; + + return count; +} + +#else /* defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + +#error "Perf event counters are only supported on x86 and ARMv7 so far." + +#endif /* #else defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, @@ -149,6 +174,20 @@ int open_perf_fd(struct perf_event_attr *attr) } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) { + perror("Error closing LTTng-UST perf memory mapping FD"); + } +} + +static struct perf_event_mmap_page *setup_perf( struct lttng_perf_counter_thread_field *thread_field) { @@ -164,11 +203,11 @@ struct perf_event_mmap_page *setup_perf( thread_field->fd = -1; } -end: return perf_addr; } static +<<<<<<< HEAD void close_perf_fd(int fd) { int ret; @@ -182,6 +221,8 @@ void close_perf_fd(int fd) } static +=== +>>>>>>> b0fa947... Add perf context support for ARMv7 void unmap_perf_page(struct perf_event_mmap_page
[lttng-dev] [PATCH lttng-ust v3 1/2] Keep perf context FD open for other architectures
Instead of closing the perf context after the page has been mapped, keep it open so it can be used with the read() system call if the architecture does not support direct access from user-space. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- liblttng-ust/lttng-context-perf-counters.c | 65 +++--- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 97ddf97..e546aee 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -55,6 +55,7 @@ struct lttng_perf_counter_thread_field { struct perf_event_mmap_page *pc; struct cds_list_head thread_field_node; /* Per-field list of thread fields (node) */ struct cds_list_head rcu_field_node;/* RCU per-thread list of fields (node) */ + int fd; /* Perf FD */ }; struct lttng_perf_counter_thread { @@ -90,6 +91,11 @@ uint64_t rdpmc(unsigned int counter) return low | ((uint64_t) high) << 32; } +static bool arch_perf_use_read(void) +{ + return false; +} + #else /* defined(__x86_64__) || defined(__i386__) */ #error "Perf event counters are only supported on x86 so far." @@ -131,27 +137,51 @@ int sys_perf_event_open(struct perf_event_attr *attr, } static -struct perf_event_mmap_page *setup_perf(struct perf_event_attr *attr) +int open_perf_fd(struct perf_event_attr *attr) { - void *perf_addr; - int fd, ret; + int fd; fd = sys_perf_event_open(attr, 0, -1, -1, 0); if (fd < 0) - return NULL; + return -1; + + return fd; +} + +static +struct perf_event_mmap_page *setup_perf( + struct lttng_perf_counter_thread_field *thread_field) +{ + void *perf_addr; perf_addr = mmap(NULL, sizeof(struct perf_event_mmap_page), - PROT_READ, MAP_SHARED, fd, 0); + PROT_READ, MAP_SHARED, thread_field->fd, 0); if (perf_addr == MAP_FAILED) - return NULL; - ret = close(fd); - if (ret) { - perror("Error closing LTTng-UST perf memory mapping FD"); + perf_addr = NULL; + + if (!arch_perf_use_read) { + close_perf_fd(thread_field->fd); + thread_field->fd = -1; } + +end: return perf_addr; } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) + perror("Error closing LTTng-UST perf memory mapping FD"); +} + +static void unmap_perf_page(struct perf_event_mmap_page *pc) { int ret; @@ -221,8 +251,13 @@ struct lttng_perf_counter_thread_field * if (!thread_field) abort(); thread_field->field = perf_field; - thread_field->pc = setup_perf(_field->attr); - /* Note: thread_field->pc can be NULL if setup_perf() fails. */ + thread_field->fd = open_perf_fd(_field->attr); + if (thread_field->fd >= 0) + thread_field->pc = setup_perf(thread_field); + /* +* Note: thread_field->pc can be NULL if setup_perf() fails. +* Also, thread_field->fd can be -1 if open_perf_fd fails. +*/ ust_lock_nocheck(); cds_list_add_rcu(_field->rcu_field_node, _thread->rcu_field_list); @@ -293,6 +328,7 @@ static void lttng_destroy_perf_thread_field( struct lttng_perf_counter_thread_field *thread_field) { + close_perf_fd(thread_field->fd); unmap_perf_page(thread_field->pc); cds_list_del_rcu(_field->rcu_field_node); cds_list_del(_field->thread_field_node); @@ -341,7 +377,6 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, { struct lttng_ctx_field *field; struct lttng_perf_counter_field *perf_field; - struct perf_event_mmap_page *tmp_pc; char *name_alloc; int ret; @@ -389,12 +424,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->u.perf_counter = perf_field; /* Ensure that this perf counter can be used in this process. */ - tmp_pc = setup_perf(_field->attr); - if (!tmp_pc) { + ret = open_perf_fd(_field->attr); + if (ret < 0) { ret = -ENODEV; goto setup_error; } - unmap_perf_page(tmp_pc); + close_perf_fd(ret); /* * Contexts can only be added before tracing is started, so we -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-ust v2 1/2] Keep perf context FD open for other architectures
Instead of closing the perf context after the page has been mapped, keep it open so it can be used with the read() system call if the architecture does not support direct access from user-space. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- liblttng-ust/lttng-context-perf-counters.c | 53 +++--- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 97ddf97..725b1b4 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -55,6 +55,7 @@ struct lttng_perf_counter_thread_field { struct perf_event_mmap_page *pc; struct cds_list_head thread_field_node; /* Per-field list of thread fields (node) */ struct cds_list_head rcu_field_node;/* RCU per-thread list of fields (node) */ + int fd; /* Perf FD */ }; struct lttng_perf_counter_thread { @@ -131,24 +132,50 @@ int sys_perf_event_open(struct perf_event_attr *attr, } static -struct perf_event_mmap_page *setup_perf(struct perf_event_attr *attr) +int open_perf_fd(struct perf_event_attr *attr) { - void *perf_addr; - int fd, ret; + int fd; fd = sys_perf_event_open(attr, 0, -1, -1, 0); if (fd < 0) - return NULL; + return -1; + + return fd; +} + +static +struct perf_event_mmap_page *setup_perf( + struct lttng_perf_counter_thread_field *thread_field) +{ + void *perf_addr; perf_addr = mmap(NULL, sizeof(struct perf_event_mmap_page), - PROT_READ, MAP_SHARED, fd, 0); + PROT_READ, MAP_SHARED, thread_field->fd, 0); if (perf_addr == MAP_FAILED) - return NULL; + perf_addr = NULL; + + /* No need to keep the FD open on x86 */ +#if defined(__x86_64__) || defined(__i386__) + close_perf_fd(thread_field->fd); + thread_field->fd = -1; +#endif + +end: + return perf_addr; +} + +static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + ret = close(fd); if (ret) { perror("Error closing LTTng-UST perf memory mapping FD"); } - return perf_addr; } static @@ -221,7 +248,9 @@ struct lttng_perf_counter_thread_field * if (!thread_field) abort(); thread_field->field = perf_field; - thread_field->pc = setup_perf(_field->attr); + thread_field->fd = open_perf_fd(_field->attr); + if (thread_field->fd >= 0) + thread_field->pc = setup_perf(thread_field); /* Note: thread_field->pc can be NULL if setup_perf() fails. */ ust_lock_nocheck(); cds_list_add_rcu(_field->rcu_field_node, @@ -293,6 +322,7 @@ static void lttng_destroy_perf_thread_field( struct lttng_perf_counter_thread_field *thread_field) { + close_perf_fd(thread_field->fd); unmap_perf_page(thread_field->pc); cds_list_del_rcu(_field->rcu_field_node); cds_list_del(_field->thread_field_node); @@ -341,7 +371,6 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, { struct lttng_ctx_field *field; struct lttng_perf_counter_field *perf_field; - struct perf_event_mmap_page *tmp_pc; char *name_alloc; int ret; @@ -389,12 +418,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->u.perf_counter = perf_field; /* Ensure that this perf counter can be used in this process. */ - tmp_pc = setup_perf(_field->attr); - if (!tmp_pc) { + ret = open_perf_fd(_field->attr); + if (ret < 0) { ret = -ENODEV; goto setup_error; } - unmap_perf_page(tmp_pc); + close_perf_fd(ret); /* * Contexts can only be added before tracing is started, so we -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-ust v2 2/2] Add perf context support for ARMv7
Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call every time a counter needs to be read which has a significant performance impact. ARMv7 does not have way to read PMU from userspace because it requires write access to the debug coprocessor to select which PMU counter to read which defeats user-space/kernel protection. For that reason, the bits required to allow user-space access to those registers are not enabled in the kernel and Perf does not expose any information in the shared mmap page, so we do not know what is the counter index. Also, for ARMv7 we cannot the exclude_kernel flag, so the counter stays active even when the process is executing in kernel context (system calls mainly). This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 1 + liblttng-ust-ctl/ustctl.c | 2 +- liblttng-ust/lttng-context-perf-counters.c | 84 +- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index de462ff..5475640 100644 --- a/configure.ac +++ b/configure.ac @@ -219,6 +219,7 @@ AS_CASE([$host_cpu], [i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], + [armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no]) AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS]) diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 0165786..97445d5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream, return client_cb->instance_id(buf, handle, id); } -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) int ustctl_has_perf_counters(void) { diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 725b1b4..a981aa9 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -91,17 +91,13 @@ uint64_t rdpmc(unsigned int counter) return low | ((uint64_t) high) << 32; } -#else /* defined(__x86_64__) || defined(__i386__) */ - -#error "Perf event counters are only supported on x86 so far." - -#endif /* #else defined(__x86_64__) || defined(__i386__) */ - static -uint64_t read_perf_counter(struct perf_event_mmap_page *pc) +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) { uint32_t seq, idx; uint64_t count; + struct perf_event_mmap_page *pc = thread_field->pc; if (caa_unlikely(!pc)) return 0; @@ -122,6 +118,29 @@ uint64_t read_perf_counter(struct perf_event_mmap_page *pc) return count; } +#elif defined (__ARM_ARCH_7A__) + +static +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) +{ + uint64_t count; + + if (caa_unlikely(thread_field->fd < 0)) + return 0; + + if (read(thread_field->fd, , sizeof(count)) < sizeof(count)) + return 0; + + return count; +} + +#else /* defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + +#error "Perf event counters are only supported on x86 and ARMv7 so far." + +#endif /* #else defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, @@ -144,6 +163,20 @@ int open_perf_fd(struct perf_event_attr *attr) } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) { + perror("Error closing LTTng-UST perf memory mapping FD"); + } +} + +static struct perf_event_mmap_page *setup_perf( struct lttng_perf_counter_thread_field *thread_field) { @@ -160,25 +193,10 @@ struct perf_event_mmap_page *setup_perf( thread_field->fd = -1; #endif -end: return perf_addr; } static -void close_perf_fd(int fd) -{ - int ret; - - if (fd < 0) - return; - - ret = close(fd); - if (ret) { - perror("Error closing LTTng-UST perf memory mapping FD"); - } -} - -static void unmap_perf_page(struct perf_event_mmap_page *pc) { int ret; @@ -292,7 +310,7 @@ uint64_t wrapper_perf_counter_re
[lttng-dev] [PATCH lttng-ust 1/2] Keep perf context FD open for other architectures
Instead of closing the perf context after the page has been mapped, keep it open so it can be used with the read() system call if the architecture does not support direct access from user-space. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- liblttng-ust/lttng-context-perf-counters.c | 53 +++--- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 97ddf97..725b1b4 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -55,6 +55,7 @@ struct lttng_perf_counter_thread_field { struct perf_event_mmap_page *pc; struct cds_list_head thread_field_node; /* Per-field list of thread fields (node) */ struct cds_list_head rcu_field_node;/* RCU per-thread list of fields (node) */ + int fd; /* Perf FD */ }; struct lttng_perf_counter_thread { @@ -131,24 +132,50 @@ int sys_perf_event_open(struct perf_event_attr *attr, } static -struct perf_event_mmap_page *setup_perf(struct perf_event_attr *attr) +int open_perf_fd(struct perf_event_attr *attr) { - void *perf_addr; - int fd, ret; + int fd; fd = sys_perf_event_open(attr, 0, -1, -1, 0); if (fd < 0) - return NULL; + return -1; + + return fd; +} + +static +struct perf_event_mmap_page *setup_perf( + struct lttng_perf_counter_thread_field *thread_field) +{ + void *perf_addr; perf_addr = mmap(NULL, sizeof(struct perf_event_mmap_page), - PROT_READ, MAP_SHARED, fd, 0); + PROT_READ, MAP_SHARED, thread_field->fd, 0); if (perf_addr == MAP_FAILED) - return NULL; + perf_addr = NULL; + + /* No need to keep the FD open on x86 */ +#if defined(__x86_64__) || defined(__i386__) + close_perf_fd(thread_field->fd); + thread_field->fd = -1; +#endif + +end: + return perf_addr; +} + +static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + ret = close(fd); if (ret) { perror("Error closing LTTng-UST perf memory mapping FD"); } - return perf_addr; } static @@ -221,7 +248,9 @@ struct lttng_perf_counter_thread_field * if (!thread_field) abort(); thread_field->field = perf_field; - thread_field->pc = setup_perf(_field->attr); + thread_field->fd = open_perf_fd(_field->attr); + if (thread_field->fd >= 0) + thread_field->pc = setup_perf(thread_field); /* Note: thread_field->pc can be NULL if setup_perf() fails. */ ust_lock_nocheck(); cds_list_add_rcu(_field->rcu_field_node, @@ -293,6 +322,7 @@ static void lttng_destroy_perf_thread_field( struct lttng_perf_counter_thread_field *thread_field) { + close_perf_fd(thread_field->fd); unmap_perf_page(thread_field->pc); cds_list_del_rcu(_field->rcu_field_node); cds_list_del(_field->thread_field_node); @@ -341,7 +371,6 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, { struct lttng_ctx_field *field; struct lttng_perf_counter_field *perf_field; - struct perf_event_mmap_page *tmp_pc; char *name_alloc; int ret; @@ -389,12 +418,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, field->u.perf_counter = perf_field; /* Ensure that this perf counter can be used in this process. */ - tmp_pc = setup_perf(_field->attr); - if (!tmp_pc) { + ret = open_perf_fd(_field->attr); + if (ret < 0) { ret = -ENODEV; goto setup_error; } - unmap_perf_page(tmp_pc); + close_perf_fd(ret); /* * Contexts can only be added before tracing is started, so we -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-ust 2/2] Add perf context support for ARMv7
Allow to add perf context to UST traces. ARMv7 does not have a reliable way to read perf PMU counters entirely from user-space like we do on x86, so this approach requires a system call everytime a counter needs to be read which has a significant performance impact. This generic approach might work on other architecture, but it has not yet been tested so it is not enabled in the code. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- configure.ac | 1 + liblttng-ust-ctl/ustctl.c | 2 +- liblttng-ust/lttng-context-perf-counters.c | 71 -- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index de462ff..5475640 100644 --- a/configure.ac +++ b/configure.ac @@ -219,6 +219,7 @@ AS_CASE([$host_cpu], [i[[3456]]86], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [x86_64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [amd64], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], + [armv7l], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=yes], [UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS=no]) AC_MSG_RESULT([$UST_SUPPORT_FOR_ARCH_PERF_EVENT_COUNTERS]) diff --git a/liblttng-ust-ctl/ustctl.c b/liblttng-ust-ctl/ustctl.c index 0165786..97445d5 100644 --- a/liblttng-ust-ctl/ustctl.c +++ b/liblttng-ust-ctl/ustctl.c @@ -1742,7 +1742,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream, return client_cb->instance_id(buf, handle, id); } -#if defined(__x86_64__) || defined(__i386__) +#if defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) int ustctl_has_perf_counters(void) { diff --git a/liblttng-ust/lttng-context-perf-counters.c b/liblttng-ust/lttng-context-perf-counters.c index 725b1b4..220686b 100644 --- a/liblttng-ust/lttng-context-perf-counters.c +++ b/liblttng-ust/lttng-context-perf-counters.c @@ -91,17 +91,13 @@ uint64_t rdpmc(unsigned int counter) return low | ((uint64_t) high) << 32; } -#else /* defined(__x86_64__) || defined(__i386__) */ - -#error "Perf event counters are only supported on x86 so far." - -#endif /* #else defined(__x86_64__) || defined(__i386__) */ - static -uint64_t read_perf_counter(struct perf_event_mmap_page *pc) +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) { uint32_t seq, idx; uint64_t count; + struct perf_event_mmap_page *pc = thread_field->pc; if (caa_unlikely(!pc)) return 0; @@ -122,6 +118,31 @@ uint64_t read_perf_counter(struct perf_event_mmap_page *pc) return count; } +#elif defined (__ARM_ARCH_7A__) + +static +uint64_t read_perf_counter( + struct lttng_perf_counter_thread_field *thread_field) +{ + uint64_t count; + int ret; + + if (caa_unlikely(thread_field->fd < 0)) + return 0; + + ret = read(thread_field->fd, , sizeof(count)); + if (ret < sizeof(count)) + return 0; + + return count; +} + +#else /* defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + +#error "Perf event counters are only supported on x86 and ARMv7 so far." + +#endif /* #else defined(__x86_64__) || defined(__i386__) || defined(__ARM_ARCH_7A__) */ + static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, @@ -144,6 +165,20 @@ int open_perf_fd(struct perf_event_attr *attr) } static +void close_perf_fd(int fd) +{ + int ret; + + if (fd < 0) + return; + + ret = close(fd); + if (ret) { + perror("Error closing LTTng-UST perf memory mapping FD"); + } +} + +static struct perf_event_mmap_page *setup_perf( struct lttng_perf_counter_thread_field *thread_field) { @@ -160,25 +195,10 @@ struct perf_event_mmap_page *setup_perf( thread_field->fd = -1; #endif -end: return perf_addr; } static -void close_perf_fd(int fd) -{ - int ret; - - if (fd < 0) - return; - - ret = close(fd); - if (ret) { - perror("Error closing LTTng-UST perf memory mapping FD"); - } -} - -static void unmap_perf_page(struct perf_event_mmap_page *pc) { int ret; @@ -292,7 +312,7 @@ uint64_t wrapper_perf_counter_read(struct lttng_ctx_field *field) perf_field = field->u.perf_counter; perf_thread_field = get_thread_field(perf_field); - return read_perf_counter(perf_thread_field->pc); + return read_perf_counter(perf_thread_field); } static @@ -413,7 +433,12 @@ int lttng_add_perf_counter_to_ctx(uint32_t type, perf_field->attr.type = type; perf_field->attr.config = config; +#if defined (__ARM_ARCH_7A__) + /* exclude_kernel does not work on ARM. */ + perf_
[lttng-dev] [RELEASE] LTTng-analyses v0.4.4
Hi everyone, We are glad to announce the first stable release of the lttng-analyses ! https://github.com/lttng/lttng-analyses This project is a collection of tools to extract metrics and high-level informations from offline LTTng kernel traces to investigate complex problems. This is a release from the new stable-0.4 branch created to support users of the integration with Trace Compass 2.0. So the changes are only backports of fixes already in master and v0.5, the most interesting ones are: - backport of the progress bar in MI mode, - fix the schedfreq analyse in MI, - Travis CI integration. We encourage you to test it and check out the integration in Trace Compass to see the power of combining an interactive graphical tool to these analyses. As always, we appreciate all kinds of feedback, use-cases and real-world experiences, so please test it and let us know what you think about it. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v2 3/3] Create a dedicated test suite for Perf
Introduce the perf_regression test suite that must be run manually to check if the support for the Perf-related features are available on the current machine. This test cannot be run automatically since there are some platforms where it can fail. For now, the test only makes sure that we can trace events with perf contexts enabled by raw ID in kernel and user-space. The test only works if libpfm is installed on the system and fails if it is not installed. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .gitignore | 1 + README.md| 2 + configure.ac | 8 +++ tests/Makefile.am| 8 +-- tests/perf/Makefile.am | 6 +++ tests/perf/find_event.c | 83 ++ tests/perf/test_perf_raw | 129 +++ tests/perf_regression| 1 + 8 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 tests/perf/Makefile.am create mode 100644 tests/perf/find_event.c create mode 100755 tests/perf/test_perf_raw create mode 100644 tests/perf_regression diff --git a/.gitignore b/.gitignore index ac78292..c31dbc5 100644 --- a/.gitignore +++ b/.gitignore @@ -106,6 +106,7 @@ tests/regression/ust/python-logging/test_python_logging /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef /tests/regression/tools/live/live_test /tests/unit/ini_config/ini_config +/tests/perf/find_event # man pages /doc/man/*.1 diff --git a/README.md b/README.md index 22de252..3156a15 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ The following items are _optional_ dependencies: pages with the `--help` option or with the `lttng help` command. Note that without `man`, you cannot get offline help with LTTng-tools commands, not even their usage. + - **`libpfm`**: needed to run the perf regression test suite. +- Debian/Ubuntu package: `libpfm4-dev` LTTng-tools supports both the [LTTng Linux Kernel tracer](https://lttng.org) and [LTTng user space tracer](https://lttng.org) released as part of the same diff --git a/configure.ac b/configure.ac index d6149fe..5d5f001 100644 --- a/configure.ac +++ b/configure.ac @@ -467,6 +467,13 @@ AC_CHECK_LIB([c], [open_memstream], ] ) +# check for libpfm +AC_CHECK_LIB([pfm], [pfm_initialize], +[ + have_libpfm=yes + ]) +AM_CONDITIONAL([LTTNG_TOOLS_BUILD_WITH_LIBPFM], [test "x$have_libpfm" = "xyes"]) + AC_ARG_ENABLE([git-version], [AC_HELP_STRING([--disable-git-version], [Do not use the git version for the build])], @@ -1005,6 +1012,7 @@ AC_CONFIG_FILES([ tests/regression/ust/clock-override/Makefile tests/regression/ust/type-declarations/Makefile tests/regression/ust/rotation-destroy-flush/Makefile + tests/regression/ust/perf/Makefile tests/stress/Makefile tests/unit/Makefile tests/unit/ini_config/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index 3600e99..d460fb6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,8 +1,8 @@ SUBDIRS = -DIST_SUBDIRS = utils regression unit stress destructive +DIST_SUBDIRS = utils regression unit stress destructive perf if BUILD_TESTS -SUBDIRS += . utils regression unit stress destructive +SUBDIRS += . utils regression unit stress destructive perf if HAS_PGREP check-am: $(top_srcdir)/tests/utils/warn_processes.sh $(PGREP) @@ -14,8 +14,8 @@ else endif -dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests -EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests +dist_noinst_SCRIPTS = run.sh fast_regression long_regression root_regression root_destructive_tests perf_regression +EXTRA_DIST = run.sh fast_regression long_regression root_regression README root_destructive_tests perf_regression all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/perf/Makefile.am b/tests/perf/Makefile.am new file mode 100644 index 000..40bb754 --- /dev/null +++ b/tests/perf/Makefile.am @@ -0,0 +1,6 @@ +if LTTNG_TOOLS_BUILD_WITH_LIBPFM +LIBS += -lpfm + +noinst_PROGRAMS = find_event +find_event_SOURCES = find_event.c +endif diff --git a/tests/perf/find_event.c b/tests/perf/find_event.c new file mode 100644 index 000..ae63800 --- /dev/null +++ b/tests/perf/find_event.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Julien Desfossez <jdesfos...@efficios.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * as published by the Free Software Foundation; only version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICU
[lttng-dev] [PATCH lttng-tools v2 1/3] Enable perf PMU counters by raw ID
Allow enabling perf PMU counters by raw ID in addition to the generic list already provided. The format for kernel tracing is "perf:cpu:raw:rNNN:" and "perf:thread:raw:rNNN: for user-space. The rNNN format is the same as perf-record(1) where NNN is a hexadecimal event descriptor in the form of umask+eventsel. The field allows the user to give a more friendly name. Example usage on Intel i7-3520M to get the unhalted reference cycles (eventsel: 0x13c) count at privilege level 0 (umask: 0x00): lttng add-context -k -t perf:cpu:raw:r0013c:x86unhalted Result in the trace: sched_switch: { cpu_id = 3 }, { perf_cpu_raw_r0013c_x86unhalted = 27632578 }, [...] Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- doc/man/lttng-add-context.1.txt | 8 +++ src/bin/lttng/commands/add_context.c | 94 +++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/doc/man/lttng-add-context.1.txt b/doc/man/lttng-add-context.1.txt index f995a7f..c43581a 100644 --- a/doc/man/lttng-add-context.1.txt +++ b/doc/man/lttng-add-context.1.txt @@ -45,6 +45,14 @@ per-thread (`perf:thread:` prefix) counters. Currently, per-CPU counters can only be used in the Linux kernel tracing domain, while per-thread counters can only be used in the user space tracing domain. +It is also possible to enable PMU counters by raw ID using the +`perf:cpu:raw:r:` or `perf:thread:raw:r:` format for the +kernel and user-space respectively. `` is a hexadecimal event descriptor +which is the same format as perf-record(1): a concatenation of the `Umask +value` and `Event number` provided by the processors manufacturer. The possible +values for this field are processor-specific. The `` field is used to +give a symbolic name to the counter in the trace. + Application-specific context fields can be added to a channel using the following syntax: diff --git a/src/bin/lttng/commands/add_context.c b/src/bin/lttng/commands/add_context.c index 2f43dc7..711c1e0 100644 --- a/src/bin/lttng/commands/add_context.c +++ b/src/bin/lttng/commands/add_context.c @@ -87,6 +87,7 @@ enum perf_type { PERF_TYPE_HARDWARE = 0, PERF_TYPE_SOFTWARE = 1, PERF_TYPE_HW_CACHE = 3, + PERF_TYPE_RAW = 4, }; enum perf_count_hard { @@ -688,9 +689,88 @@ end: } static +int find_ctx_type_perf_raw(const char *ctx, struct ctx_type *type) +{ + char *next; + int ret; + int field_pos = 0; + char *tmp_list; + + tmp_list = strdup(ctx); + if (!tmp_list) { + PERROR("strdup temp list"); + ret = -ENOMEM; + goto error; + } + + /* Looking for "perf:[cpu|thread]:raw::". */ + for (;;) { + next = strtok(tmp_list, ":"); + if (!next) { + break; + } + tmp_list = NULL; + switch (field_pos) { + case 0: + if (strncmp(next, "perf", 4) != 0) { + ret = -1; + goto end; + } + break; + case 1: + if (strncmp(next, "cpu", 3) == 0) { + type->opt->ctx_type = CONTEXT_PERF_CPU_COUNTER; + } else if (strncmp(next, "thread", 4) == 0) { + type->opt->ctx_type = CONTEXT_PERF_THREAD_COUNTER; + } else { + ret = -1; + goto end; + } + break; + case 2: + if (strncmp(next, "raw", 3) != 0) { + ret = -1; + goto end; + } + break; + case 3: + if (strlen(next) < 2 || next[0] != 'r') { + ERR("Wrong perf raw mask format: rNNN"); + ret = -1; + goto end; + } + type->opt->u.perf.config = strtoll(next + 1, NULL, 16); + break; + case 4: + /* name */ + break; + case 5: + ERR("Too many ':' in perf raw format"); + ret = -1; + goto end; + }; + field_pos++; + } + + if (field_pos < 5) { + ERR("Wrong perf raw format"); + ret = -1; + goto end; + } + + ret = 0; + goto end; + +end: + free(tmp_list); +error: + return ret; +} + +static struct ctx_type *get_context_type(const c
[lttng-dev] [PATCH lttng-tools] Test add-context perf raw command
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/fast_regression | 1 + tests/regression/ust/test_perf_raw | 103 + 2 files changed, 104 insertions(+) create mode 100755 tests/regression/ust/test_perf_raw diff --git a/tests/fast_regression b/tests/fast_regression index 0c4f079..a3084d5 100644 --- a/tests/fast_regression +++ b/tests/fast_regression @@ -30,3 +30,4 @@ regression/ust/clock-override/test_clock_override regression/ust/rotation-destroy-flush/test_rotation_destroy_flush regression/ust/test_event_basic regression/ust/test_event_tracef +regression/ust/test_perf_raw diff --git a/tests/regression/ust/test_perf_raw b/tests/regression/ust/test_perf_raw new file mode 100755 index 000..00d7c52 --- /dev/null +++ b/tests/regression/ust/test_perf_raw @@ -0,0 +1,103 @@ +#!/bin/bash +# +# Copyright (C) - 2016 Julien Desfossez <jdesfos...@efficios.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +TEST_DESC="UST tracer - Perf counters" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../.. +LTTNG_BIN="lttng" +SESSION_NAME="perf_counters" +EVENT_NAME="tp:tptest" +NUM_TESTS=15 +NR_ITER=1 +NR_USEC_WAIT=1 +TESTAPP_PATH="$TESTDIR/utils/testapp" +TESTAPP_NAME="gen-ust-events" +TESTAPP_BIN="$TESTAPP_PATH/$TESTAPP_NAME/$TESTAPP_NAME" + +source $TESTDIR/utils/utils.sh + +function enable_ust_lttng_event_per_chan() +{ + sess_name="$1" + event_name="$2" + chan_name="$3" + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" -s $sess_name -c $chan_name -u >/dev/null 2>&1 + ok $? "Enable event $event_name for session $sess_name in channel $chan_name" +} + +function add_ust_lttng_context_ok() +{ + sess_name="$1" + chan_name="$2" + type="$3" + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN add-context -s $sess_name -c $chan_name -t $type -u >/dev/null 2>&1 + ok $? "Add context $type for session $sess_name in channel $chan_name" +} + +function add_ust_lttng_context_fail() +{ + sess_name="$1" + chan_name="$2" + type="$3" + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN add-context -s $sess_name -c $chan_name -t $type -u >/dev/null 2>&1 + test $? -ne "4" + ok $? "Add context $type for session $sess_name in channel $chan_name failed as expected" +} + +# Only test parsing since this feature depends on the counters available on +# specifics processors and does not work in VM. +function test_parsing_raw() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="ust_event_basic" + CHAN_NAME="mychan" + + create_lttng_session_ok $SESSION_NAME $TRACE_PATH + + enable_ust_lttng_channel_ok $SESSION_NAME $CHAN_NAME + + enable_ust_lttng_event_per_chan $SESSION_NAME $EVENT_NAME $CHAN_NAME + + add_ust_lttng_context_ok $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:test" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:b0110:test" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110::" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r:test" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r::" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw::" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw" + add_ust_lttng_context_fail $SESSION_NAME $CHAN_NAME "perf:thread:raw:r0110:test:wrong" + + destroy_lttng_session_ok $SESSION_NAME + + rm -rf $TRACE_PATH +} + +# MUST set TESTDIR before calling those functions +plan_tests $NUM_TESTS + +print_test_banner "$TEST_DESC" + +start_lttng_sessiond + +test_parsing_raw + +stop_lttng_sessiond -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools] Enable perf PMU counters by raw ID
Allow enabling perf PMU counters by raw ID in addition to the generic list already provided. The format for kernel tracing is "perf:cpu:raw:rNNN:" and "perf:thread:raw:rNNN: for user-space. The rNNN format is the same as perf-record(1) where NNN is a hexadecimal event descriptor in the form of umask+eventsel. The field allows the user to give a more friendly name. Example usage on Intel i7-3520M to get the unhalted reference cycles (eventsel: 0x13c) count at privilege level 0 (umask: 0x00): lttng add-context -k -t perf:cpu:raw:r0013c:x86unhalted Result in the trace: sched_switch: { cpu_id = 3 }, { perf_cpu_raw_r0013c_x86unhalted = 27632578 }, [...] Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- doc/man/lttng-add-context.1.txt | 7 +++ include/lttng/event.h| 2 + src/bin/lttng-sessiond/context.c | 1 + src/bin/lttng-sessiond/trace-ust.c | 1 + src/bin/lttng/commands/add_context.c | 94 +++- 5 files changed, 104 insertions(+), 1 deletion(-) diff --git a/doc/man/lttng-add-context.1.txt b/doc/man/lttng-add-context.1.txt index f995a7f..4779672 100644 --- a/doc/man/lttng-add-context.1.txt +++ b/doc/man/lttng-add-context.1.txt @@ -45,6 +45,13 @@ per-thread (`perf:thread:` prefix) counters. Currently, per-CPU counters can only be used in the Linux kernel tracing domain, while per-thread counters can only be used in the user space tracing domain. +It is also possible to enable PMU counters by raw ID using the +`perf:cpu:raw:rNNN:` or `perf:thread:raw:rNNN:` format for the +kernel and user-space respectively. `NNN` is a hexadecimal event descriptor +(umask+eventsel) just like with perf-record(1), the possible values for this +field are processor-specific. The `` field is used to give a symbolic +name to the counter in the trace. + Application-specific context fields can be added to a channel using the following syntax: diff --git a/include/lttng/event.h b/include/lttng/event.h index 16b4d4f..398f94c 100644 --- a/include/lttng/event.h +++ b/include/lttng/event.h @@ -142,6 +142,8 @@ enum lttng_event_context_type { LTTNG_EVENT_CONTEXT_PREEMPTIBLE = 17, LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE = 18, LTTNG_EVENT_CONTEXT_MIGRATABLE = 19, + LTTNG_EVENT_CONTEXT_PERF_CPU_RAW= 20, + LTTNG_EVENT_CONTEXT_PERF_THREAD_RAW = 21, }; enum lttng_event_field_type { diff --git a/src/bin/lttng-sessiond/context.c b/src/bin/lttng-sessiond/context.c index 9c3a394..81089b1 100644 --- a/src/bin/lttng-sessiond/context.c +++ b/src/bin/lttng-sessiond/context.c @@ -227,6 +227,7 @@ int context_kernel_add(struct ltt_kernel_session *ksession, break; case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: case LTTNG_EVENT_CONTEXT_PERF_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_CPU_RAW: kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER; break; case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE: diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 1c325fb..b75d11b 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -541,6 +541,7 @@ int trace_ust_context_type_event_to_ust( utype = LTTNG_UST_CONTEXT_IP; break; case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_THREAD_RAW: if (!ustctl_has_perf_counters()) { utype = -1; WARN("Perf counters not implemented in UST"); diff --git a/src/bin/lttng/commands/add_context.c b/src/bin/lttng/commands/add_context.c index 2f43dc7..4db9bd2 100644 --- a/src/bin/lttng/commands/add_context.c +++ b/src/bin/lttng/commands/add_context.c @@ -78,6 +78,8 @@ enum context_type { CONTEXT_PREEMPTIBLE = 17, CONTEXT_NEED_RESCHEDULE = 18, CONTEXT_MIGRATABLE = 19, + CONTEXT_PERF_CPU_RAW = 20, + CONTEXT_PERF_THREAD_RAW = 21, }; /* @@ -87,6 +89,7 @@ enum perf_type { PERF_TYPE_HARDWARE = 0, PERF_TYPE_SOFTWARE = 1, PERF_TYPE_HW_CACHE = 3, + PERF_TYPE_RAW = 4, }; enum perf_count_hard { @@ -564,6 +567,8 @@ static int add_context(char *session_name) case LTTNG_EVENT_CONTEXT_PERF_COUNTER: case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_CPU_RAW: + case LTTNG_EVENT_CONTEXT_PERF_THREAD_RAW: context.u.perf_counter.type = type->opt->u.perf.type; context.u.perf_counter.config = type->opt->u.perf.config; strncpy(context.u.perf_counter.name, type->opt->symbol, @@ -688,9 +693,88 @@ end: } static +int find_ctx_type_perf_raw(const char *ctx, struct ctx_type *type) +{ +
Re: [lttng-dev] Duplicate traces in multiple sessions
Hi, > We are using LTTng to collect traces from our non-stopping service (our > service is running 24/7, highly available). We collect traces by rotate > the trace in an interval. We do this by creating new session, stop the > old session, and process the old traces, every 10 minutes. > There are overlaps on the session since we create new session before > stopping the old session. We are seeing some traces exist in both the > old session, and new session. This is expected. We also noticed that > these duplicated traces could have slightly different timestamp in the > two sessions, so it is very difficult to do post-processing to remove > the duplicates. Yes, this is normal since you are enabling 2 probes during the overlap and each probe reads its own timestamp. > Assuming we could read the raw binary trace files, we would like to know > whether this is any way to identify the duplicating traces. Is there any > kind of unique id or hash that could be used to identity the duplicate > traces in two sessions? There is currently no clean way to match those duplicate events. We have already discussed about the kind of use-case you are talking about and we have an idea to introduce a kind of "rotate" command for a session. This would allow to make a clean transition to a new set of trace files with no overlap, but it is not on our short term priority list. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] "lttng enable-channel --tracefile-size" bug
> thanks, just one more question, I would think that it would be more > efficient to have multiple sub-buffers writing to a file versus one > sub-buffer to one file,. Of course, when the file gets overwritten > (rolled-over by the tracefile-count option) multiple sub-buffers are > lost. Do you have any use case recommendation? John It all depends on your use-case, usually the tracefile-count option is used to keep an relatively short time-frame history on disk, so the size you keep on disk is dependant on how long you want this history to be and the rate at which events are recorded. The sub-buffer size is not directly related to this option, when a tracefile is overwritten all its content is truncated regardless the number of sub-buffers. So having 10 sub-buffers of 4k or 1 sub-buffer of 40k is basically the same thing for the tracefile rotation. In terms of performance, handling the rotation adds some work for the consumerd after extracting the data, so if it is too frequent, you might see more discarded events. On the other hand, if your tracefiles are really big, when you overwrite one, you loose a lot of old data (more or less old depending on the tracefile-count option). So it really is a tradeoff you have to think about with your use-case. I hope it clarifies the situation. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [RELEASE] LTTng-analyses v0.5
Hi everyone, We are glad to announce a new release of the lttng-analyses ! https://github.com/lttng/lttng-analyses This project is a collection of tools to extract metrics and high-level informations from offline LTTng kernel traces to investigate complex problems. The main changes in this release are: - The integration of the stream intersect mode from Babeltrace (enabled by default if available). This limits the analysis time-range to only the section of the trace where we have trace data for all the processors. This feature is required to make sure we have consistent information across all CPUs, a warning is displayed if the feature is not available and users and encouraged to update their Babeltrace installation; - Various internal improvements to the MI format and working integration with Trace Compass; - The machine interface (now named LAMI) specification is now is its own repository: https://github.com/lttng/lami-spec; - Automated tests (unit and integration), EfficiOS CI integration; - Code cleanup and bugfixes. As always, we appreciate all kinds of feedback, use-cases and real-world experiences, so please test it and let us know what you think about it. Thanks, Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] "lttng enable-channel --tracefile-size" bug
> Julien, > thanks, I was mislead by the 2.7 documentation saying: > "...parameters > of |enable-channel| are |--tracefile-size|and |--tracefile-count|, which > respectively limit the size of each trace file and the their count for a > given channel. " > In this case the tracefile-size option should be removed, will it become > useful in the future releases or has a more subtle use? No, the tracefile-size options does what it says, the limitation is that the smallest unit it can work with is the subbuf-size. So the smallest tracefile size you can have is the subbuf-size. If you are using 4k subbuffers and you limit the size of the tracefiles to 4M, then you will have at most 1000 full packets in each tracefile. But if you have subbuffers of 8M, the smallest tracefile size you can have is 8M. Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Re: [lttng-dev] "lttng enable-channel --tracefile-size" bug
> Hi, > it looks like for the "enable-channel" command, "tracefile-size" option > doesn't take effect, bellow are all the options, the resulted files have > the actual size the same as the size specified by subbuf-size option: > > # lttng -V > lttng (LTTng Trace Control) 2.7.1 - Herbe à Détourne > > $ lttng enable-channel chan_name -u -s session_name --discard > --num-subbuf 8 > --subbuf-size 32M --tracefile-size 8K --tracefile-count 8 > --buffers-pid Yes, that is the expected behaviour, we work with packets (sub-buffers), so the smallest unit we can store is the subbuf-size. With 2.7.3 I get this warning when I try your command: Warning: Tracefile size rounded up from (8192) to subbuffer size (33554432) Julien ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-tools v3] Test for select, poll and epoll syscall overrides
This test for root_regression checks if the syscall overrides for select, pselect6, poll, ppoll, epoll_ctl, epoll_wait and epoll_pwait work as expected on arm and x86 (32 and 64-bit). There are 11 test cases that check for normal and abnormal behaviour. If the test system has the Babeltrace python bindings, the test validates the content of the events, otherwise only the presence of the generated events is checked. We also check if kernel OOPS, WARNING or BUG were generated during the test. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am| 7 +- tests/regression/kernel/select_poll_epoll.c| 904 + tests/regression/kernel/test_select_poll_epoll | 398 + .../kernel/validate_select_poll_epoll.py | 783 ++ tests/root_regression | 1 + 5 files changed, 2092 insertions(+), 1 deletion(-) create mode 100644 tests/regression/kernel/select_poll_epoll.c create mode 100755 tests/regression/kernel/test_select_poll_epoll create mode 100755 tests/regression/kernel/validate_select_poll_epoll.py diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index 36ff6ee..023c4c6 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,4 +1,9 @@ -EXTRA_DIST = test_event_basic test_all_events test_syscall +noinst_PROGRAMS = select_poll_epoll +select_poll_epoll_SOURCES = select_poll_epoll.c +select_poll_epoll_LDADD = -lpthread -lpopt +select_poll_epoll_CFLAGS = -fno-stack-protector -D_FORTIFY_SOURCE=0 + +EXTRA_DIST = test_event_basic test_all_events test_syscall test_select_poll_epoll all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/kernel/select_poll_epoll.c b/tests/regression/kernel/select_poll_epoll.c new file mode 100644 index 000..d99c2f6 --- /dev/null +++ b/tests/regression/kernel/select_poll_epoll.c @@ -0,0 +1,904 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 +#define NB_FD 1 +#define MAX_FDS 2047 +#define NR_ITER 1000 /* for stress-tests */ + +#define MIN_NR_FDS 5 /* the minimum number of open FDs required for the test to run */ +#define BIG_SELECT_FD 1022 + +#define MSEC_PER_USEC 1000 +#define MSEC_PER_NSEC (MSEC_PER_USEC * 1000) + +static int timeout; /* seconds, -1 to disable */ +static int stop_thread; +static int wait_fd; + +struct ppoll_thread_data { + struct pollfd *ufds; + int value; +}; + +void test_select_big(void) +{ + fd_set rfds, wfds, exfds; + struct timeval tv; + int ret; + int fd2; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_ZERO(); + FD_ZERO(); + + fd2 = dup2(wait_fd, BIG_SELECT_FD); + if (fd2 < 0) { + perror("dup2"); + goto end; + } + FD_SET(fd2, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * MSEC_PER_USEC; + + if (timeout > 0) { + ret = select(fd2 + 1, , , , ); + } else { + ret = select(fd2 + 1, , , , NULL); + } + + if (ret == -1) { + perror("select()"); + } else if (ret) { + printf("# [select] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[select] read"); + } + } else { + printf("# [select] timeout\n"); + } + + ret = close(BIG_SELECT_FD); + if (ret) + perror("close"); + +end: + return; +} + +void test_pselect(void) +{ + fd_set rfds; + struct timespec tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_nsec = timeout * MSEC_PER_NSEC; + + if (timeout > 0) { + ret = pselect(1, , NULL, NULL, , NULL); + } else { + ret = pselect(1, , NULL, NULL, NULL, NULL); + } + + if (ret == -1) { + perror("pselect()"); + } else if (ret) { + printf("# [pselect] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[pselect] read"); + } + } else { + printf("# [pselect] timeout\n"); + } + +} + +void test_select(void) +{ + fd_set rfds; + struct timeval tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * MSEC_PER_USEC; + +
[lttng-dev] [PATCH lttng-tools v2] Test for select, poll and epoll syscall overrides
This test for root_regression checks if the syscall overrides for select, pselect6, poll, ppoll, epoll_ctl, epoll_wait and epoll_pwait work as expected on arm and x86 (32 and 64-bit). There are 11 test cases that check for normal and abnormal behaviour. If the test system has the Babeltrace python bindings, the test validates the content of the events, otherwise only the presence of the generated events is checked. We also check if kernel OOPS, WARNING or BUG were generated during the test. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am| 7 +- tests/regression/kernel/select_poll_epoll.c| 901 + tests/regression/kernel/test_select_poll_epoll | 420 ++ .../kernel/validate_select_poll_epoll.py | 783 ++ tests/root_regression | 1 + 5 files changed, 2111 insertions(+), 1 deletion(-) create mode 100644 tests/regression/kernel/select_poll_epoll.c create mode 100755 tests/regression/kernel/test_select_poll_epoll create mode 100755 tests/regression/kernel/validate_select_poll_epoll.py diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index 36ff6ee..023c4c6 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,4 +1,9 @@ -EXTRA_DIST = test_event_basic test_all_events test_syscall +noinst_PROGRAMS = select_poll_epoll +select_poll_epoll_SOURCES = select_poll_epoll.c +select_poll_epoll_LDADD = -lpthread -lpopt +select_poll_epoll_CFLAGS = -fno-stack-protector -D_FORTIFY_SOURCE=0 + +EXTRA_DIST = test_event_basic test_all_events test_syscall test_select_poll_epoll all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/kernel/select_poll_epoll.c b/tests/regression/kernel/select_poll_epoll.c new file mode 100644 index 000..2efeea2 --- /dev/null +++ b/tests/regression/kernel/select_poll_epoll.c @@ -0,0 +1,901 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 +#define NB_FD 1 +#define MAX_FDS 2047 +#define NR_ITER 1000 /* for stress-tests */ + +#define MIN_NR_FDS 5 /* the minimum number of open FDs required for the test to run */ +#define BIG_SELECT_FD 1022 + +#define MSEC_PER_USEC 1000 +#define MSEC_PER_NSEC MSEC_PER_USEC * 1000 + +static int timeout; /* seconds, -1 to disable */ +static int stop_thread; +static int wait_fd; + +struct ppoll_thread_data { + struct pollfd *ufds; + int value; +}; + +void test_select_big(void) +{ + fd_set rfds, wfds, exfds; + struct timeval tv; + int ret; + int fd2; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_ZERO(); + FD_ZERO(); + + fd2 = dup2(wait_fd, BIG_SELECT_FD); + FD_SET(fd2, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * MSEC_PER_USEC; + + if (timeout > 0) { + ret = select(fd2 + 1, , , , ); + } else { + ret = select(fd2 + 1, , , , NULL); + } + + if (ret == -1) { + perror("select()"); + } else if (ret) { + printf("# [select] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[select] read"); + } + } else { + printf("# [select] timeout\n"); + } + + ret = close(BIG_SELECT_FD); + if (ret) + perror("close"); +} + +void test_pselect(void) +{ + fd_set rfds; + struct timespec tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_nsec = timeout * MSEC_PER_NSEC; + + if (timeout > 0) { + ret = pselect(1, , NULL, NULL, , NULL); + } else { + ret = pselect(1, , NULL, NULL, NULL, NULL); + } + + if (ret == -1) { + perror("pselect()"); + } else if (ret) { + printf("# [pselect] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[pselect] read"); + } + } else { + printf("# [pselect] timeout\n"); + } + +} + +void test_select(void) +{ + fd_set rfds; + struct timeval tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * MSEC_PER_USEC; + + if (timeout > 0) { + ret = select(1, , NULL, NULL, ); + } else { + r
[lttng-dev] [PATCH lttng-tools] Test for select, poll and epoll syscall overrides
This test for root_regression checks if the syscall overrides for select, pselect6, poll, ppoll, epoll_ctl, epoll_wait and epoll_pwait work as expected on arm and x86 (32 and 64-bit). There are 11 test cases that check for normal and abnormal behaviour. If the test system has the Babeltrace python bindings, the test validates the content of the events, otherwise only the presence of the generated events is checked. We also check if kernel OOPS, WARNING or BUG were generated during the test. Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- tests/regression/kernel/Makefile.am| 7 +- tests/regression/kernel/select_poll_epoll.c| 872 + tests/regression/kernel/test_select_poll_epoll | 420 ++ .../kernel/validate_select_poll_epoll.py | 783 ++ tests/root_regression | 1 + 5 files changed, 2082 insertions(+), 1 deletion(-) create mode 100644 tests/regression/kernel/select_poll_epoll.c create mode 100755 tests/regression/kernel/test_select_poll_epoll create mode 100755 tests/regression/kernel/validate_select_poll_epoll.py diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index 36ff6ee..023c4c6 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,4 +1,9 @@ -EXTRA_DIST = test_event_basic test_all_events test_syscall +noinst_PROGRAMS = select_poll_epoll +select_poll_epoll_SOURCES = select_poll_epoll.c +select_poll_epoll_LDADD = -lpthread -lpopt +select_poll_epoll_CFLAGS = -fno-stack-protector -D_FORTIFY_SOURCE=0 + +EXTRA_DIST = test_event_basic test_all_events test_syscall test_select_poll_epoll all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/kernel/select_poll_epoll.c b/tests/regression/kernel/select_poll_epoll.c new file mode 100644 index 000..9a46191 --- /dev/null +++ b/tests/regression/kernel/select_poll_epoll.c @@ -0,0 +1,872 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 256 +#define NB_FD 1 +#define MAX_FDS 2047 +#define NR_ITER 1000 /* for stress-tests */ + +static int timeout; /* seconds, -1 to disable */ +static int stop_thread; +static int wait_fd; + +struct ppoll_thread_data { + struct pollfd *ufds; + int value; +}; + +void test_select_big() +{ + fd_set rfds, wfds, exfds; + struct timeval tv; + int ret; + int fd2; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_ZERO(); + FD_ZERO(); + + fd2 = dup2(wait_fd, 1022); + FD_SET(fd2, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + + if (timeout > 0) + ret = select(fd2 + 1, , , , ); + else + ret = select(fd2 + 1, , , , NULL); + + if (ret == -1) { + perror("select()"); + } else if (ret) { + printf("# [select] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[select] read"); + } + } else { + printf("# [select] timeout\n"); + } +} + +void test_pselect() +{ + fd_set rfds; + struct timespec tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_nsec = 1000 * 1000* timeout; + + if (timeout > 0) + ret = pselect(1, , NULL, NULL, , NULL); + else + ret = pselect(1, , NULL, NULL, NULL, NULL); + + if (ret == -1) { + perror("pselect()"); + } else if (ret) { + printf("# [pselect] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[pselect] read"); + } + } else { + printf("# [pselect] timeout\n"); + } + +} + +void test_select() +{ + fd_set rfds; + struct timeval tv; + int ret; + char buf[BUF_SIZE]; + + FD_ZERO(); + FD_SET(wait_fd, ); + + tv.tv_sec = 0; + tv.tv_usec = timeout * 1000; + + if (timeout > 0) + ret = select(1, , NULL, NULL, ); + else + ret = select(1, , NULL, NULL, NULL); + + if (ret == -1) { + perror("select()"); + } else if (ret) { + printf("# [select] data available\n"); + ret = read(wait_fd, buf, BUF_SIZE); + if (ret < 0) { + perror("[select] read"); + } + } else { +
[lttng-dev] [PATCH lttng-modules v7 2/5] Extract the FD sets in select and pselect6
Instead of extracting the user-space pointers of the 3 fd_set, we now extract the bitmask of the FDs in the sets (in, out, ex) in the form of an array of uint8_t (1024 FDs is the limit in the kernel). In this example, we select in input FDs 5 to 19 (0x0), it returns that one FD is ready: FD 12 (0x1000). syscall_entry_select: { n = 20, _fdset_in_length = 3, fdset_in = [ [0] = 0xF0, [1] = 0xFF, [2] = 0xF ], _fdset_out_length = 0, fdset_out = [ ], _fdset_ex_length = 0, fdset_ex = [ ], tvp = 0 } syscall_exit_select: { ret = 1, _fdset_in_length = 3, fdset_in = [ [0] = 0x0, [1] = 0x10, [2] = 0x0 ], _fdset_out_length = 0, fdset_out = [ ], _fdset_ex_length = 0, fdset_ex = [ ], tvp = 0 } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 248 + 1 file changed, 248 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index bf5c632..b9dd54a 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -53,4 +53,252 @@ SC_LTTNG_TRACEPOINT_EVENT(pipe2, ) ) +#define LTTNG_SYSCALL_SELECT_locvar\ + unsigned long *fds_in, *fds_out, *fds_ex; \ + unsigned long nr_bytes, nr_ulong; \ + uint8_t overflow; + +#define LTTNG_SYSCALL_SELECT_code_pre \ + sc_inout( \ + { \ + int err; \ + unsigned int n_in_bytes; \ + \ + tp_locvar->fds_in = NULL; \ + tp_locvar->fds_out = NULL; \ + tp_locvar->fds_ex = NULL; \ + tp_locvar->overflow = 0; \ + \ + sc_out( \ + if (ret <= 0) \ + goto error; \ + ) \ + \ + if (n <= 0) \ + goto error; \ + \ + /* On error or bogus input, don't copy anything. */ \ + if (n >__FD_SETSIZE) \ + goto error; \ + \ + n_in_bytes = DIV_ROUND_UP((unsigned int) n, BITS_PER_BYTE); \ + \ + /* \ +* Limit atomic memory allocation to one page, since n \ +* is limited to 1024 and the smallest page size on Linux \ +* is 4k, this should not happen, don't try to make it work. \ +*/ \ + if (n_in_bytes > PAGE_SIZE) { \ + WARN_ON_ONCE(1); \ + /* Inform the user that we did not output everything. */\ + tp_locvar->overflow = 1; \ + goto error; \ + } else { \ + tp_locvar->nr_bytes = n_in_bytes; \ + tp_locvar->nr_ulong = DIV_ROUND_UP(n_in_bytes, \ +
[lttng-dev] [PATCH lttng-modules v7 4/5] Extract the payload for epoll_ctl
Map the operation to its name (EPOLL_CTL_*), extract the standard event flags (EPOLL*) and output the data in two different formats: FD as an int in decimal, and u64 in hex. The less standard event flags are not extracted yet, but we extract the raw value in hex for more advanced analyses. Here is an example output: syscall_entry_epoll_ctl: { epfd = 4, op_enum = ( "EPOLL_CTL_ADD" : container = 1 ), fd = 0, event = { raw_events = 0x8003, events = { EPOLLIN = 1, EPOLLPRI = 1, EPOLLOUT = 0, EPOLLERR = 0, padding = 0 }, data_union = { u64 = 0x0, fd = 0 } } } syscall_exit_epoll_ctl: { ret = 0 } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 140 + 1 file changed, 140 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index 2ffe814..636287f 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -555,4 +555,144 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll, ) #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ +#include + +SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op, + TP_ENUM_VALUES( + ctf_enum_value("EPOLL_CTL_ADD", EPOLL_CTL_ADD) + ctf_enum_value("EPOLL_CTL_DEL", EPOLL_CTL_DEL) + ctf_enum_value("EPOLL_CTL_MOD", EPOLL_CTL_MOD) + ) +) + +#ifndef ONCE_LTTNG_TRACE_EPOLL_CTL_H +#define ONCE_LTTNG_TRACE_EPOLL_CTL_H + +#define LTTNG_EPOLL_NRFLAGS (POLLHUP + 1) +#define EPOLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \ + ilog2(LTTNG_EPOLL_NRFLAGS - 1) + +/* + * Only extract the values specified by iBCS2 for now. + */ +static struct lttng_event_field lttng_epoll_ctl_events_fields[] = { + /* 0x0001 */ + [ilog2(POLLIN)] = { + .name = "EPOLLIN", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0002 */ + [ilog2(POLLPRI)] = { + .name = "EPOLLPRI", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0004 */ + [ilog2(POLLOUT)] = { + .name = "EPOLLOUT", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0008 */ + [ilog2(POLLERR)] = { + .name = "EPOLLERR", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0010 */ + [ilog2(POLLHUP)] = { + .name = "EPOLLHUP", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(LTTNG_EPOLL_NRFLAGS)] = { + .name = "padding", + .type = __type_integer(int, EPOLL_FLAGS_PADDING_SIZE, 1, 0, + __LITTLE_ENDIAN, 10, none), + }, + +}; + +static struct lttng_event_field lttng_epoll_data_fields[] = { + [0] = { + .name = "u64", + .type = __type_integer(uint64_t, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [1] = { + .name = "fd", + .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none), + }, +}; + +static struct lttng_event_field epoll_ctl_fields[] = { + [0] = { + .name = "data_union", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields), + .u._struct.fields = lttng_epoll_data_fields, + } + }, + [1] = { + .name = "raw_events", + .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [2] = { + .name = "events", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields), + .u._struct.fields = lttng_epoll_ctl_events_fields, + } + }, +}; +#endif /* ONCE_LTTNG_TRACE_EPOLL_CTL_H */ + +#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) +#define OVERRIDE_32_epoll_ctl +#define OVERRIDE_64_epoll_ctl +SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_ctl, + TP_PROTO(sc_exit(long ret,) int epfd, int op, int fd, + struct epoll_event __user * uevent), + TP_ARGS(sc_exit(ret,) epfd, op, fd, uevent), + TP_locvar( + struct epoll_event event; + int err; + ), + TP_code_pre( + tp_locvar->err = lib_ring_buffer_copy_from_user_check_
[lttng-dev] [PATCH lttng-modules v7 1/5] Add ctf_integer_bitfield_type
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> Acked-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> --- probes/lttng-events-write.h | 8 1 file changed, 8 insertions(+) diff --git a/probes/lttng-events-write.h b/probes/lttng-events-write.h index 5db66eb..87741a1 100644 --- a/probes/lttng-events-write.h +++ b/probes/lttng-events-write.h @@ -22,6 +22,10 @@ #define ctf_integer(_type, _item, _src)\ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, 0, 0) +#undef ctf_integer_bitfield +#define ctf_integer_bitfield(_type, _item, _src) \ + _ctf_integer_ext(_type, _item, _src, __LITTLE_ENDIAN, 10, 0, 0) + #undef ctf_integer_hex #define ctf_integer_hex(_type, _item, _src)\ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 16, 0, 0) @@ -145,6 +149,10 @@ #define ctf_integer_type(_type, _src) \ ctf_integer(_type, unused, _src) +#undef ctf_integer_bitfield_type +#define ctf_integer_bitfield_type(_type, _src) \ + ctf_integer_bitfield(_type, unused, _src) + #undef ctf_integer_hex_type #define ctf_integer_hex_type(_type, _src) \ ctf_integer_hex(_type, unused, _src) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-modules v7 3/5] Extract the FDs and flags from poll and ppoll
Instead of printing the pointer address of the poll set, extract all the FDs and flags from the poll set. For now, we only output the standardized set of events to limit the verbosity of the output, we also extract the raw value. When we switch to CTF2 we will be able to hide unset fields and then we will extract all the fields. Here is an example of output with one FD: syscall_entry_poll: { timeout_msecs = -1, nfds = 1, fds_length = 1, fds = [ [0] = { fd = 4, raw_events = 0x5, events = { POLLIN = 1, POLLPRI = 0, POLLOUT = 1, POLLERR = 0, POLLHUP = 0, padding = 0 } } ] } syscall_exit_poll: { ret = 1, nfds = 1, fds_length = 1, fds = [ [0] = { fd = 4, raw_events = 0x4, events = { POLLIN = 0, POLLPRI = 0, POLLOUT = 1, POLLERR = 0, POLLHUP = 0, padding = 0 } } ] } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 254 + 1 file changed, 254 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index b9dd54a..2ffe814 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -301,4 +301,258 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6, ) #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ +#ifndef ONCE_LTTNG_TRACE_POLL_H +#define ONCE_LTTNG_TRACE_POLL_H + +#define LTTNG_POLL_NRFLAGS (POLLNVAL + 1) +#define POLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \ + ilog2(LTTNG_POLL_NRFLAGS - 1) + +/* + * Only extract the values specified by iBCS2 for now. + */ +static struct lttng_event_field lttng_pollfd_flag_fields[] = { + [ilog2(POLLIN)] = { + .name = "POLLIN", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLPRI)] = { + .name = "POLLPRI", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLOUT)] = { + .name = "POLLOUT", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLERR)] = { + .name = "POLLERR", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLHUP)] = { + .name = "POLLHUP", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLNVAL)] = { + .name = "POLLNVAL", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(LTTNG_POLL_NRFLAGS)] = { + .name = "padding", + .type = __type_integer(int, POLL_FLAGS_PADDING_SIZE, 1, 0, + __LITTLE_ENDIAN, 10, none), + }, +}; + +static struct lttng_event_field lttng_pollfd_fields[] = { + [0] = { + .name = "fd", + .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none), + }, + [1] = { + .name = "raw_events", + .type = __type_integer(short, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [2] = { + .name = "events", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_flag_fields), + .u._struct.fields = lttng_pollfd_flag_fields, + } + }, +}; + +static struct lttng_type lttng_pollfd_elem = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_fields), + .u._struct.fields = lttng_pollfd_fields, +}; +#endif /* ONCE_LTTNG_TRACE_POLL_H */ + +#define LTTNG_SYSCALL_POLL_locvar \ + unsigned int fds_length, fds_max_len, alloc_fds;\ + struct pollfd *fds; \ + uint8_t overflow; + +#define LTTNG_SYSCALL_POLL_code_pre\ + BUILD_BUG_ON(((ARRAY_SIZE(lttng_pollfd_flag_fields) - 1) + \ + POLL_FLAGS_PADDING_SIZE) != \ + sizeof(uint8_t) * BITS_PER_BYTE); \ + tp_locvar->fds = NULL; \ + tp_locvar->overflow = 0; \ + \ + sc_in( \ + if (nfds > (PAGE_SIZE / sizeof(struct pol
Re: [lttng-dev] [PATCH lttng-modules v6 4/5] Extract the payload for epoll_ctl
On 30-Apr-2016 02:19:24 PM, Mathieu Desnoyers wrote: > - On Apr 30, 2016, at 10:17 AM, Mathieu Desnoyers > mathieu.desnoy...@efficios.com wrote: > > > - On Apr 29, 2016, at 6:53 PM, Julien Desfossez jdesfos...@efficios.com > > wrote: > > > >> Map the operation to its name (EPOLL_CTL_*), extract the standard event > >> flags (EPOLL*) and output the data in two different formats: FD as an > >> int in decimal, and u64 in hex. The less standard event flags are not > >> extracted yet, but we extract the raw value in hex for more advanced > >> analyses. > >> > >> Here is an example output: > >> syscall_entry_epoll_ctl: { > >> epfd = 4, op_enum = ( "EPOLL_CTL_ADD" : container = 1 ), > >> fd = 0, event = { raw_events = 0x8003, > >> events = { EPOLLIN = 1, EPOLLPRI = 1, EPOLLOUT = 0, EPOLLERR = 0, > >> padding = 0 }, > >> data_union = { u64 = 0x0, fd = 0 } } > >> } > >> > >> syscall_exit_epoll_ctl: { ret = 0 } > >> > >> Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> > >> --- > >> .../syscalls/headers/syscalls_pointers_override.h | 140 > >> + > >> 1 file changed, 140 insertions(+) > >> > >> diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h > >> b/instrumentation/syscalls/headers/syscalls_pointers_override.h > >> index 11d5f3d..59931df 100644 > >> --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h > >> +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h > >> @@ -555,4 +555,144 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll, > >> ) > >> #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || > >> defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ > >> > >> +#include > >> + > >> +SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op, > >> + TP_ENUM_VALUES( > >> + ctf_enum_value("EPOLL_CTL_ADD", EPOLL_CTL_ADD) > >> + ctf_enum_value("EPOLL_CTL_DEL", EPOLL_CTL_DEL) > >> + ctf_enum_value("EPOLL_CTL_MOD", EPOLL_CTL_MOD) > >> + ) > >> +) > >> + > >> +#ifndef ONCE_LTTNG_TRACE_EPOLL_CTL_H > >> +#define ONCE_LTTNG_TRACE_EPOLL_CTL_H > >> + > >> +#define LTTNG_EPOLL_NRFLAGS (POLLHUP + 1) > >> +#define EPOLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \ > >> + ilog2(LTTNG_EPOLL_NRFLAGS - 1) > >> + > >> +/* > >> + * Only extract the values specified by iBCS2 for now. > >> + */ > >> +static struct lttng_event_field lttng_epoll_ctl_events_fields[] = { > >> + /* 0x0001 */ > >> + [ilog2(POLLIN)] = { > >> + .name = "EPOLLIN", > >> + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), > >> + }, > >> + /* 0x0002 */ > >> + [ilog2(POLLPRI)] = { > >> + .name = "EPOLLPRI", > >> + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), > >> + }, > >> + /* 0x0004 */ > >> + [ilog2(POLLOUT)] = { > >> + .name = "EPOLLOUT", > >> + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), > >> + }, > >> + /* 0x0008 */ > >> + [ilog2(POLLERR)] = { > >> + .name = "EPOLLERR", > >> + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), > >> + }, > >> + /* 0x0010 */ > >> + [ilog2(POLLHUP)] = { > >> + .name = "EPOLLHUP", > >> + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), > >> + }, > >> + [ilog2(LTTNG_EPOLL_NRFLAGS)] = { > >> + .name = "padding", > >> + .type = __type_integer(int, EPOLL_FLAGS_PADDING_SIZE, 1, 0, > >> + __LITTLE_ENDIAN, 10, none), > >> + }, > >> + > >> +}; > >> + > >> +static struct lttng_event_field lttng_epoll_data_fields[] = { > >> + [0] = { > >> + .name = "u64", > >> + .type = __type_integer(uint64_t, 0, 0, 0, __BYTE_ORDER, 16, > >> none), > >> + }, > >> + [1] = { > >> + .name = "fd", > >> + .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none), > >> + }, > >> +}; > >> + > >> +static struct lttng_event
[lttng-dev] [PATCH lttng-modules v6 4/5] Extract the payload for epoll_ctl
Map the operation to its name (EPOLL_CTL_*), extract the standard event flags (EPOLL*) and output the data in two different formats: FD as an int in decimal, and u64 in hex. The less standard event flags are not extracted yet, but we extract the raw value in hex for more advanced analyses. Here is an example output: syscall_entry_epoll_ctl: { epfd = 4, op_enum = ( "EPOLL_CTL_ADD" : container = 1 ), fd = 0, event = { raw_events = 0x8003, events = { EPOLLIN = 1, EPOLLPRI = 1, EPOLLOUT = 0, EPOLLERR = 0, padding = 0 }, data_union = { u64 = 0x0, fd = 0 } } } syscall_exit_epoll_ctl: { ret = 0 } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 140 + 1 file changed, 140 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index 11d5f3d..59931df 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -555,4 +555,144 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll, ) #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ +#include + +SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op, + TP_ENUM_VALUES( + ctf_enum_value("EPOLL_CTL_ADD", EPOLL_CTL_ADD) + ctf_enum_value("EPOLL_CTL_DEL", EPOLL_CTL_DEL) + ctf_enum_value("EPOLL_CTL_MOD", EPOLL_CTL_MOD) + ) +) + +#ifndef ONCE_LTTNG_TRACE_EPOLL_CTL_H +#define ONCE_LTTNG_TRACE_EPOLL_CTL_H + +#define LTTNG_EPOLL_NRFLAGS (POLLHUP + 1) +#define EPOLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \ + ilog2(LTTNG_EPOLL_NRFLAGS - 1) + +/* + * Only extract the values specified by iBCS2 for now. + */ +static struct lttng_event_field lttng_epoll_ctl_events_fields[] = { + /* 0x0001 */ + [ilog2(POLLIN)] = { + .name = "EPOLLIN", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0002 */ + [ilog2(POLLPRI)] = { + .name = "EPOLLPRI", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0004 */ + [ilog2(POLLOUT)] = { + .name = "EPOLLOUT", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0008 */ + [ilog2(POLLERR)] = { + .name = "EPOLLERR", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + /* 0x0010 */ + [ilog2(POLLHUP)] = { + .name = "EPOLLHUP", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(LTTNG_EPOLL_NRFLAGS)] = { + .name = "padding", + .type = __type_integer(int, EPOLL_FLAGS_PADDING_SIZE, 1, 0, + __LITTLE_ENDIAN, 10, none), + }, + +}; + +static struct lttng_event_field lttng_epoll_data_fields[] = { + [0] = { + .name = "u64", + .type = __type_integer(uint64_t, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [1] = { + .name = "fd", + .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none), + }, +}; + +static struct lttng_event_field epoll_ctl_fields[] = { + [0] = { + .name = "data_union", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields), + .u._struct.fields = lttng_epoll_data_fields, + } + }, + [1] = { + .name = "raw_events", + .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [2] = { + .name = "events", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields), + .u._struct.fields = lttng_epoll_ctl_events_fields, + } + }, +}; +#endif /* ONCE_LTTNG_TRACE_EPOLL_CTL_H */ + +#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) +#define OVERRIDE_32_epoll_ctl +#define OVERRIDE_64_epoll_ctl +SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_ctl, + TP_PROTO(sc_exit(long ret,) int epfd, int op, int fd, + struct epoll_event __user * uevent), + TP_ARGS(sc_exit(ret,) epfd, op, fd, uevent), + TP_locvar( + struct epoll_event event; + int err; + ), + TP_code_pre( + tp_locvar->err = lib_ring_buffer_copy_from_user_check_
[lttng-dev] [PATCH lttng-modules v6 2/5] Extract the FD sets in select and pselect6
Instead of extracting the user-space pointers of the 3 fd_set, we now extract the bitmask of the FDs in the sets (in, out, ex) in the form of an array of uint8_t (1024 FDs is the limit in the kernel). In this example, we select in input FDs 5 to 19 (0x0), it returns that one FD is ready: FD 12 (0x1000). syscall_entry_select: { n = 20, _fdset_in_length = 3, fdset_in = [ [0] = 0xF0, [1] = 0xFF, [2] = 0xF ], _fdset_out_length = 0, fdset_out = [ ], _fdset_ex_length = 0, fdset_ex = [ ], tvp = 0 } syscall_exit_select: { ret = 1, _fdset_in_length = 3, fdset_in = [ [0] = 0x0, [1] = 0x10, [2] = 0x0 ], _fdset_out_length = 0, fdset_out = [ ], _fdset_ex_length = 0, fdset_ex = [ ], tvp = 0 } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 248 + 1 file changed, 248 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index bf5c632..b9dd54a 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -53,4 +53,252 @@ SC_LTTNG_TRACEPOINT_EVENT(pipe2, ) ) +#define LTTNG_SYSCALL_SELECT_locvar\ + unsigned long *fds_in, *fds_out, *fds_ex; \ + unsigned long nr_bytes, nr_ulong; \ + uint8_t overflow; + +#define LTTNG_SYSCALL_SELECT_code_pre \ + sc_inout( \ + { \ + int err; \ + unsigned int n_in_bytes; \ + \ + tp_locvar->fds_in = NULL; \ + tp_locvar->fds_out = NULL; \ + tp_locvar->fds_ex = NULL; \ + tp_locvar->overflow = 0; \ + \ + sc_out( \ + if (ret <= 0) \ + goto error; \ + ) \ + \ + if (n <= 0) \ + goto error; \ + \ + /* On error or bogus input, don't copy anything. */ \ + if (n >__FD_SETSIZE) \ + goto error; \ + \ + n_in_bytes = DIV_ROUND_UP((unsigned int) n, BITS_PER_BYTE); \ + \ + /* \ +* Limit atomic memory allocation to one page, since n \ +* is limited to 1024 and the smallest page size on Linux \ +* is 4k, this should not happen, don't try to make it work. \ +*/ \ + if (n_in_bytes > PAGE_SIZE) { \ + WARN_ON_ONCE(1); \ + /* Inform the user that we did not output everything. */\ + tp_locvar->overflow = 1; \ + goto error; \ + } else { \ + tp_locvar->nr_bytes = n_in_bytes; \ + tp_locvar->nr_ulong = DIV_ROUND_UP(n_in_bytes, \ +
[lttng-dev] [PATCH lttng-modules v6 3/5] Extract the FDs and flags from poll and ppoll
Instead of printing the pointer address of the poll set, extract all the FDs and flags from the poll set. For now, we only output the standardized set of events to limit the verbosity of the output, we also extract the raw value. When we switch to CTF2 we will be able to hide unset fields and then we will extract all the fields. Here is an example of output with one FD: syscall_entry_poll: { timeout_msecs = -1, nfds = 1, fds_length = 1, fds = [ [0] = { fd = 4, raw_events = 0x5, events = { POLLIN = 1, POLLPRI = 0, POLLOUT = 1, POLLERR = 0, POLLHUP = 0, padding = 0 } } ] } syscall_exit_poll: { ret = 1, nfds = 1, fds_length = 1, fds = [ [0] = { fd = 4, raw_events = 0x4, events = { POLLIN = 0, POLLPRI = 0, POLLOUT = 1, POLLERR = 0, POLLHUP = 0, padding = 0 } } ] } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 254 + 1 file changed, 254 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index b9dd54a..11d5f3d 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -301,4 +301,258 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6, ) #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ +#ifndef ONCE_LTTNG_TRACE_POLL_H +#define ONCE_LTTNG_TRACE_POLL_H + +#define LTTNG_POLL_NRFLAGS (POLLNVAL + 1) +#define POLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \ + ilog2(LTTNG_POLL_NRFLAGS - 1) + +/* + * Only extract the values specified by iBCS2 for now. + */ +static struct lttng_event_field lttng_pollfd_flag_fields[] = { + [ilog2(POLLIN)] = { + .name = "POLLIN", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLPRI)] = { + .name = "POLLPRI", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLOUT)] = { + .name = "POLLOUT", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLERR)] = { + .name = "POLLERR", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLHUP)] = { + .name = "POLLHUP", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(POLLNVAL)] = { + .name = "POLLNVAL", + .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none), + }, + [ilog2(LTTNG_POLL_NRFLAGS)] = { + .name = "padding", + .type = __type_integer(int, POLL_FLAGS_PADDING_SIZE, 1, 0, + __LITTLE_ENDIAN, 10, none), + }, +}; + +static struct lttng_event_field lttng_pollfd_fields[] = { + [0] = { + .name = "fd", + .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none), + }, + [1] = { + .name = "raw_events", + .type = __type_integer(short, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [2] = { + .name = "events", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_flag_fields), + .u._struct.fields = lttng_pollfd_flag_fields, + } + }, +}; + +static struct lttng_type lttng_pollfd_elem = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_fields), + .u._struct.fields = lttng_pollfd_fields, +}; +#endif /* ONCE_LTTNG_TRACE_POLL_H */ + +#define LTTNG_SYSCALL_POLL_locvar \ + unsigned int fds_length, fds_max_len, alloc_fds;\ + struct pollfd *fds; \ + uint8_t overflow; + +#define LTTNG_SYSCALL_POLL_code_pre\ + BUILD_BUG_ON(((ARRAY_SIZE(lttng_pollfd_flag_fields) - 1) + \ + POLL_FLAGS_PADDING_SIZE) != \ + sizeof(uint8_t) * BITS_PER_BYTE); \ + tp_locvar->fds = NULL; \ + tp_locvar->overflow = 0; \ + \ + sc_in( \ + if (nfds * sizeof(struct pollfd) > PAGE_S
[lttng-dev] [PATCH lttng-modules v5 0/5] Extract payload from polling syscalls
Patch serie to extract the payload of the polling system calls on x86 and ARM (32 and 64-bit). The concerned system calls are select, pselect6, poll, ppoll, epoll_ctl, epoll_wait, epoll_pwait. Changes from v4: - Use GFP_ATOMIC memory for dynamic allocation (because we cannot sleep in TP) - Limit the allocated memory to one page - Set an overflow flag if we cannot allocate enough memory - Fix endianness problem for select - Bugfix from v4 review Changes from v3: - Use dynamic allocation for select - Bugfix from v3 review - Cleanup epoll_wait error handling Changes from v2: - Make sure all user-controlled data is handled safely in the kernel - Allocate memory instead of using the stack for arbitrarily large data - Only extract the standard event flags and output the raw event value as hex - Various bugfixes from v2 Julien Desfossez (5): Add ctf_integer_bitfield_type Extract the FD sets in select and pselect6 Extract the FDs and flags from poll and ppoll Extract the payload for epoll_ctl Extract the payload of epoll_wait/epoll_pwait .../syscalls/headers/syscalls_pointers_override.h | 1243 probes/lttng-events-write.h|8 + 2 files changed, 1251 insertions(+) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-modules v5 1/5] Add ctf_integer_bitfield_type
Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> Acked-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> --- probes/lttng-events-write.h | 8 1 file changed, 8 insertions(+) diff --git a/probes/lttng-events-write.h b/probes/lttng-events-write.h index 5db66eb..87741a1 100644 --- a/probes/lttng-events-write.h +++ b/probes/lttng-events-write.h @@ -22,6 +22,10 @@ #define ctf_integer(_type, _item, _src)\ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 10, 0, 0) +#undef ctf_integer_bitfield +#define ctf_integer_bitfield(_type, _item, _src) \ + _ctf_integer_ext(_type, _item, _src, __LITTLE_ENDIAN, 10, 0, 0) + #undef ctf_integer_hex #define ctf_integer_hex(_type, _item, _src)\ _ctf_integer_ext(_type, _item, _src, __BYTE_ORDER, 16, 0, 0) @@ -145,6 +149,10 @@ #define ctf_integer_type(_type, _src) \ ctf_integer(_type, unused, _src) +#undef ctf_integer_bitfield_type +#define ctf_integer_bitfield_type(_type, _src) \ + ctf_integer_bitfield(_type, unused, _src) + #undef ctf_integer_hex_type #define ctf_integer_hex_type(_type, _src) \ ctf_integer_hex(_type, unused, _src) -- 1.9.1 ___ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
[lttng-dev] [PATCH lttng-modules v5 5/5] Extract the payload of epoll_wait/epoll_pwait
When epoll_wait returns, extract the content of the "events" field (events set and data payload). Here is an example output: syscall_entry_epoll_wait: { epfd = 3, maxevents = 32, timeout = 100 } syscall_exit_epoll_wait: { ret = 1, fds_length = 1, fds = [ [0] = { raw_events = 0x1, events = { EPOLLIN = 1, EPOLLPRI = 0, EPOLLOUT = 0, EPOLLERR = 0, padding = 0 }, data_union = { u64 = 0x10005, fd = 5 } } ] } Signed-off-by: Julien Desfossez <jdesfos...@efficios.com> --- .../syscalls/headers/syscalls_pointers_override.h | 234 + 1 file changed, 234 insertions(+) diff --git a/instrumentation/syscalls/headers/syscalls_pointers_override.h b/instrumentation/syscalls/headers/syscalls_pointers_override.h index 9fe0030..68ba1a2 100644 --- a/instrumentation/syscalls/headers/syscalls_pointers_override.h +++ b/instrumentation/syscalls/headers/syscalls_pointers_override.h @@ -1062,4 +1062,238 @@ SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_ctl, ) #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */ +#ifndef ONCE_LTTNG_TRACE_EPOLL_H +#define ONCE_LTTNG_TRACE_EPOLL_H + +static struct lttng_event_field lttng_epoll_wait_fields[] = { + [0] = { + .name = "data_union", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields), + .u._struct.fields = lttng_epoll_data_fields, + } + }, + [1] = { + .name = "raw_events", + .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none), + }, + [2] = { + .name = "events", + .type = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields), + .u._struct.fields = lttng_epoll_ctl_events_fields, + } + }, +}; + +static struct lttng_type lttng_epoll_wait_elem = { + .atype = atype_struct, + .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_wait_fields), + .u._struct.fields = lttng_epoll_wait_fields, +}; + +#endif /* ONCE_LTTNG_TRACE_EPOLL_H */ + +#if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) +#define OVERRIDE_32_epoll_wait +#define OVERRIDE_64_epoll_wait +SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_wait, + TP_PROTO(sc_exit(long ret,) int epfd, struct epoll_event __user * uevents, + int maxevents, int timeout), + TP_ARGS(sc_exit(ret,) epfd, uevents, maxevents, timeout), + TP_locvar( + sc_out( + unsigned int fds_length, overflow; + struct epoll_event *events; + ) + ), + TP_code_pre( + BUILD_BUG_ON(((ARRAY_SIZE(lttng_epoll_ctl_events_fields) - 1) + + EPOLL_FLAGS_PADDING_SIZE) != + sizeof(uint8_t) * BITS_PER_BYTE); + sc_out({ + int err; + unsigned long maxalloc; + + tp_locvar->fds_length = 0; + tp_locvar->events = NULL; + tp_locvar->overflow = 0; + + if (maxevents <= 0 || ret <= 0 || ret > maxevents) + goto skip_code; + + if ((maxevents * sizeof(struct epoll_event)) > PAGE_SIZE) { + maxalloc = PAGE_SIZE / sizeof(struct epoll_event); + if (ret > maxalloc) { + tp_locvar->fds_length = maxalloc; + tp_locvar->overflow = 1; + } else { + tp_locvar->fds_length = ret; + } + } else { + maxalloc = maxevents; + tp_locvar->fds_length = ret; + } + + tp_locvar->events = kmalloc( + maxalloc * sizeof(struct epoll_event), + GFP_ATOMIC); + if (!tp_locvar->events) { + tp_locvar->fds_length = 0; + goto skip_code; + } + + err = lib_ring_buffer_copy_from_user_check_nofault( + tp_locvar->events, uevents, + maxevents * sizeof(struct epoll_event)); + if (err != 0) + tp_locvar->fds_length = 0; + } + skip_code: + ) + ), + TP_FIELDS( + sc_exit(ctf_integer(long,