Tracepoints v4 for linux-next
Subsystems (18)
cover Tracepoints v4 for linux-next
Hi,
Here is the newest release of the Tracepoints, following the feedback from Peter Zijlstra. The main change is the creation of include/trace/ as a placeholder from tracepoint headers.
The patchset applies over linux-next patch-v2.6.26-next-20080715 in this order :
#This a separate RCU update upon which the tracepoints depend rcu-read-sched.patch
tracepoints.patch
tracepoints-documentation.patch
tracepoints-samples.patch
lttng-instrumentation-irq.patch
lttng-instrumentation-scheduler.patch
lttng-instrumentation-timer.patch
lttng-instrumentation-kernel.patch
lttng-instrumentation-filemap.patch
lttng-instrumentation-swap.patch
lttng-instrumentation-memory.patch
lttng-instrumentation-page.patch
lttng-instrumentation-hugetlb.patch
lttng-instrumentation-net.patch
lttng-instrumentation-ipv4.patch
lttng-instrumentation-ipv6.patch
ftrace-port-to-tracepoints.patch
Mathieu
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 1/17 RCU read sched
Add rcu_read_lock_sched() and rcu_read_unlock_sched() to rcupdate.h to match the recently added write-side call_rcu_sched() and rcu_barrier_sched(). They also match the no-so-recently-added synchronize_sched().
It will help following matching use of the update/read lock primitives. Those new read lock will replace preempt_disable()/enable() used in pair with RCU-classic synchronization.
--- include/linux/rcupdate.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
include/linux/rcupdate.h +18 -0
@@ -133,6 +133,24 @@ struct rcu_head {#define rcu_read_unlock_bh () __rcu_read_unlock_bh()/** +* rcu_read_lock_sched - mark the beginning of a RCU-classic critical section +* +* Should be used with either +* - synchronize_sched() +* or +* - call_rcu_sched() and rcu_barrier_sched() +* on the write-side to insure proper synchronization. +*/ +#define rcu_read_lock_sched () preempt_disable() + +/* +* rcu_read_unlock_sched - marks the end of a RCU-classic critical section +* +* See rcu_read_lock_sched for more information. +*/ +#define rcu_read_unlock_sched () preempt_enable() + +/** * rcu_dereference - fetch an RCU-protected pointer in an * RCU read-side critical section. This pointer may later * be safely dereferenced.
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 01/17] RCU read sched
Quoted 7 lines · Mathieu Desnoyers
Add
rcu_read_lock_sched()andrcu_read_unlock_sched()torcupdate.hto match the recently added write-sidecall_rcu_sched()andrcu_barrier_sched(). They also match the no-so-recently-addedsynchronize_sched().It will help following matching use of the update/read lock primitives. Those new read lock will replace preempt_disable()/enable() used in pair with RCU-classic synchronization.
Looks good, but...
synchronize_sched(), call_rcu_sched(), and rcu_barrier_sched() can also pair up with:
o local_irq_save() and local_irq_restore()
o local_irq_disable() and local_irq_enable()
o spin_lock_irqsave() and spin_lock_irqrestore()
o etc. etc.
I do very much like the idea of marking the intent of matching with RCU, but am getting a bit queasy about adding rcu_read_lock_sched_irq() and so on.
Thoughts? Other than having an rcu_read_lock_sched_nop() or some other window-dressing macro that doesn't really do anything? (Which might really be the right thing to do...)
Thanx, Paul
Quoted 42 lines
Signed-off-by Mathieu Desnoyers <[email protected]>CC Peter Zijlstra <[email protected]>CC Paul E McKenney <[email protected]>--- include/linux/rcupdate.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)Index:
linux-2.6-lttng/include/linux/rcupdate.h
===================================================================include/linux/rcupdate.h +18
-0@@ -133,6 +133,24 @@ struct rcu_head {#define rcu_read_unlock_bh () __rcu_read_unlock_bh()/** +* rcu_read_lock_sched - mark the beginning of a RCU-classic critical section +* +* Should be used with either +* - synchronize_sched() +* or +* - call_rcu_sched() and rcu_barrier_sched() +* on the write-side to insure proper synchronization. +*/ +#define rcu_read_lock_sched () preempt_disable() + +/* +* rcu_read_unlock_sched - marks the end of a RCU-classic critical section +* +* See rcu_read_lock_sched for more information. +*/ +#define rcu_read_unlock_sched () preempt_enable() + +/** * rcu_dereference - fetch an RCU-protected pointer in an * RCU read-side critical section. This pointer may later * be safely dereferenced. Signature · 4 lines
-- Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Peter Zijlstra
maintainerRe: [patch 01/17] RCU read sched
Quoted 11 lines · Paul E. McKenney
Quoted 7 lines · Mathieu Desnoyers
Add
rcu_read_lock_sched()andrcu_read_unlock_sched()torcupdate.hto match the recently added write-sidecall_rcu_sched()andrcu_barrier_sched(). They also match the no-so-recently-addedsynchronize_sched().It will help following matching use of the update/read lock primitives. Those new read lock will replace preempt_disable()/enable() used in pair with RCU-classic synchronization.
Looks good, but...
Quoted 7 lines
synchronize_sched(),call_rcu_sched(), andrcu_barrier_sched()can also pair up with:o
local_irq_save()andlocal_irq_restore()
olocal_irq_disable()andlocal_irq_enable()o
spin_lock_irqsave()andspin_lock_irqrestore()
You can't actually, as on PREEMP_RT these will not actuall disable preemption.
Quoted 5 lines
o etc. etc.
I do very much like the idea of marking the intent of matching with RCU, but am getting a bit queasy about adding
rcu_read_lock_sched_irq()and so on.
I'm thinking that if you disable interrupts, you're doing that for another reason than RCU, so I'm not seeing the need for rcu_read_lock_sched_irq variants.
Also, we should be very careful with using the *sched* RCU variant as it really relies on disabling preemption - we should only use it when there really is no other option, as we generally prefer to keep stuff preemptable.
Quoted 3 lines
Thoughts? Other than having an
rcu_read_lock_sched_nop()or some other window-dressing macro that doesn't really do anything? (Which might really be the right thing to do...)
Afraid you lost me here..
PATCH 2/17 Kernel Tracepoints
In reply to Mathieu DesnoyersImplementation of kernel tracepoints. Inspired from the Linux Kernel Markers. Allows complete typing verification by declaring both tracing statement inline functions and probe registration/unregistration static inline functions within the same macro "DEFINE_TRACE". No format string is required. See the tracepoint Documentation and Samples patches for usage examples.
Taken from the documentation patch :
"A tracepoint placed in code provides a hook to call a function (probe) that you can provide at runtime. A tracepoint can be "on" (a probe is connected to it) or "off" (no probe is attached). When a tracepoint is "off" it has no effect, except for adding a tiny time penalty (checking a condition for a branch) and space penalty (adding a few bytes for the function call at the end of the instrumented function and adds a data structure in a separate section). When a tracepoint is "on", the function you provide is called each time the tracepoint is executed, in the execution context of the caller. When the function provided ends its execution, it returns to the caller (continuing from the tracepoint site).
You can put tracepoints at important locations in the code. They are lightweight hooks that can pass an arbitrary number of parameters, which prototypes are described in a tracepoint declaration placed in a header file."
Addition and removal of tracepoints is synchronized by RCU using the scheduler (and preempt_disable) as guarantees to find a quiescent state (this is really RCU "classic"). The update side uses rcu_barrier_sched() with call_rcu_sched() and the read/execute side uses "preempt_disable()/preempt_enable()".
We make sure the previous array containing probes, which has been scheduled for deletion by the rcu callback, is indeed freed before we proceed to the next update. It therefore limits the rate of modification of a single tracepoint to one update per RCU period. The objective here is to permit fast batch add/removal of probes on _different_ tracepoints.
Changelog :
- Use #name ":" #proto as string to identify the tracepoint in the tracepoint table. This will make sure not type mismatch happens due to connexion of a probe with the wrong type to a tracepoint declared with the same name in a different header.
- Add tracepoint_entry_free_old.
- Change __TO_TRACE to get rid of the 'i' iterator.
Masami Hiramatsu <[email protected]> :
Tested on x86-64.
Performance impact of a tracepoint : same as markers, except that it adds about 70 bytes of instructions in an unlikely branch of each instrumented function (the for loop, the stack setup and the function call). It currently adds a memory read, a test and a conditional branch at the instrumentation site (in the hot path). Immediate values will eventually change this into a load immediate, test and branch, which removes the memory read which will make the i-cache impact smaller (changing the memory read for a load immediate removes 3-4 bytes per site on x86_32 (depending on mov prefixes), or 7-8 bytes on x86_64, it also saves the d-cache hit).
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added.
Quoting Hideo Aoki about Markers :
I evaluated overhead of kernel marker using linux-2.6-sched-fixes git tree, which includes several markers for LTTng, using an ia64 server.
While the immediate trace mark feature isn't implemented on ia64, there is no major performance regression. So, I think that we don't have any issues to propose merging marker point patches into Linus's tree from the viewpoint of performance impact.
I prepared two kernels to evaluate. The first one was compiled without CONFIG_MARKERS. The second one was enabled CONFIG_MARKERS.
I downloaded the original hackbench from the following URL:
http://devresources.linux-foundation.org/craiger/hackbench/src/hackbench.c
I ran hackbench 5 times in each condition and calculated the average and difference between the kernels.
The parameter of hackbench: every 50 from 50 to 800 The number of CPUs of the server: 2, 4, and 8
Below is the results. As you can see, major performance regression wasn't found in any case. Even if number of processes increases, differences between marker-enabled kernel and marker- disabled kernel doesn't increase. Moreover, if number of CPUs increases, the differences doesn't increase either.
Curiously, marker-enabled kernel is better than marker-disabled kernel in more than half cases, although I guess it comes from the difference of memory access pattern.
* 2 CPUs
Number of | without | with | diff | diff |
processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] |
--------------------------------------------------------------
50 | 4.811 | 4.872 | +0.061 | +1.27 |
100 | 9.854 | 10.309 | +0.454 | +4.61 |
150 | 15.602 | 15.040 | -0.562 | -3.6 |
200 | 20.489 | 20.380 | -0.109 | -0.53 |
250 | 25.798 | 25.652 | -0.146 | -0.56 |
300 | 31.260 | 30.797 | -0.463 | -1.48 |
350 | 36.121 | 35.770 | -0.351 | -0.97 |
400 | 42.288 | 42.102 | -0.186 | -0.44 |
450 | 47.778 | 47.253 | -0.526 | -1.1 |
500 | 51.953 | 52.278 | +0.325 | +0.63 |
550 | 58.401 | 57.700 | -0.701 | -1.2 |
600 | 63.334 | 63.222 | -0.112 | -0.18 |
650 | 68.816 | 68.511 | -0.306 | -0.44 |
700 | 74.667 | 74.088 | -0.579 | -0.78 |
750 | 78.612 | 79.582 | +0.970 | +1.23 |
800 | 85.431 | 85.263 | -0.168 | -0.2 |--------------------------------------------------------------
* 4 CPUs
Number of | without | with | diff | diff |
processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] |
--------------------------------------------------------------
50 | 2.586 | 2.584 | -0.003 | -0.1 |
100 | 5.254 | 5.283 | +0.030 | +0.56 |
150 | 8.012 | 8.074 | +0.061 | +0.76 |
200 | 11.172 | 11.000 | -0.172 | -1.54 |
250 | 13.917 | 14.036 | +0.119 | +0.86 |
300 | 16.905 | 16.543 | -0.362 | -2.14 |
350 | 19.901 | 20.036 | +0.135 | +0.68 |
400 | 22.908 | 23.094 | +0.186 | +0.81 |
450 | 26.273 | 26.101 | -0.172 | -0.66 |
500 | 29.554 | 29.092 | -0.461 | -1.56 |
550 | 32.377 | 32.274 | -0.103 | -0.32 |
600 | 35.855 | 35.322 | -0.533 | -1.49 |
650 | 39.192 | 38.388 | -0.804 | -2.05 |
700 | 41.744 | 41.719 | -0.025 | -0.06 |
750 | 45.016 | 44.496 | -0.520 | -1.16 |
800 | 48.212 | 47.603 | -0.609 | -1.26 |--------------------------------------------------------------
* 8 CPUs
Number of | without | with | diff | diff |
processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] |
--------------------------------------------------------------
50 | 2.094 | 2.072 | -0.022 | -1.07 |
100 | 4.162 | 4.273 | +0.111 | +2.66 |
150 | 6.485 | 6.540 | +0.055 | +0.84 |
200 | 8.556 | 8.478 | -0.078 | -0.91 |
250 | 10.458 | 10.258 | -0.200 | -1.91 |
300 | 12.425 | 12.750 | +0.325 | +2.62 |
350 | 14.807 | 14.839 | +0.032 | +0.22 |
400 | 16.801 | 16.959 | +0.158 | +0.94 |
450 | 19.478 | 19.009 | -0.470 | -2.41 |
500 | 21.296 | 21.504 | +0.208 | +0.98 |
550 | 23.842 | 23.979 | +0.137 | +0.57 |
600 | 26.309 | 26.111 | -0.198 | -0.75 |
650 | 28.705 | 28.446 | -0.259 | -0.9 |
700 | 31.233 | 31.394 | +0.161 | +0.52 |
750 | 34.064 | 33.720 | -0.344 | -1.01 |
800 | 36.320 | 36.114 | -0.206 | -0.57 |--------------------------------------------------------------
Best regards,
Hideo
P.S. When I compiled the linux-2.6-sched-fixes tree on ia64, I had to revert the following git commit since pteval_t is defined on x86 only.
commit 8686f2b37e7394b51dd6593678cbfd85ecd28c65
Date: Tue May 6 15:42:40 2008 -0700
generic, x86, PAT: fix mprotect
--- include/asm-generic/vmlinux.lds.h | 6 include/linux/module.h | 17 + include/linux/tracepoint.h | 127 ++++++++++ init/Kconfig | 7 kernel/Makefile | 1 kernel/module.c | 66 +++++ kernel/tracepoint.c | 473 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 695 insertions(+), 2 deletions(-)
init/Kconfig +7 -0
@@ -782,6 +782,13 @@ config PROFILING Say Y here to enable the extended profiling support mechanisms used by profilers such as OProfile. +config TRACEPOINTS + bool "Activate tracepoints" + default y + help + Place an empty function call at each tracepoint site. Can be + dynamically changed for a probe function. + config MARKERS bool "Activate markers" help
kernel/Makefile +1 -0
@@ -77,6 +77,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o obj-$(CONFIG_MARKERS) += marker.o +obj-$(CONFIG_TRACEPOINTS) += tracepoint.o obj-$(CONFIG_LATENCYTOP) += latencytop.o obj-$(CONFIG_FTRACE) += trace/ obj-$(CONFIG_TRACING) += trace/
include/linux/tracepoint.h new file +127 -0
127 lines not on this page · raw message
include/asm-generic/vmlinux.lds.h +5 -1
@@ -52,7 +52,10 @@ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___markers) = .; \ *(__markers ) \ - VMLINUX_SYMBOL(__stop___markers) = .; + VMLINUX_SYMBOL(__stop___markers) = .; \ + VMLINUX_SYMBOL(__start___tracepoints) = .; \ + *(__tracepoints ) \ + VMLINUX_SYMBOL(__stop___tracepoints) = .;#define RO_DATA (align) \ . = ALIGN((align)); \
@@ -61,6 +64,7 @@ *(.rodata) *(.rodata.*) \ *(__vermagic)/* Kernel version magic */ \ *(__markers_strings)/* Markers: strings */ \ + *(__tracepoints_strings)/* Tracepoints: strings */ \ } \ \ .rodata1 : AT(ADDR(.rodata1) - LOAD_OFFSET) { \
kernel/tracepoint.c new file +473 -0
473 lines not on this page · raw message
kernel/module.c +65 -1
103 lines not on this page · raw message
include/linux/module.h +17 -0
@@ -16,6 +16,7 @@#include <linux/kobject.h> #include <linux/moduleparam.h> #include <linux/marker.h> +#include <linux/tracepoint.h> #include <asm/local.h> #include <asm/module.h>
@@ -331,6 +332,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_TRACEPOINTS +struct tracepoint *tracepoints; +unsigned int num_tracepoints; +#endif #ifdef CONFIG_MODULE_UNLOAD /* What modules depend on me? */
@@ -454,6 +459,9 @@ extern void print_modules(void);extern void module_update_markers (void ); +extern void module_update_tracepoints (void ); +extern int module_get_iter_tracepoints (struct tracepoint_iter *iter); +#else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL (sym)#define EXPORT_SYMBOL_GPL (sym)
@@ -558,6 +566,15 @@ static inline void module_update_markers { } +static inline void module_update_tracepoints (void ) +{ +} + +static inline int module_get_iter_tracepoints (struct tracepoint_iter *iter) +{ +return 0 ; +} +#endif /* CONFIG_MODULES */ struct device_driver ;
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Steven Rostedt
maintainerRe: [patch 02/17] Kernel Tracepoints
[Added Paul McKenney to CC]
Quoted 40 lines · Mathieu Desnoyers
+++
linux-2.6-lttng/include/linux/tracepoint.h2008-07-15 17:35:19.000000000 -0400include/linux/tracepoint.h new file +38
-0@@ -0,0 +1,127 @@ +#ifndef _LINUX_TRACEPOINT_H +#define _LINUX_TRACEPOINT_H + +/* +* Kernel Tracepoint API. +* +* See Documentation/tracepoint.txt. +* +* (C) Copyright 2008 Mathieu Desnoyers <[email protected]> +* +* Heavily inspired from the Linux Kernel Markers. +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#include <linux/types.h> +#include <linux/rcupdate.h> + +struct module ; +struct tracepoint ; + +struct tracepoint { +const char *name;/* Tracepoint name */ +int state;/* State. */ +void **funcs; +} __attribute__((aligned (8 ))); + + +#define TPPROTO(args...) args +#define TPARGS(args...) args + +#ifdef CONFIG_TRACEPOINTS + +/* +* it_func[0] is never NULL because there is at least one element in the array +* when the array itself is non NULL. +*/
include/linux/tracepoint.h line 48
Quoted 10 lines
include/linux/tracepoint.h new file +10
-0+#define __DO_TRACE (tp, proto, args) \ + do { \ + void **it_func; \ + \ + rcu_read_lock_sched(); \ + it_func = rcu_dereference((tp)->funcs); \ + if (it_func) { \ + do { \ + ((void(*)(proto))(*it_func))(args); \ + } while (*(++it_func)); \
OK, I still don't understand the concept of the rcu_dereference, but why is it needed for the first assignment of it_func but not the ++? Is it only needed with the (tp)->funcs?
-- Steve
Quoted 3 lines
include/linux/tracepoint.h new file +3
-0+ } \ +rcu_read_unlock_sched (); \ + }while (0 )
Re: [patch 02/17] Kernel Tracepoints
Quoted 50 lines · * Steven Rostedt ([email protected]) wrote:
[Added Paul McKenney to CC]
Quoted 46 lines · Mathieu Desnoyers
+++
linux-2.6-lttng/include/linux/tracepoint.h2008-07-15 17:35:19.000000000 -0400include/linux/tracepoint.h new file +44
-0@@ -0,0 +1,127 @@ +#ifndef _LINUX_TRACEPOINT_H +#define _LINUX_TRACEPOINT_H + +/* +* Kernel Tracepoint API. +* +* See Documentation/tracepoint.txt. +* +* (C) Copyright 2008 Mathieu Desnoyers <[email protected]> +* +* Heavily inspired from the Linux Kernel Markers. +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#include <linux/types.h> +#include <linux/rcupdate.h> + +struct module ; +struct tracepoint ; + +struct tracepoint { +const char *name;/* Tracepoint name */ +int state;/* State. */ +void **funcs; +} __attribute__((aligned (8 ))); + + +#define TPPROTO(args...) args +#define TPARGS(args...) args + +#ifdef CONFIG_TRACEPOINTS + +/* +* it_func[0] is never NULL because there is at least one element in the array +* when the array itself is non NULL. +*/ +#define __DO_TRACE (tp, proto, args) \ + do { \ + void **it_func; \ + \ + rcu_read_lock_sched(); \ + it_func = rcu_dereference((tp)->funcs); \
Quoted 9 lines
include/linux/tracepoint.h line 48
Quoted 4 lines
include/linux/tracepoint.h new file +4
-0+if (it_func) { \ +do { \ + ((void (*)(proto ))(*it_func))(args); \ + }while (*(++it_func)); \OK, I still don't understand the concept of the
rcu_dereference, but why is it needed for the first assignment ofit_funcbut not the ++? Is it only needed with the (tp)->funcs?
rcu_dereference copies the tp->funcs pointer on the local stack and then puts a smp_read_barrier_depends() to make sure that the tp->funcs read occurs before the actual use of the data (here, it is the array elements) where the tp->funcs pointer copy points to.
What happens here is that the tp->funcs pointer, pointing to the beginning of the array, is only read once. Afterward, the iterator is located on the stack and therefore incrementing it does not need to be protected by any other kind of barrier whatsoever because only the original tp->funcs read was a RCU pointer read.
Then, as you probably know, the update side performs a rcu_assign_pointer which does a smp_wmb before the pointer assignment to make sure the array data has been populated before the pointer assignment.
Mathieu
Quoted 7 lines
-- Steve
Quoted 3 lines
include/linux/tracepoint.h new file +3
-0+ } \ +rcu_read_unlock_sched (); \ + }while (0 )
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 02/17] Kernel Tracepoints
Quoted 72 lines · Mathieu Desnoyers
Quoted 50 lines · * Steven Rostedt ([email protected]) wrote:
[Added Paul McKenney to CC]
Quoted 46 lines · Mathieu Desnoyers
+++
linux-2.6-lttng/include/linux/tracepoint.h2008-07-15 17:35:19.000000000 -0400include/linux/tracepoint.h new file +44
-0@@ -0,0 +1,127 @@ +#ifndef _LINUX_TRACEPOINT_H +#define _LINUX_TRACEPOINT_H + +/* +* Kernel Tracepoint API. +* +* See Documentation/tracepoint.txt. +* +* (C) Copyright 2008 Mathieu Desnoyers <[email protected]> +* +* Heavily inspired from the Linux Kernel Markers. +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#include <linux/types.h> +#include <linux/rcupdate.h> + +struct module ; +struct tracepoint ; + +struct tracepoint { +const char *name;/* Tracepoint name */ +int state;/* State. */ +void **funcs; +} __attribute__((aligned (8 ))); + + +#define TPPROTO(args...) args +#define TPARGS(args...) args + +#ifdef CONFIG_TRACEPOINTS + +/* +* it_func[0] is never NULL because there is at least one element in the array +* when the array itself is non NULL. +*/ +#define __DO_TRACE (tp, proto, args) \ + do { \ + void **it_func; \ + \ + rcu_read_lock_sched(); \ + it_func = rcu_dereference((tp)->funcs); \Quoted 9 lines
include/linux/tracepoint.h line 48
Quoted 4 lines
include/linux/tracepoint.h new file +4
-0+if (it_func) { \ +do { \ + ((void (*)(proto ))(*it_func))(args); \ + }while (*(++it_func)); \OK, I still don't understand the concept of the
rcu_dereference, but why is it needed for the first assignment ofit_funcbut not the ++? Is it only needed with the (tp)->funcs?
rcu_dereferencecopies thetp->funcspointer on the local stack and then puts asmp_read_barrier_depends()to make sure that thetp->funcsread occurs before the actual use of the data (here, it is the array elements) where thetp->funcspointer copy points to.What happens here is that the
tp->funcspointer, pointing to the beginning of the array, is only read once. Afterward, the iterator is located on the stack and therefore incrementing it does not need to be protected by any other kind of barrier whatsoever because only the originaltp->funcsread was a RCU pointer read.
Quoted 4 lines
Then, as you probably know, the update side performs a
rcu_assign_pointerwhich does asmp_wmbbefore the pointer assignment to make sure the array data has been populated before the pointer assignment.
So the update side inserts a whole new array, rather than just the first entry, correct? If so, I am happy.
Thanx, Paul
Quoted 13 lines
Mathieu
Quoted 7 lines
-- Steve
Quoted 3 lines
include/linux/tracepoint.h new file +3
-0+ } \ +rcu_read_unlock_sched (); \ + }while (0 )Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 02/17] Kernel Tracepoints
Quoted 73 lines · * Paul E. McKenney ([email protected]) wrote:
Quoted 72 lines · Mathieu Desnoyers
Quoted 50 lines · * Steven Rostedt ([email protected]) wrote:
[Added Paul McKenney to CC]
Quoted 46 lines · Mathieu Desnoyers
+++
linux-2.6-lttng/include/linux/tracepoint.h2008-07-15 17:35:19.000000000 -0400include/linux/tracepoint.h new file +44
-0@@ -0,0 +1,127 @@ +#ifndef _LINUX_TRACEPOINT_H +#define _LINUX_TRACEPOINT_H + +/* +* Kernel Tracepoint API. +* +* See Documentation/tracepoint.txt. +* +* (C) Copyright 2008 Mathieu Desnoyers <[email protected]> +* +* Heavily inspired from the Linux Kernel Markers. +* +* This file is released under the GPLv2. +* See the file COPYING for more details. +*/ + +#include <linux/types.h> +#include <linux/rcupdate.h> + +struct module ; +struct tracepoint ; + +struct tracepoint { +const char *name;/* Tracepoint name */ +int state;/* State. */ +void **funcs; +} __attribute__((aligned (8 ))); + + +#define TPPROTO(args...) args +#define TPARGS(args...) args + +#ifdef CONFIG_TRACEPOINTS + +/* +* it_func[0] is never NULL because there is at least one element in the array +* when the array itself is non NULL. +*/ +#define __DO_TRACE (tp, proto, args) \ + do { \ + void **it_func; \ + \ + rcu_read_lock_sched(); \ + it_func = rcu_dereference((tp)->funcs); \Quoted 9 lines
include/linux/tracepoint.h line 48
Quoted 4 lines
include/linux/tracepoint.h new file +4
-0+if (it_func) { \ +do { \ + ((void (*)(proto ))(*it_func))(args); \ + }while (*(++it_func)); \OK, I still don't understand the concept of the
rcu_dereference, but why is it needed for the first assignment ofit_funcbut not the ++? Is it only needed with the (tp)->funcs?
rcu_dereferencecopies thetp->funcspointer on the local stack and then puts asmp_read_barrier_depends()to make sure that thetp->funcsread occurs before the actual use of the data (here, it is the array elements) where thetp->funcspointer copy points to.What happens here is that the
tp->funcspointer, pointing to the beginning of the array, is only read once. Afterward, the iterator is located on the stack and therefore incrementing it does not need to be protected by any other kind of barrier whatsoever because only the originaltp->funcsread was a RCU pointer read.
Quoted 8 lines
Quoted 4 lines
Then, as you probably know, the update side performs a
rcu_assign_pointerwhich does asmp_wmbbefore the pointer assignment to make sure the array data has been populated before the pointer assignment.So the update side inserts a whole new array, rather than just the first entry, correct? If so, I am happy.
Exactly.
Mathieu
Quoted 15 lines
Thanx, Paul
Quoted 13 lines
Mathieu
Quoted 7 lines
-- Steve
Quoted 3 lines
include/linux/tracepoint.h new file +3
-0+ } \ +rcu_read_unlock_sched (); \ + }while (0 )Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Steven Rostedt
maintainerRe: [patch 02/17] Kernel Tracepoints
In reply to Mathieu DesnoyersQuoted 19 lines · Mathieu Desnoyers
kernel/tracepoint.c new file +19
-0+static void * +tracepoint_entry_remove_probe (struct tracepoint_entry *entry,void *probe) +{ +int nr_probes =0 , nr_del =0 , i; +void **old, **new; + + old = entry->funcs; + +debug_print_probes (entry); +/* (N -> M), (N > 1, M >= 0) probes */ +for (nr_probes =0 ; old[nr_probes]; nr_probes++) { +if ((!probe || old[nr_probes] == probe)) + nr_del++; + } + +if (nr_probes - nr_del ==0 ) { +/* N -> 0, (N > 1) */ + entry->funcs =NULL ; + entry->refcount =0 ;
kernel/tracepoint.c line 154
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+debug_print_probes (entry); +return old; + }else { +int j =0 ; +/* N -> M, (N > 1, M > 0) */ +/* + 1 for NULL */ + new =kzalloc ((nr_probes - nr_del +1 ) + *sizeof (void *),GFP_KERNEL ); +if (new ==NULL ) +return ERR_PTR (-ENOMEM );
Hmm, on failure of allocating a new array, we could simply use the old array, and remove the one probe from it instead of just failing.
-- Steve
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+for (i =0 ; old[i]; i++) +if ((probe && old[i] != probe)) + new[j++] = old[i]; + entry->refcount = nr_probes - nr_del; + entry->funcs = new; + } +debug_print_probes (entry); +return old; +} +
Re: [patch 02/17] Kernel Tracepoints
Quoted 27 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 24 lines · Mathieu Desnoyers
kernel/tracepoint.c new file +24
-0+static void * +tracepoint_entry_remove_probe (struct tracepoint_entry *entry,void *probe) +{ +int nr_probes =0 , nr_del =0 , i; +void **old, **new; + + old = entry->funcs; + +debug_print_probes (entry); +/* (N -> M), (N > 1, M >= 0) probes */ +for (nr_probes =0 ; old[nr_probes]; nr_probes++) { +if ((!probe || old[nr_probes] == probe)) + nr_del++; + } + +if (nr_probes - nr_del ==0 ) { +/* N -> 0, (N > 1) */ + entry->funcs =NULL ; + entry->refcount =0 ; +debug_print_probes (entry); +return old; + }else { +int j =0 ; +/* N -> M, (N > 1, M > 0) */
Quoted 9 lines
kernel/tracepoint.c line 154
Quoted 5 lines
kernel/tracepoint.c new file +5
-0+/* + 1 for NULL */ + new =kzalloc ((nr_probes - nr_del +1 ) + *sizeof (void *),GFP_KERNEL ); +if (new ==NULL ) +return ERR_PTR (-ENOMEM );Hmm, on failure of allocating a new array, we could simply use the old array, and remove the one probe from it instead of just failing.
Nay, because of RCU constraints. So we have the readers in the current RCU window who need to see the old version, and readers of the following window who need to see the next version. Both can live at the same time on the system. We cannot reuse the same memory to perform the array shrink without corrupting the data seen by the previous readers. We really have to perform a copy here.
Mathieu
Quoted 12 lines
-- Steve
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+for (i =0 ; old[i]; i++) +if ((probe && old[i] != probe)) + new[j++] = old[i]; + entry->refcount = nr_probes - nr_del; + entry->funcs = new; + } +debug_print_probes (entry); +return old; +} +
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Steven Rostedt
maintainerRe: [patch 02/17] Kernel Tracepoints
Quoted 20 lines · Mathieu Desnoyers
Quoted 10 lines
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+ +if (nr_probes - nr_del ==0 ) { +/* N -> 0, (N > 1) */ + entry->funcs =NULL ; + entry->refcount =0 ; +debug_print_probes (entry); +return old; + }else { +int j =0 ; +/* N -> M, (N > 1, M > 0) */ Quoted 9 lines
kernel/tracepoint.c line 154
Quoted 5 lines
kernel/tracepoint.c new file +5
-0+/* + 1 for NULL */ + new =kzalloc ((nr_probes - nr_del +1 ) + *sizeof (void *),GFP_KERNEL ); +if (new ==NULL ) +return ERR_PTR (-ENOMEM );Hmm, on failure of allocating a new array, we could simply use the old array, and remove the one probe from it instead of just failing.
Quoted 6 lines
Nay, because of RCU constraints. So we have the readers in the current RCU window who need to see the old version, and readers of the following window who need to see the next version. Both can live at the same time on the system. We cannot reuse the same memory to perform the array shrink without corrupting the data seen by the previous readers. We really have to perform a copy here.
Ah, good point. I forgot the whole RCU factor here.
-- Steve
Steven Rostedt
maintainerRe: [patch 02/17] Kernel Tracepoints
In reply to Mathieu DesnoyersQuoted 4 lines · Mathieu Desnoyers
Index:
linux-2.6-lttng/kernel/tracepoint.c
===================================================================kernel/tracepoint.c new file +0
-0
[...]
Quoted 7 lines
kernel/tracepoint.c new file +7
-0+/* +* Tracepoint hash table, containing the active tracepoints. +* Protected by tracepoints_mutex. +*/ +#define TRACEPOINT_HASH_BITS 6 +#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) +
[...]
kernel/tracepoint.c line 177
Quoted 13 lines
kernel/tracepoint.c new file +13
-0+/* +* Get tracepoint if the tracepoint is present in the tracepoint hash table. +* Must be called with tracepoints_mutex held. +* Returns NULL if not present. +*/ +static struct tracepoint_entry *get_tracepoint (const char *name) +{ +struct hlist_head *head; +struct hlist_node *node; +struct tracepoint_entry *e; +u32 hash =jhash (name,strlen (name),0 ); + + head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )];
Wouldn't it look nicer to have: (TRACEPOINT_TABLE_SIZE - 1) ?
hash & (
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+hlist_for_each_entry (e, node, head, hlist) { +if (!strcmp (name, e->name)) +return e; + } +return NULL ; +} + +/* +* Add the tracepoint to the tracepoint hash table. Must be called with +* tracepoints_mutex held.
kernel/tracepoint.c line 197
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+*/ +static struct tracepoint_entry *add_tracepoint (const char *name) +{ +struct hlist_head *head; +struct hlist_node *node; +struct tracepoint_entry *e; +size_t name_len =strlen (name) +1 ; +u32 hash =jhash (name, name_len-1 ,0 ); + + head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )];
here too.
Quoted 26 lines
kernel/tracepoint.c new file +26
-0+hlist_for_each_entry (e, node, head, hlist) { +if (!strcmp (name, e->name)) { +printk (KERN_NOTICE +"tracepoint %s busy\n" , name); +return ERR_PTR (-EEXIST );/* Already there */ + } + } +/* +* Using kmalloc here to allocate a variable length element. Could +* cause some memory fragmentation if overused. +*/ + e =kmalloc (sizeof (struct tracepoint_entry ) + name_len,GFP_KERNEL ); +if (!e) +return ERR_PTR (-ENOMEM ); +memcpy (&e->name[0 ], name, name_len); + e->funcs =NULL ; + e->refcount =0 ; + e->rcu_pending =0 ; +hlist_add_head (&e->hlist, head); +return e; +} + +/* +* Remove the tracepoint from the tracepoint hash table. Must be called with +* mutex_lock held. +*/
kernel/tracepoint.c line 233
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+static int remove_tracepoint (const char *name) +{ +struct hlist_head *head; +struct hlist_node *node; +struct tracepoint_entry *e; +int found =0 ; +size_t len =strlen (name) +1 ; +u32 hash =jhash (name, len-1 ,0 ); + + head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )];
here too.
Quoted 7 lines
kernel/tracepoint.c new file +7
-0+hlist_for_each_entry (e, node, head, hlist) { +if (!strcmp (name, e->name)) { + found =1 ; +break ; + } + } +if (!found)
kernel/tracepoint.c line 250
Quoted 10 lines
kernel/tracepoint.c new file +10
-0+return -ENOENT ; +if (e->refcount) +return -EBUSY ; +hlist_del (&e->hlist); +/* Make sure the call_rcu has been executed */ +if (e->rcu_pending) +rcu_barrier (); +kfree (e); +return 0 ; +}
-- Steve
PATCH 1/1 Tracepoints use TABLE_SIZE macro
Steven Rostedt <[email protected]> :
Wouldn't it look nicer to have: (TRACEPOINT_TABLE_SIZE - 1) ?
me :
Sure,
It applies on top of the "Tracepoints" patch, currently in the ftrace tree.
--- kernel/tracepoint.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/tracepoint.c +3 -3
@@ -177,7 +177,7 @@ static struct tracepoint_entry *get_tracstruct tracepoint_entry *e;u32 hash =jhash (name,strlen (name),0 ); - head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )]; + head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE -1 )];hlist_for_each_entry (e, node, head, hlist) {if (!strcmp (name, e->name))return e;
@@ -197,7 +197,7 @@ static struct tracepoint_entry *add_tracsize_t name_len =strlen (name) +1 ;u32 hash =jhash (name, name_len-1 ,0 ); - head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )]; + head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE -1 )];hlist_for_each_entry (e, node, head, hlist) {if (!strcmp (name, e->name)) { printk(KERN_NOTICE
@@ -233,7 +233,7 @@ static int remove_tracepoint(const charsize_t len =strlen (name) +1 ;u32 hash =jhash (name, len-1 ,0 ); - head = &tracepoint_table[hash & ((1 <<TRACEPOINT_HASH_BITS )-1 )]; + head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE -1 )];hlist_for_each_entry (e, node, head, hlist) {if (!strcmp (name, e->name)) { found =1 ;
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 3/17 Tracepoints Documentation
In reply to Mathieu DesnoyersDocumentation of tracepoint usage.
--- Documentation/tracepoints.txt | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)
Documentation/tracepoints.txt new file +101 -0
@@ -0,0 +1,101 @@ + Using the Linux Kernel Tracepoints + + Mathieu Desnoyers + + +This document introduces Linux Kernel Tracepoints and their use. It provides +examples of how to insert tracepoints in the kernel and connect probe functions +to them and provides some examples of probe functions. + + +* Purpose of tracepoints + +A tracepoint placed in code provides a hook to call a function (probe) that you +can provide at runtime. A tracepoint can be "on" (a probe is connected to it) or +"off" (no probe is attached). When a tracepoint is "off" it has no effect, +except for adding a tiny time penalty (checking a condition for a branch) and +space penalty (adding a few bytes for the function call at the end of the +instrumented function and adds a data structure in a separate section). When a +tracepoint is "on", the function you provide is called each time the tracepoint +is executed, in the execution context of the caller. When the function provided +ends its execution, it returns to the caller (continuing from the tracepoint +site). + +You can put tracepoints at important locations in the code. They are +lightweight hooks that can pass an arbitrary number of parameters, +which prototypes are described in a tracepoint declaration placed in a header +file. + +They can be used for tracing and performance accounting. + + +* Usage + +Two elements are required for tracepoints : + +- A tracepoint definition, placed in a header file. +- The tracepoint statement, in C code. + +In order to use tracepoints, you should include linux/tracepoint.h. + +In include/trace/subsys.h : + +#include <linux/tracepoint.h> + +DEFINE_TRACE(subsys_eventname, + TPPTOTO(int firstarg, struct task_struct *p), + TPARGS(firstarg, p)); + +In subsys/file.c (where the tracing statement must be added) : + +#include <trace/subsys.h> + +void somefct(void) +{ + ... + trace_subsys_eventname(arg, task); + ... +} + +Where : +- subsys_eventname is an identifier unique to your event + - subsys is the name of your subsystem. + - eventname is the name of the event to trace. +- TPPTOTO(int firstarg, struct task_struct *p) is the prototype of the function + called by this tracepoint. +- TPARGS(firstarg, p) are the parameters names, same as found in the prototype. + +Connecting a function (probe) to a tracepoint is done by providing a probe +(function to call) for the specific tracepoint through +register_trace_subsys_eventname(). Removing a probe is done through +unregister_trace_subsys_eventname(); it will remove the probe sure there is no +caller left using the probe when it returns. Probe removal is preempt-safe +because preemption is disabled around the probe call. See the "Probe example" +section below for a sample probe module. + +The tracepoint mechanism supports inserting multiple instances of the same +tracepoint, but a single definition must be made of a given tracepoint name over +all the kernel to make sure no type conflict will occur. Name mangling of the +tracepoints is done using the prototypes to make sure typing is correct. +Verification of probe type correctness is done at the registration site by the +compiler. Tracepoints can be put in inline functions, inlined static functions, +and unrolled loops as well as regular functions. + +The naming scheme "subsys_event" is suggested here as a convention intended +to limit collisions. Tracepoint names are global to the kernel: they are +considered as being the same whether they are in the core kernel image or in +modules. + + +* Probe / tracepoint example + +See the example provided in samples/tracepoints/src + +Compile them with your kernel. + +Run, as root : +modprobe tracepoint-example (insmod order is not important) +modprobe tracepoint-probe-example +cat /proc/tracepoint-example (returns an expected error) +rmmod tracepoint-example tracepoint-probe-example +dmesg
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 4/17 Tracepoints Samples
In reply to Mathieu DesnoyersTracepoint example code under samples/.
--- samples/Kconfig | 6 ++ samples/Makefile | 2 samples/tracepoints/Makefile | 6 ++ samples/tracepoints/tp-samples-trace.h | 13 +++++ samples/tracepoints/tracepoint-probe-sample.c | 55 +++++++++++++++++++++++++ samples/tracepoints/tracepoint-probe-sample2.c | 42 +++++++++++++++++++ samples/tracepoints/tracepoint-sample.c | 53 ++++++++++++++++++++++++ 7 files changed, 176 insertions(+), 1 deletion(-)
samples/Kconfig +6 -0
@@ -13,6 +13,12 @@ config SAMPLE_MARKERS help This build markers example modules. +config SAMPLE_TRACEPOINTS + tristate "Build tracepoints examples -- loadable modules only" + depends on TRACEPOINTS && m + help + This build tracepoints example modules. + config SAMPLE_KOBJECT tristate "Build kobject examples" help
samples/tracepoints/Makefile new file +6 -0
@@ -0,0 +1,6 @@ +# builds the tracepoint example kernel modules; +# then to use one (as root): insmod <module_name.ko> + +obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-sample.o +obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample.o +obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample2.o
samples/tracepoints/tracepoint-probe-sample.c new file +55 -0
55 lines not on this page · raw message
samples/tracepoints/tracepoint-sample.c new file +53 -0
53 lines not on this page · raw message
samples/tracepoints/tp-samples-trace.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _TP_SAMPLES_TRACE_H +#define _TP_SAMPLES_TRACE_H + +#include <linux/proc_fs.h> /* for struct inode and struct file */ +#include <linux/tracepoint.h> + +DEFINE_TRACE (subsys_event, + TPPROTO(struct inode *inode, struct file *file), +TPARGS (inode, file)); +DEFINE_TRACE (subsys_eventb, +TPPROTO (void), +TPARGS ()); +#endif
samples/Makefile +1 -1
@@ -1,3 +1,3 @@ # Makefile for Linux samples code -obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ +obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/
samples/tracepoints/tracepoint-probe-sample2.c new file +42 -0
42 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 5/17 LTTng instrumentation - irq
In reply to Mathieu DesnoyersInstrumentation of IRQ related events : irq, softirq, tasklet entry and exit and softirq "raise" events.
It allows tracers to perform latency analysis on those various types of interrupts and to detect interrupts with max/min/avg duration. It helps detecting driver or hardware problems which cause an ISR to take ages to execute. It has been shown to be the case with bogus hardware causing an mmio read to take a few milliseconds.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Changelog:
- Add retval as irq_exit argument.
--- include/trace/irq.h | 36 ++++++++++++++++++++++++++++++++++++ kernel/irq/handle.c | 6 ++++++ kernel/softirq.c | 8 ++++++++ 3 files changed, 50 insertions(+)
kernel/irq/handle.c +6 -0
@@ -15,6 +15,7 @@#include <linux/random.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> +#include <trace/irq.h> #include "internals.h"
@@ -130,6 +131,9 @@ irqreturn_t handle_IRQ_event(unsigned in {irqreturn_t ret, retval =IRQ_NONE ;unsigned int status =0 ; +struct pt_regs *regs =get_irq_regs (); + +trace_irq_entry (irq, regs);handle_dynamic_tick (action);
@@ -148,6 +152,8 @@ irqreturn_t handle_IRQ_event(unsigned inadd_interrupt_randomness (irq);local_irq_disable (); +trace_irq_exit (retval); +return retval; }
kernel/softirq.c +8 -0
@@ -21,6 +21,7 @@#include <linux/rcupdate.h> #include <linux/smp.h> #include <linux/tick.h> +#include <trace/irq.h> #include <asm/irq.h> /*
@@ -205,7 +206,9 @@ restart: do { if (pending & 1) { + trace_irq_softirq_entry(h, softirq_vec); h->action(h); + trace_irq_softirq_exit(h, softirq_vec); rcu_bh_qsctr_inc(cpu); } h++;
@@ -297,6 +300,7 @@ void irq_exit(void)*/ inline void raise_softirq_irqoff (unsigned int nr) { +trace_irq_softirq_raise (nr);__raise_softirq_irqoff (nr);/*
@@ -394,7 +398,9 @@ static void tasklet_action(struct softirif (!atomic_read (&t->count)) {if (!test_and_clear_bit (TASKLET_STATE_SCHED , &t->state))BUG (); +trace_irq_tasklet_low_entry (t); t->func (t->data); +trace_irq_tasklet_low_exit (t);tasklet_unlock (t);continue ; }
@@ -429,7 +435,9 @@ static void tasklet_hi_action(struct sofif (!atomic_read (&t->count)) {if (!test_and_clear_bit (TASKLET_STATE_SCHED , &t->state))BUG (); +trace_irq_tasklet_high_entry (t); t->func (t->data); +trace_irq_tasklet_high_exit (t);tasklet_unlock (t);continue ; }
include/trace/irq.h new file +36 -0
@@ -0,0 +1,36 @@ +#ifndef _TRACE_IRQ_H +#define _TRACE_IRQ_H + +#include <linux/kdebug.h> +#include <linux/interrupt.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (irq_entry, + TPPROTO(unsigned int id, struct pt_regs *regs), +TPARGS (id, regs)); +DEFINE_TRACE (irq_exit, + TPPROTO(irqreturn_t retval), +TPARGS (retval)); +DEFINE_TRACE (irq_softirq_entry, + TPPROTO(struct softirq_action *h, struct softirq_action *softirq_vec), +TPARGS (h, softirq_vec)); +DEFINE_TRACE (irq_softirq_exit, + TPPROTO(struct softirq_action *h, struct softirq_action *softirq_vec), +TPARGS (h, softirq_vec)); +DEFINE_TRACE (irq_softirq_raise, + TPPROTO(unsigned int nr), +TPARGS (nr)); +DEFINE_TRACE (irq_tasklet_low_entry, + TPPROTO(struct tasklet_struct *t), +TPARGS (t)); +DEFINE_TRACE (irq_tasklet_low_exit, + TPPROTO(struct tasklet_struct *t), +TPARGS (t)); +DEFINE_TRACE (irq_tasklet_high_entry, + TPPROTO(struct tasklet_struct *t), +TPARGS (t)); +DEFINE_TRACE (irq_tasklet_high_exit, + TPPROTO(struct tasklet_struct *t), +TPARGS (t)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 6/17 LTTng instrumentation - scheduler
In reply to Mathieu DesnoyersInstrument the scheduler activity (sched_switch, migration, wakeups, wait for a task, signal delivery) and process/thread creation/destruction (fork, exit, kthread stop). Actually, kthread creation is not instrumented in this patch because it is architecture dependent. It allows to connect tracers such as ftrace which detects scheduling latencies, good/bad scheduler decisions. Tools like LTTng can export this scheduler information along with instrumentation of the rest of the kernel activity to perform post-mortem analysis on the scheduler activity.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Changelog :
- Change instrumentation location and parameter to match ftrace instrumentation, previously done with kernel markers.
--- include/trace/sched.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ kernel/exit.c | 6 ++++++ kernel/fork.c | 3 +++ kernel/kthread.c | 5 +++++ kernel/sched.c | 17 ++++++----------- kernel/signal.c | 3 +++ 6 files changed, 68 insertions(+), 11 deletions(-)
kernel/kthread.c +5 -0
@@ -13,6 +13,7 @@#include <linux/file.h> #include <linux/module.h> #include <linux/mutex.h> +#include <trace/sched.h> #define KTHREAD_NICE_LEVEL (-5)
@@ -187,6 +188,8 @@ int kthread_stop(struct task_struct *k)/* It could exit after stop_info.k set, but before wake_up_process. */ get_task_struct (k); +trace_sched_kthread_stop (k); +/* Must init completion *before* thread sees kthread_stop_info.k */ init_completion (&kthread_stop_info.done);smp_wmb ();
@@ -202,6 +205,8 @@ int kthread_stop(struct task_struct *k) ret = kthread_stop_info.err;mutex_unlock (&kthread_stop_lock); +trace_sched_kthread_stop_ret (ret); +return ret; }EXPORT_SYMBOL (kthread_stop);
kernel/sched.c +6 -11
@@ -71,6 +71,7 @@#include <linux/debugfs.h> #include <linux/ctype.h> #include <linux/ftrace.h> +#include <trace/sched.h> #include <asm/tlb.h> #include <asm/irq_regs.h>
@@ -1987,6 +1988,7 @@ void wait_task_inactive(struct task_stru* just go back and repeat. */ rq =task_rq_lock (p, &flags); +trace_sched_wait_task (rq, p); running =task_running (rq, p); on_rq = p->se.on_rq;task_rq_unlock (rq, &flags);
@@ -2337,9 +2339,7 @@ out_activate: success =1 ; out_running: -trace_mark (kernel_sched_wakeup, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup (rq, p);check_preempt_curr (rq, p); p->state =TASK_RUNNING ;
@@ -2472,9 +2472,7 @@ void wake_up_new_task(struct task_struct p->sched_class->task_new (rq, p);inc_nr_running (rq); } -trace_mark (kernel_sched_wakeup_new, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup_new (rq, p);check_preempt_curr (rq, p);#ifdef CONFIG_SMP if (p->sched_class->task_wake_up)
@@ -2647,11 +2645,7 @@ context_switch(struct rq *rq, struct tasstruct mm_struct *mm, *oldmm;prepare_task_switch (rq, prev, next); -trace_mark (kernel_sched_schedule, -"prev_pid %d next_pid %d prev_state %ld " -"## rq %p prev %p next %p" , - prev->pid, next->pid, prev->state, - rq, prev, next); +trace_sched_switch (rq, prev, next); mm = next->mm; oldmm = prev->active_mm;/*
@@ -2884,6 +2878,7 @@ static void sched_migrate_task(struct ta || unlikely(cpu_is_offline(dest_cpu))) goto out; +trace_sched_migrate_task (rq, p, dest_cpu);/* force the process onto the specified CPU */ if (migrate_task (p, dest_cpu, &req)) {/* Need to wait for migration thread (might exit: take ref). */
kernel/exit.c +6 -0
@@ -46,6 +46,7 @@#include <linux/resource.h> #include <linux/blkdev.h> #include <linux/task_io_accounting_ops.h> +#include <trace/sched.h> #include <asm/uaccess.h> #include <asm/unistd.h>
@@ -149,6 +150,7 @@ static void __exit_signal(struct task_ststatic void delayed_put_task_struct (struct rcu_head *rhp) { +trace_sched_process_free (container_of(rhp ,struct task_struct ,rcu ));put_task_struct (container_of(rhp ,struct task_struct ,rcu )); }
@@ -1040,6 +1042,8 @@ NORET_TYPE void do_exit(long code)if (group_dead)acct_process (); +trace_sched_process_exit (tsk); +exit_sem (tsk);exit_files (tsk);exit_fs (tsk);
@@ -1524,6 +1528,8 @@ static long do_wait(enum pid_type type,struct task_struct *tsk;int flag, retval; +trace_sched_process_wait (pid); +add_wait_queue (¤t->signal->wait_chldexit,&wait); repeat:/* If there is nothing that can match our critier just get out */
kernel/fork.c +3 -0
@@ -56,6 +56,7 @@#include <linux/proc_fs.h> #include <linux/blkdev.h> #include <linux/magic.h> +#include <trace/sched.h> #include <asm/pgtable.h> #include <asm/pgalloc.h>
@@ -1362,6 +1363,8 @@ long do_fork(unsigned long clone_flags,if (!IS_ERR (p)) {struct completion vfork; +trace_sched_process_fork (current, p); + nr =task_pid_vnr (p);if (clone_flags &CLONE_PARENT_SETTID )
kernel/signal.c +3 -0
@@ -26,6 +26,7 @@#include <linux/freezer.h> #include <linux/pid_namespace.h> #include <linux/nsproxy.h> +#include <trace/sched.h> #include <asm/param.h> #include <asm/uaccess.h>
@@ -807,6 +808,8 @@ static int send_signal(int sig, struct sstruct sigpending *pending;struct sigqueue *q; +trace_sched_signal_send (sig, t); +assert_spin_locked (&t->sighand->siglock);if (!prepare_signal (sig, t))return 0 ;
include/trace/sched.h new file +45 -0
45 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Peter Zijlstra
maintainerRe: [patch 06/17] LTTng instrumentation - scheduler
Quoted 61 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-scheduler.patch) Instrument the scheduler activity (
sched_switch, migration, wakeups, wait for a task, signal delivery) and process/thread creation/destruction (fork, exit, kthread stop). Actually, kthread creation is not instrumented in this patch because it is architecture dependent. It allows to connect tracers such as ftrace which detects scheduling latencies, good/bad scheduler decisions. Tools like LTTng can export this scheduler information along with instrumentation of the rest of the kernel activity to perform post-mortem analysis on the scheduler activity.About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Changelog :
- Change instrumentation location and parameter to match ftrace instrumentation, previously done with kernel markers.Signed-off-by Mathieu Desnoyers <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Thomas Gleixner <[email protected]>CC Masami Hiramatsu <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/sched.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ kernel/exit.c | 6 ++++++ kernel/fork.c | 3 +++ kernel/kthread.c | 5 +++++ kernel/sched.c | 17 ++++++----------- kernel/signal.c | 3 +++ 6 files changed, 68 insertions(+), 11 deletions(-)Index:
linux-2.6-lttng/kernel/kthread.c
===================================================================kernel/kthread.c +3
-0@@ -13,6 +13,7 @@#include <linux/file.h> #include <linux/module.h> #include <linux/mutex.h> +#include <trace/sched.h> #define KTHREAD_NICE_LEVEL (-5)@@ -187,6 +188,8 @@ int kthread_stop(struct task_struct *k)/* It could exit after stop_info.k set, but before wake_up_process. */ get_task_struct (k); +trace_sched_kthread_stop (k); +/* Must init completion *before* thread sees kthread_stop_info.k */ init_completion (&kthread_stop_info.done);smp_wmb ();
kernel/kthread.c int kthread_stop(struct task_struct *k) · line 212
Quoted 8 lines
kernel/kthread.c +2
-0@@ -202,6 +205,8 @@ int kthread_stop(struct task_struct *k) ret = kthread_stop_info.err;mutex_unlock (&kthread_stop_lock); +trace_sched_kthread_stop_ret (ret); +return ret; }EXPORT_SYMBOL (kthread_stop);
Why do we need two trace points in this function?
Quoted 76 lines
Index:
linux-2.6-lttng/kernel/sched.c
===================================================================kernel/sched.c +6
-11@@ -71,6 +71,7 @@#include <linux/debugfs.h> #include <linux/ctype.h> #include <linux/ftrace.h> +#include <trace/sched.h> #include <asm/tlb.h> #include <asm/irq_regs.h> @@ -1987,6 +1988,7 @@ void wait_task_inactive(struct task_stru* just go back and repeat. */ rq =task_rq_lock (p, &flags); +trace_sched_wait_task (rq, p); running =task_running (rq, p); on_rq = p->se.on_rq;task_rq_unlock (rq, &flags);@@ -2337,9 +2339,7 @@ out_activate: success =1 ; out_running: -trace_mark (kernel_sched_wakeup, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup (rq, p);check_preempt_curr (rq, p); p->state =TASK_RUNNING ;@@ -2472,9 +2472,7 @@ void wake_up_new_task(struct task_struct p->sched_class->task_new (rq, p);inc_nr_running (rq); } -trace_mark (kernel_sched_wakeup_new, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup_new (rq, p);check_preempt_curr (rq, p);#ifdef CONFIG_SMP if (p->sched_class->task_wake_up)@@ -2647,11 +2645,7 @@ context_switch(struct rq *rq, struct tasstruct mm_struct *mm, *oldmm;prepare_task_switch (rq, prev, next); -trace_mark (kernel_sched_schedule, -"prev_pid %d next_pid %d prev_state %ld " -"## rq %p prev %p next %p" , - prev->pid, next->pid, prev->state, - rq, prev, next); +trace_sched_switch (rq, prev, next); mm = next->mm; oldmm = prev->active_mm;/* @@ -2884,6 +2878,7 @@ static void sched_migrate_task(struct ta || unlikely(cpu_is_offline(dest_cpu))) goto out; +trace_sched_migrate_task (rq, p, dest_cpu);/* force the process onto the specified CPU */ if (migrate_task (p, dest_cpu, &req)) {/* Need to wait for migration thread (might exit: take ref). */ Index:
linux-2.6-lttng/kernel/exit.c
===================================================================kernel/exit.c +1
-0@@ -46,6 +46,7 @@#include <linux/resource.h> #include <linux/blkdev.h> #include <linux/task_io_accounting_ops.h> +#include <trace/sched.h> #include <asm/uaccess.h> #include <asm/unistd.h>
kernel/exit.c static void __exit_signal(struct task_st · line 155
Quoted 6 lines
kernel/exit.c +1
-0@@ -149,6 +150,7 @@ static void __exit_signal(struct task_ststatic void delayed_put_task_struct (struct rcu_head *rhp) { +trace_sched_process_free (container_of(rhp ,struct task_struct ,rcu ));put_task_struct (container_of(rhp ,struct task_struct ,rcu )); }
It might make sense to write it like:
static void delayed_put_task_struct(struct rcu_head *rhp)
{
struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
trace_sched_process_free(tsk);
put_task_struct(tsk);
}Quoted 52 lines
kernel/exit.c +4
-0@@ -1040,6 +1042,8 @@ NORET_TYPE void do_exit(long code)if (group_dead)acct_process (); +trace_sched_process_exit (tsk); +exit_sem (tsk);exit_files (tsk);exit_fs (tsk);@@ -1524,6 +1528,8 @@ static long do_wait(enum pid_type type,struct task_struct *tsk;int flag, retval; +trace_sched_process_wait (pid); +add_wait_queue (¤t->signal->wait_chldexit,&wait); repeat:/* If there is nothing that can match our critier just get out */ Index:
linux-2.6-lttng/kernel/fork.c
===================================================================kernel/fork.c +3
-0@@ -56,6 +56,7 @@#include <linux/proc_fs.h> #include <linux/blkdev.h> #include <linux/magic.h> +#include <trace/sched.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -1362,6 +1363,8 @@ long do_fork(unsigned long clone_flags,if (!IS_ERR (p)) {struct completion vfork; +trace_sched_process_fork (current, p); + nr =task_pid_vnr (p);if (clone_flags &CLONE_PARENT_SETTID )Index:
linux-2.6-lttng/kernel/signal.c
===================================================================kernel/signal.c +1
-0@@ -26,6 +26,7 @@#include <linux/freezer.h> #include <linux/pid_namespace.h> #include <linux/nsproxy.h> +#include <trace/sched.h> #include <asm/param.h> #include <asm/uaccess.h>
kernel/signal.c static int send_signal(int sig, struct s · line 815
Quoted 8 lines
kernel/signal.c +2
-0@@ -807,6 +808,8 @@ static int send_signal(int sig, struct sstruct sigpending *pending;struct sigqueue *q; +trace_sched_signal_send (sig, t); +assert_spin_locked (&t->sighand->siglock);if (!prepare_signal (sig, t))return 0 ;
Would it make sense to also put a trace point on receiveing a signal?
/me utterly clueless about the whole signal stuff.
Quoted 51 lines
Index:
linux-2.6-lttng/include/trace/sched.h
===================================================================include/trace/sched.h new file +45
-0@@ -0,0 +1,45 @@ +#ifndef _TRACE_SCHED_H +#define _TRACE_SCHED_H + +#include <linux/sched.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (sched_kthread_stop, + TPPROTO(struct task_struct *t), +TPARGS (t)); +DEFINE_TRACE (sched_kthread_stop_ret, + TPPROTO(int ret), +TPARGS (ret)); +DEFINE_TRACE (sched_wait_task, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_wakeup, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_wakeup_new, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_switch, + TPPROTO(struct rq *rq, struct task_struct *prev, + struct task_struct *next), +TPARGS (rq, prev, next)); +DEFINE_TRACE (sched_migrate_task, + TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu), +TPARGS (rq, p, dest_cpu)); +DEFINE_TRACE (sched_process_free, + TPPROTO(struct task_struct *p), +TPARGS (p)); +DEFINE_TRACE (sched_process_exit, + TPPROTO(struct task_struct *p), +TPARGS (p)); +DEFINE_TRACE (sched_process_wait, + TPPROTO(struct pid *pid), +TPARGS (pid)); +DEFINE_TRACE (sched_process_fork, + TPPROTO(struct task_struct *parent, struct task_struct *child), +TPARGS (parent, child)); +DEFINE_TRACE (sched_signal_send, + TPPROTO(int sig, struct task_struct *p), +TPARGS (sig, p)); + +#endif
Re: [patch 06/17] LTTng instrumentation - scheduler
Quoted 65 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 64 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-scheduler.patch) Instrument the scheduler activity (
sched_switch, migration, wakeups, wait for a task, signal delivery) and process/thread creation/destruction (fork, exit, kthread stop). Actually, kthread creation is not instrumented in this patch because it is architecture dependent. It allows to connect tracers such as ftrace which detects scheduling latencies, good/bad scheduler decisions. Tools like LTTng can export this scheduler information along with instrumentation of the rest of the kernel activity to perform post-mortem analysis on the scheduler activity.About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Changelog :
- Change instrumentation location and parameter to match ftrace instrumentation, previously done with kernel markers.Signed-off-by Mathieu Desnoyers <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Thomas Gleixner <[email protected]>CC Masami Hiramatsu <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/sched.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ kernel/exit.c | 6 ++++++ kernel/fork.c | 3 +++ kernel/kthread.c | 5 +++++ kernel/sched.c | 17 ++++++----------- kernel/signal.c | 3 +++ 6 files changed, 68 insertions(+), 11 deletions(-)Index:
linux-2.6-lttng/kernel/kthread.c
===================================================================kernel/kthread.c +3
-0@@ -13,6 +13,7 @@#include <linux/file.h> #include <linux/module.h> #include <linux/mutex.h> +#include <trace/sched.h> #define KTHREAD_NICE_LEVEL (-5)@@ -187,6 +188,8 @@ int kthread_stop(struct task_struct *k)/* It could exit after stop_info.k set, but before wake_up_process. */ get_task_struct (k); +trace_sched_kthread_stop (k); +/* Must init completion *before* thread sees kthread_stop_info.k */ init_completion (&kthread_stop_info.done);smp_wmb ();@@ -202,6 +205,8 @@ int kthread_stop(struct task_struct *k) ret = kthread_stop_info.err;mutex_unlock (&kthread_stop_lock);
Quoted 8 lines
kernel/kthread.c int kthread_stop(struct task_struct *k) · line 212
Quoted 5 lines
kernel/kthread.c +2
-0+trace_sched_kthread_stop_ret (ret); +return ret; }EXPORT_SYMBOL (kthread_stop);Why do we need two trace points in this function?
As of my understanding, if we look at the complete function :
int kthread_stop(struct task_struct *k)
{
int ret;
mutex_lock(&kthread_stop_lock);
/* It could exit after stop_info.k set, but before wake_up_process. */
get_task_struct(k);
trace_sched_kthread_stop(k);
/* Must init completion *before* thread sees kthread_stop_info.k */
init_completion(&kthread_stop_info.done);
smp_wmb();
/* Now set kthread_should_stop() to true, and wake it up. */
kthread_stop_info.k = k;
wake_up_process(k);
put_task_struct(k);--> starting from this point, k can be freed by the thread being stopped and exiting. Therefore, if we want an identifier about the thread about to stop, we have to instrument before this point.
/* Once it dies, reset stop ptr, gather result and we're done. */
wait_for_completion(&kthread_stop_info.done);
kthread_stop_info.k = NULL;
ret = kthread_stop_info.err;
mutex_unlock(&kthread_stop_lock);
trace_sched_kthread_stop_ret(ret);---> the success of this operation is only known after "ret" is assigned. So this is why I couldn't find one tracepoint to have both valid "k" and "ret" at the same time.
return ret; }
Quoted 85 lines
Quoted 76 lines
Index:
linux-2.6-lttng/kernel/sched.c
===================================================================kernel/sched.c +6
-11@@ -71,6 +71,7 @@#include <linux/debugfs.h> #include <linux/ctype.h> #include <linux/ftrace.h> +#include <trace/sched.h> #include <asm/tlb.h> #include <asm/irq_regs.h> @@ -1987,6 +1988,7 @@ void wait_task_inactive(struct task_stru* just go back and repeat. */ rq =task_rq_lock (p, &flags); +trace_sched_wait_task (rq, p); running =task_running (rq, p); on_rq = p->se.on_rq;task_rq_unlock (rq, &flags);@@ -2337,9 +2339,7 @@ out_activate: success =1 ; out_running: -trace_mark (kernel_sched_wakeup, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup (rq, p);check_preempt_curr (rq, p); p->state =TASK_RUNNING ;@@ -2472,9 +2472,7 @@ void wake_up_new_task(struct task_struct p->sched_class->task_new (rq, p);inc_nr_running (rq); } -trace_mark (kernel_sched_wakeup_new, -"pid %d state %ld ## rq %p task %p rq->curr %p" , - p->pid, p->state, rq, p, rq->curr); +trace_sched_wakeup_new (rq, p);check_preempt_curr (rq, p);#ifdef CONFIG_SMP if (p->sched_class->task_wake_up)@@ -2647,11 +2645,7 @@ context_switch(struct rq *rq, struct tasstruct mm_struct *mm, *oldmm;prepare_task_switch (rq, prev, next); -trace_mark (kernel_sched_schedule, -"prev_pid %d next_pid %d prev_state %ld " -"## rq %p prev %p next %p" , - prev->pid, next->pid, prev->state, - rq, prev, next); +trace_sched_switch (rq, prev, next); mm = next->mm; oldmm = prev->active_mm;/* @@ -2884,6 +2878,7 @@ static void sched_migrate_task(struct ta || unlikely(cpu_is_offline(dest_cpu))) goto out; +trace_sched_migrate_task (rq, p, dest_cpu);/* force the process onto the specified CPU */ if (migrate_task (p, dest_cpu, &req)) {/* Need to wait for migration thread (might exit: take ref). */ Index:
linux-2.6-lttng/kernel/exit.c
===================================================================kernel/exit.c +1
-0@@ -46,6 +46,7 @@#include <linux/resource.h> #include <linux/blkdev.h> #include <linux/task_io_accounting_ops.h> +#include <trace/sched.h> #include <asm/uaccess.h> #include <asm/unistd.h> kernel/exit.c static void __exit_signal(struct task_st · line 155
Quoted 6 lines
kernel/exit.c +1
-0@@ -149,6 +150,7 @@ static void __exit_signal(struct task_ststatic void delayed_put_task_struct (struct rcu_head *rhp) { +trace_sched_process_free (container_of(rhp ,struct task_struct ,rcu ));put_task_struct (container_of(rhp ,struct task_struct ,rcu )); }It might make sense to write it like:
Quoted 8 lines
static void
delayed_put_task_struct(struct rcu_head *rhp){ struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); trace_sched_process_free(tsk); put_task_struct(tsk); }
Yep, will fix.
Quoted 63 lines
Quoted 52 lines
kernel/exit.c +4
-0@@ -1040,6 +1042,8 @@ NORET_TYPE void do_exit(long code)if (group_dead)acct_process (); +trace_sched_process_exit (tsk); +exit_sem (tsk);exit_files (tsk);exit_fs (tsk);@@ -1524,6 +1528,8 @@ static long do_wait(enum pid_type type,struct task_struct *tsk;int flag, retval; +trace_sched_process_wait (pid); +add_wait_queue (¤t->signal->wait_chldexit,&wait); repeat:/* If there is nothing that can match our critier just get out */ Index:
linux-2.6-lttng/kernel/fork.c
===================================================================kernel/fork.c +3
-0@@ -56,6 +56,7 @@#include <linux/proc_fs.h> #include <linux/blkdev.h> #include <linux/magic.h> +#include <trace/sched.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> @@ -1362,6 +1363,8 @@ long do_fork(unsigned long clone_flags,if (!IS_ERR (p)) {struct completion vfork; +trace_sched_process_fork (current, p); + nr =task_pid_vnr (p);if (clone_flags &CLONE_PARENT_SETTID )Index:
linux-2.6-lttng/kernel/signal.c
===================================================================kernel/signal.c +1
-0@@ -26,6 +26,7 @@#include <linux/freezer.h> #include <linux/pid_namespace.h> #include <linux/nsproxy.h> +#include <trace/sched.h> #include <asm/param.h> #include <asm/uaccess.h> kernel/signal.c static int send_signal(int sig, struct s · line 815
Quoted 8 lines
kernel/signal.c +2
-0@@ -807,6 +808,8 @@ static int send_signal(int sig, struct sstruct sigpending *pending;struct sigqueue *q; +trace_sched_signal_send (sig, t); +assert_spin_locked (&t->sighand->siglock);if (!prepare_signal (sig, t))return 0 ;Would it make sense to also put a trace point on receiveing a signal?
Quoted 2 lines
/me utterly clueless about the whole signal stuff.
When the signal is sent, it is added to the pending signal list of the target process. Unless the process blocks the signal, its TIF_SIGPENDING thread flag is set and the process (actually, all threads in the process) is then woken up. If signals are blocked by that process, it will set its own TIF_SIGPENDING flag when it unblocks the signals. recalc_sigpending() as well as a few other code paths) set/clear the thread flag TIF_SIGPENDING which controls delivery of signals on interrupt, trap and syscall return paths to userspace.
When TIF_SIGPENDING is set, do_signal(regs) is called. It is architecture specific (I'm currently looking at x86_32). It delivers the signal by calling the arch-specific handle_signal().
So I think that handle_signal() could be an interesting function to instrument within each architecture to know exactly when the signal stack is setup. However, since we are currently discussing architecture-independent instrumentation, instrumenting all
set_tsk_thread_flag(p, TIF_SIGPENDING);
statements would be good to learn whenever the signal is being seen by the target process.
Since this thread flag is set at 3 locations in signal.c, putting a wrapper around set_tsk_thread_flag(t, TIF_SIGPENDING); and inserting a tracepoint with each call could make sense.
But we can also decide that knowing when a signal is sent is enough, and that by simply inserting the correct architecture-specific instrumentation we learn when the signal is delivered...
Mathieu
Quoted 52 lines
Quoted 51 lines
Index:
linux-2.6-lttng/include/trace/sched.h
===================================================================include/trace/sched.h new file +45
-0@@ -0,0 +1,45 @@ +#ifndef _TRACE_SCHED_H +#define _TRACE_SCHED_H + +#include <linux/sched.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (sched_kthread_stop, + TPPROTO(struct task_struct *t), +TPARGS (t)); +DEFINE_TRACE (sched_kthread_stop_ret, + TPPROTO(int ret), +TPARGS (ret)); +DEFINE_TRACE (sched_wait_task, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_wakeup, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_wakeup_new, + TPPROTO(struct rq *rq, struct task_struct *p), +TPARGS (rq, p)); +DEFINE_TRACE (sched_switch, + TPPROTO(struct rq *rq, struct task_struct *prev, + struct task_struct *next), +TPARGS (rq, prev, next)); +DEFINE_TRACE (sched_migrate_task, + TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu), +TPARGS (rq, p, dest_cpu)); +DEFINE_TRACE (sched_process_free, + TPPROTO(struct task_struct *p), +TPARGS (p)); +DEFINE_TRACE (sched_process_exit, + TPPROTO(struct task_struct *p), +TPARGS (p)); +DEFINE_TRACE (sched_process_wait, + TPPROTO(struct pid *pid), +TPARGS (pid)); +DEFINE_TRACE (sched_process_fork, + TPPROTO(struct task_struct *parent, struct task_struct *child), +TPARGS (parent, child)); +DEFINE_TRACE (sched_signal_send, + TPPROTO(int sig, struct task_struct *p), +TPARGS (sig, p)); + +#endif
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 7/17 LTTng instrumentation - timer
In reply to Mathieu DesnoyersInstrument timer activity (timer set, expired, current time updates) to keep information about the "real time" flow within the kernel. It can be used by a trace analysis tool to synchronize information coming from various sources, e.g. to merge traces with system logs.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/timer.h | 24 ++++++++++++++++++++++++ kernel/itimer.c | 5 +++++ kernel/timer.c | 8 +++++++- 3 files changed, 36 insertions(+), 1 deletion(-)
kernel/itimer.c +5 -0
@@ -12,6 +12,7 @@#include <linux/time.h> #include <linux/posix-timers.h> #include <linux/hrtimer.h> +#include <trace/timer.h> #include <asm/uaccess.h>
@@ -132,6 +133,8 @@ enum hrtimer_restart it_real_fn(struct hstruct signal_struct *sig = container_of(timer, struct signal_struct, real_timer); +trace_timer_itimer_expired (sig); +kill_pid_info (SIGALRM ,SEND_SIG_PRIV , sig->leader_pid);return HRTIMER_NORESTART ;
@@ -157,6 +160,8 @@ int do_setitimer(int which, struct itime !timeval_valid(&value->it_interval))return -EINVAL ; +trace_timer_itimer_set (which, value); +switch (which) {case ITIMER_REAL : again:
kernel/timer.c +7 -1
@@ -37,12 +37,14 @@#include <linux/delay.h> #include <linux/tick.h> #include <linux/kallsyms.h> +#include <trace/timer.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/div64.h> #include <asm/timex.h> #include <asm/io.h> +#include <asm/irq_regs.h> u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
@@ -288,6 +290,7 @@ static void internal_add_timer(struct tv i = (expires >> (TVR_BITS +3 *TVN_BITS )) &TVN_MASK ; vec = base->tv5.vec + i; } +trace_timer_set (timer);/* * Timers are FIFO: */
@@ -1066,6 +1069,7 @@ void do_timer(unsigned long ticks) { jiffies_64 += ticks;update_times (ticks); +trace_timer_update_time (&xtime, &wall_to_monotonic); }#ifdef __ARCH_WANT_SYS_ALARM
@@ -1147,7 +1151,9 @@ asmlinkage long sys_getegid(void)static void process_timeout (unsigned long __data) { -wake_up_process ((struct task_struct *)__data); +struct task_struct *task = (struct task_struct *)__data; +trace_timer_timeout (task); +wake_up_process (task); }/**
include/trace/timer.h new file +24 -0
@@ -0,0 +1,24 @@ +#ifndef _TRACE_TIMER_H +#define _TRACE_TIMER_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (timer_itimer_expired, + TPPROTO(struct signal_struct *sig), +TPARGS (sig)); +DEFINE_TRACE (timer_itimer_set, + TPPROTO(int which, struct itimerval *value), +TPARGS (which, value)); +DEFINE_TRACE (timer_set, + TPPROTO(struct timer_list *timer), +TPARGS (timer)); +/* +* xtime_lock is taken when kernel_timer_update_time tracepoint is reached. +*/ +DEFINE_TRACE (timer_update_time, + TPPROTO(struct timespec *_xtime, struct timespec *_wall_to_monotonic), +TPARGS (_xtime, _wall_to_monotonic)); +DEFINE_TRACE (timer_timeout, + TPPROTO(struct task_struct *p), +TPARGS (p)); +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Peter Zijlstra
maintainerRe: [patch 07/17] LTTng instrumentation - timer
Quoted 88 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-timer.patch) Instrument timer activity (timer set, expired, current time updates) to keep information about the "real time" flow within the kernel. It can be used by a trace analysis tool to synchronize information coming from various sources, e.g. to merge traces with system logs.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC 'Ingo Molnar' <[email protected]>CC "David S. Miller" <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/timer.h | 24 ++++++++++++++++++++++++ kernel/itimer.c | 5 +++++ kernel/timer.c | 8 +++++++- 3 files changed, 36 insertions(+), 1 deletion(-)Index:
linux-2.6-lttng/kernel/itimer.c
===================================================================kernel/itimer.c +5
-0@@ -12,6 +12,7 @@#include <linux/time.h> #include <linux/posix-timers.h> #include <linux/hrtimer.h> +#include <trace/timer.h> #include <asm/uaccess.h> @@ -132,6 +133,8 @@ enum hrtimer_restart it_real_fn(struct hstruct signal_struct *sig = container_of(timer, struct signal_struct, real_timer); +trace_timer_itimer_expired (sig); +kill_pid_info (SIGALRM ,SEND_SIG_PRIV , sig->leader_pid);return HRTIMER_NORESTART ;@@ -157,6 +160,8 @@ int do_setitimer(int which, struct itime !timeval_valid(&value->it_interval))return -EINVAL ; +trace_timer_itimer_set (which, value); +switch (which) {case ITIMER_REAL : again:Index:
linux-2.6-lttng/kernel/timer.c
===================================================================kernel/timer.c +3
-0@@ -37,12 +37,14 @@#include <linux/delay.h> #include <linux/tick.h> #include <linux/kallsyms.h> +#include <trace/timer.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/div64.h> #include <asm/timex.h> #include <asm/io.h> +#include <asm/irq_regs.h> u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;@@ -288,6 +290,7 @@ static void internal_add_timer(struct tv i = (expires >> (TVR_BITS +3 *TVN_BITS )) &TVN_MASK ; vec = base->tv5.vec + i; } +trace_timer_set (timer);/* * Timers are FIFO: */
kernel/timer.c void do_timer(unsigned long ticks) · line 1073
Quoted 5 lines
kernel/timer.c +1
-0@@ -1066,6 +1069,7 @@ void do_timer(unsigned long ticks) { jiffies_64 += ticks;update_times (ticks); +trace_timer_update_time (&xtime, &wall_to_monotonic); }
This is a very dangerous trace point - we're holding xtime lock here.
Ah, I see you make that comment below too, are you sure you want to do this?
Thomas, any input?
Quoted 42 lines
kernel/timer.c +3
-1#ifdef __ARCH_WANT_SYS_ALARM@@ -1147,7 +1151,9 @@ asmlinkage long sys_getegid(void)static void process_timeout (unsigned long __data) { -wake_up_process ((struct task_struct *)__data); +struct task_struct *task = (struct task_struct *)__data; +trace_timer_timeout (task); +wake_up_process (task); }/** Index:
linux-2.6-lttng/include/trace/timer.h
===================================================================include/trace/timer.h new file +24
-0@@ -0,0 +1,24 @@ +#ifndef _TRACE_TIMER_H +#define _TRACE_TIMER_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (timer_itimer_expired, + TPPROTO(struct signal_struct *sig), +TPARGS (sig)); +DEFINE_TRACE (timer_itimer_set, + TPPROTO(int which, struct itimerval *value), +TPARGS (which, value)); +DEFINE_TRACE (timer_set, + TPPROTO(struct timer_list *timer), +TPARGS (timer)); +/* +* xtime_lock is taken when kernel_timer_update_time tracepoint is reached. +*/ +DEFINE_TRACE (timer_update_time, + TPPROTO(struct timespec *_xtime, struct timespec *_wall_to_monotonic), +TPARGS (_xtime, _wall_to_monotonic)); +DEFINE_TRACE (timer_timeout, + TPPROTO(struct task_struct *p), +TPARGS (p)); +#endif
Re: [patch 07/17] LTTng instrumentation - timer
Quoted 97 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 88 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-timer.patch) Instrument timer activity (timer set, expired, current time updates) to keep information about the "real time" flow within the kernel. It can be used by a trace analysis tool to synchronize information coming from various sources, e.g. to merge traces with system logs.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC 'Ingo Molnar' <[email protected]>CC "David S. Miller" <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/timer.h | 24 ++++++++++++++++++++++++ kernel/itimer.c | 5 +++++ kernel/timer.c | 8 +++++++- 3 files changed, 36 insertions(+), 1 deletion(-)Index:
linux-2.6-lttng/kernel/itimer.c
===================================================================kernel/itimer.c +5
-0@@ -12,6 +12,7 @@#include <linux/time.h> #include <linux/posix-timers.h> #include <linux/hrtimer.h> +#include <trace/timer.h> #include <asm/uaccess.h> @@ -132,6 +133,8 @@ enum hrtimer_restart it_real_fn(struct hstruct signal_struct *sig = container_of(timer, struct signal_struct, real_timer); +trace_timer_itimer_expired (sig); +kill_pid_info (SIGALRM ,SEND_SIG_PRIV , sig->leader_pid);return HRTIMER_NORESTART ;@@ -157,6 +160,8 @@ int do_setitimer(int which, struct itime !timeval_valid(&value->it_interval))return -EINVAL ; +trace_timer_itimer_set (which, value); +switch (which) {case ITIMER_REAL : again:Index:
linux-2.6-lttng/kernel/timer.c
===================================================================kernel/timer.c +3
-0@@ -37,12 +37,14 @@#include <linux/delay.h> #include <linux/tick.h> #include <linux/kallsyms.h> +#include <trace/timer.h> #include <asm/uaccess.h> #include <asm/unistd.h> #include <asm/div64.h> #include <asm/timex.h> #include <asm/io.h> +#include <asm/irq_regs.h> u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;@@ -288,6 +290,7 @@ static void internal_add_timer(struct tv i = (expires >> (TVR_BITS +3 *TVN_BITS )) &TVN_MASK ; vec = base->tv5.vec + i; } +trace_timer_set (timer);/* * Timers are FIFO: */ kernel/timer.c void do_timer(unsigned long ticks) · line 1073
Quoted 5 lines
kernel/timer.c +1
-0@@ -1066,6 +1069,7 @@ void do_timer(unsigned long ticks) { jiffies_64 += ticks;update_times (ticks); +trace_timer_update_time (&xtime, &wall_to_monotonic); }This is a very dangerous trace point - we're holding xtime lock here.
Quoted 3 lines
Ah, I see you make that comment below too, are you sure you want to do this?
Yes, this is done on purpose : I want to know the link between evolution of the "system time" and my more precise time source (habitually the TSC), so I can know how to interleave events between system logs and low-level traces.
However it involves that a tracer connected to this tracepoint cannot take the xtime lock (or must be aware that it is already taken). Since LTTng has been designed to support NMIs, and because seqlocks and NMIs does not mix well together (cause deadlocks), I have no such concern. I created my own RCU-based 32-to-64 bits counter extension infrastructure for that precise purpose (so I could support architectures which provide hardware counters with fewer than 64 bits).
You'll notice that as tracepoints are added, one must be more and more careful about what locks it takes or what parts of kernel infrastructure it uses in its tracer. But nobody said tracing was easy. ;-)
Mathieu
Quoted 45 lines
Thomas, any input?
Quoted 42 lines
kernel/timer.c +3
-1#ifdef __ARCH_WANT_SYS_ALARM@@ -1147,7 +1151,9 @@ asmlinkage long sys_getegid(void)static void process_timeout (unsigned long __data) { -wake_up_process ((struct task_struct *)__data); +struct task_struct *task = (struct task_struct *)__data; +trace_timer_timeout (task); +wake_up_process (task); }/** Index:
linux-2.6-lttng/include/trace/timer.h
===================================================================include/trace/timer.h new file +24
-0@@ -0,0 +1,24 @@ +#ifndef _TRACE_TIMER_H +#define _TRACE_TIMER_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (timer_itimer_expired, + TPPROTO(struct signal_struct *sig), +TPARGS (sig)); +DEFINE_TRACE (timer_itimer_set, + TPPROTO(int which, struct itimerval *value), +TPARGS (which, value)); +DEFINE_TRACE (timer_set, + TPPROTO(struct timer_list *timer), +TPARGS (timer)); +/* +* xtime_lock is taken when kernel_timer_update_time tracepoint is reached. +*/ +DEFINE_TRACE (timer_update_time, + TPPROTO(struct timespec *_xtime, struct timespec *_wall_to_monotonic), +TPARGS (_xtime, _wall_to_monotonic)); +DEFINE_TRACE (timer_timeout, + TPPROTO(struct task_struct *p), +TPARGS (p)); +#endif
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 8/17 LTTng instrumentation - kernel
In reply to Mathieu DesnoyersInstrument the core kernel : module load/free and printk events. It helps the tracer to keep track of module related events and to export valuable printk information into the traces.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/kernel.h | 19 +++++++++++++++++++ kernel/module.c | 5 +++++ kernel/printk.c | 6 ++++++ 3 files changed, 30 insertions(+)
kernel/printk.c +6 -0
@@ -32,6 +32,7 @@#include <linux/security.h> #include <linux/bootmem.h> #include <linux/syscalls.h> +#include <trace/kernel.h> #include <asm/uaccess.h>
@@ -59,6 +60,7 @@ int console_printk[4] = {MINIMUM_CONSOLE_LOGLEVEL ,/* minimum_console_loglevel */ DEFAULT_CONSOLE_LOGLEVEL ,/* default_console_loglevel */ }; +EXPORT_SYMBOL_GPL (console_printk);/* * Low level drivers may need that to know if they can schedule in
@@ -601,6 +603,7 @@ asmlinkage int printk(const char *fmt, .int r;va_start (args, fmt); +trace_kernel_printk (__builtin_return_address (0 )); r =vprintk (fmt, args);va_end (args);
@@ -677,6 +680,9 @@ asmlinkage int vprintk(const char *fmt,raw_local_irq_save (flags); this_cpu =smp_processor_id (); +trace_kernel_vprintk (__builtin_return_address (0 ), + printk_buf, printed_len); +/* * Ouch, printk recursed into itself! */
kernel/module.c +5 -0
@@ -48,6 +48,7 @@#include <linux/license.h> #include <asm/sections.h> #include <linux/tracepoint.h> +#include <trace/kernel.h> #if 0 #define DEBUGP printk
@@ -1429,6 +1430,8 @@ static int __unlink_module(void *_mod)/* Free a module, remove from lists, etc (must hold module_mutex). */ static void free_module (struct module *mod) { +trace_kernel_module_free (mod); +/* Delete from various lists */ stop_machine (__unlink_module, mod,NULL );remove_notes_attrs (mod);
@@ -2244,6 +2247,8 @@ static struct module *load_module(void _/* Get rid of temporary copy */ vfree (hdr); +trace_kernel_module_load (mod); +/* Done! */ return mod;
include/trace/kernel.h new file +19 -0
@@ -0,0 +1,19 @@ +#ifndef _TRACE_KERNEL_H +#define _TRACE_KERNEL_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (kernel_printk, +TPPROTO (void *retaddr), +TPARGS (retaddr)); +DEFINE_TRACE (kernel_vprintk, + TPPROTO(void *retaddr, char *buf, int len), +TPARGS (retaddr, buf, len)); +DEFINE_TRACE (kernel_module_free, + TPPROTO(struct module *mod), +TPARGS (mod)); +DEFINE_TRACE (kernel_module_load, + TPPROTO(struct module *mod), +TPARGS (mod)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Steven Rostedt
maintainerRe: [patch 08/17] LTTng instrumentation - kernel
kernel/printk.c asmlinkage int printk(const char *fmt, . · line 606
Quoted 8 lines · Mathieu Desnoyers
/*
* Low level drivers may need that to know if they can schedule inkernel/printk.c +1
-0@@ -601,6 +603,7 @@ asmlinkage int printk(const char *fmt, .int r;va_start (args, fmt); +trace_kernel_printk (__builtin_return_address (0 ));
BTW, ftrace.h has macros that let you use CALLER_ADDR0 for __builtin_return_address. It also converts it from a pointer to a long, but makes the code look prettier.
kernel/printk.c asmlinkage int vprintk(const char *fmt, · line 688
Quoted 13 lines
kernel/printk.c +3
-0r =vprintk (fmt, args);va_end (args);@@ -677,6 +680,9 @@ asmlinkage int vprintk(const char *fmt,raw_local_irq_save (flags); this_cpu =smp_processor_id (); +trace_kernel_vprintk (__builtin_return_address (0 ), + printk_buf, printed_len); +/* * Ouch, printk recursed into itself! */
-- Steve
Re: [patch 08/17] LTTng instrumentation - kernel
Quoted 9 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 6 lines · Mathieu Desnoyers
/*
* Low level drivers may need that to know if they can schedule in(quoted diff) +0
-0@@ -601,6 +603,7 @@ asmlinkage int printk(const char *fmt, . int r;
Quoted 7 lines
kernel/printk.c asmlinkage int printk(const char *fmt, . · line 606
Quoted 2 lines
kernel/printk.c +1
-0va_start (args, fmt); +trace_kernel_printk (__builtin_return_address (0 ));BTW,
ftrace.hhas macros that let you useCALLER_ADDR0for__builtin_return_address. It also converts it from a pointer to a long, but makes the code look prettier.
include/linux/kernel.h:#define _RET_IP_ (unsigned long)__builtin_return_address(0)
Hrm, did not see this one. So I guess we can both switch to it ?
Thanks for pointing this out,
Mathieu
Quoted 17 lines
Quoted 5 lines
kernel/printk.c +0
-0r =vprintk (fmt, args);va_end (args);kernel/printk.c asmlinkage int vprintk(const char *fmt, · line 688
Quoted 9 lines
kernel/printk.c +3
-0@@ -677,6 +680,9 @@ asmlinkage int vprintk(const char *fmt,raw_local_irq_save (flags); this_cpu =smp_processor_id (); +trace_kernel_vprintk (__builtin_return_address (0 ), + printk_buf, printed_len); +/* * Ouch, printk recursed into itself! */ -- Steve
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Steven Rostedt
maintainerRe: [patch 08/17] LTTng instrumentation - kernel
Quoted 19 lines · Mathieu Desnoyers
Quoted 9 lines · * Steven Rostedt ([email protected]) wrote:
Quoted 6 lines · Mathieu Desnoyers
/*
* Low level drivers may need that to know if they can schedule in(quoted diff) +0
-0@@ -601,6 +603,7 @@ asmlinkage int printk(const char *fmt, . int r;Quoted 7 lines
kernel/printk.c asmlinkage int printk(const char *fmt, . · line 606
Quoted 2 lines
kernel/printk.c +1
-0va_start (args, fmt); +trace_kernel_printk (__builtin_return_address (0 ));BTW,
ftrace.hhas macros that let you useCALLER_ADDR0for__builtin_return_address. It also converts it from a pointer to a long, but makes the code look prettier.
Quoted 3 lines
include/linux/kernel.h:#define _RET_IP_ (unsigned long)__builtin_return_address(0)
Hrm, did not see this one. So I guess we can both switch to it ?
Hmm, yeah, I forgot about that. Someplaces I do use CALLER_ADDR1 and higher, but when it is just CALLER_ADDR0, then _RET_IP_ would probably be better.
Quoted 2 lines
Thanks for pointing this out,
-- Steve
PATCH 9/17 LTTng instrumentation - filemap
In reply to Mathieu DesnoyersInstrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/filemap.h | 13 +++++++++++++ mm/filemap.c | 3 +++ 2 files changed, 16 insertions(+)
mm/filemap.c +3 -0
@@ -33,6 +33,7 @@#include <linux/cpuset.h> #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ #include <linux/memcontrol.h> +#include <trace/filemap.h> #include "internal.h" /*
@@ -541,9 +542,11 @@ void wait_on_page_bit(struct page *page, {DEFINE_WAIT_BIT (wait, &page->flags, bit_nr); +trace_filemap_wait_start (page, bit_nr);if (test_bit (bit_nr, &page->flags))__wait_on_bit (page_waitqueue (page), &wait, sync_page,TASK_UNINTERRUPTIBLE ); +trace_filemap_wait_end (page, bit_nr); }EXPORT_SYMBOL (wait_on_page_bit);
include/trace/filemap.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _TRACE_FILEMAP_H +#define _TRACE_FILEMAP_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (filemap_wait_start, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); +DEFINE_TRACE (filemap_wait_end, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); + +#endif
Signature · 9 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Peter Zijlstra
maintainerRe: [patch 09/17] LTTng instrumentation - filemap
Quoted 40 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-filemap.patch) Instrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Dave Hansen <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/filemap.h | 13 +++++++++++++ mm/filemap.c | 3 +++ 2 files changed, 16 insertions(+)Index:
linux-2.6-lttng/mm/filemap.c
===================================================================mm/filemap.c +1
-0@@ -33,6 +33,7 @@#include <linux/cpuset.h> #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ #include <linux/memcontrol.h> +#include <trace/filemap.h> #include "internal.h" /*
mm/filemap.c void wait_on_page_bit(struct page *page, · line 551
Quoted 10 lines
mm/filemap.c +2
-0@@ -541,9 +542,11 @@ void wait_on_page_bit(struct page *page, {DEFINE_WAIT_BIT (wait, &page->flags, bit_nr); +trace_filemap_wait_start (page, bit_nr);if (test_bit (bit_nr, &page->flags))__wait_on_bit (page_waitqueue (page), &wait, sync_page,TASK_UNINTERRUPTIBLE ); +trace_filemap_wait_end (page, bit_nr); }EXPORT_SYMBOL (wait_on_page_bit);
I don't like the trace_filemap_wait_* naming..
trace_wait_on_page_* might make more sense
Quoted 19 lines
Index:
linux-2.6-lttng/include/trace/filemap.h
===================================================================include/trace/filemap.h new file +13
-0@@ -0,0 +1,13 @@ +#ifndef _TRACE_FILEMAP_H +#define _TRACE_FILEMAP_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (filemap_wait_start, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); +DEFINE_TRACE (filemap_wait_end, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); + +#endif
Re: [patch 09/17] LTTng instrumentation - filemap
Quoted 44 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 43 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-filemap.patch) Instrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Dave Hansen <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/filemap.h | 13 +++++++++++++ mm/filemap.c | 3 +++ 2 files changed, 16 insertions(+)Index:
linux-2.6-lttng/mm/filemap.c
===================================================================mm/filemap.c +1
-0@@ -33,6 +33,7 @@#include <linux/cpuset.h> #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */ #include <linux/memcontrol.h> +#include <trace/filemap.h> #include "internal.h" /* @@ -541,9 +542,11 @@ void wait_on_page_bit(struct page *page, {DEFINE_WAIT_BIT (wait, &page->flags, bit_nr);
Quoted 10 lines
mm/filemap.c void wait_on_page_bit(struct page *page, · line 551
Quoted 7 lines
mm/filemap.c +2
-0+trace_filemap_wait_start (page, bit_nr);if (test_bit (bit_nr, &page->flags))__wait_on_bit (page_waitqueue (page), &wait, sync_page,TASK_UNINTERRUPTIBLE ); +trace_filemap_wait_end (page, bit_nr); }EXPORT_SYMBOL (wait_on_page_bit);I don't like the trace_filemap_wait_* naming..
Me neither :)
Quoted 2 lines
trace_wait_on_page_* might make more sense
Yep, agreed,
Mathieu
Quoted 20 lines
Quoted 19 lines
Index:
linux-2.6-lttng/include/trace/filemap.h
===================================================================include/trace/filemap.h new file +13
-0@@ -0,0 +1,13 @@ +#ifndef _TRACE_FILEMAP_H +#define _TRACE_FILEMAP_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (filemap_wait_start, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); +DEFINE_TRACE (filemap_wait_end, + TPPROTO(struct page *page, int bit_nr), +TPARGS (page, bit_nr)); + +#endif
Signature · 8 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 09/17] LTTng instrumentation - filemap
In reply to Mathieu DesnoyersQuoted 10 lines · Mathieu Desnoyers
Instrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
BTW. this sort of test is practically useless to measure overhead. If a modern CPU is executing out of primed insn/data and branch prediction cache, then yes this sort of thing is pretty well free.
I see *real* workloads that have got continually and incrementally slower eg from 2.6.5 to 2.6.20+ as "features" get added. Surprisingly, none of them ever showed up individually on a microbenchmark.
OK, for this case if you can configure it out, I guess that's fine. But let's not pretend that adding code and branches and function calls are ever free.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 09/17] LTTng instrumentation - filemap
Quoted 16 lines · * Nick Piggin ([email protected]) wrote:
Quoted 10 lines · Mathieu Desnoyers
Instrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
BTW. this sort of test is practically useless to measure overhead. If a modern CPU is executing out of primed insn/data and branch prediction cache, then yes this sort of thing is pretty well free.
Quoted 7 lines
I see *real* workloads that have got continually and incrementally slower eg from 2.6.5 to 2.6.20+ as "features" get added. Surprisingly, none of them ever showed up individually on a microbenchmark.
OK, for this case if you can configure it out, I guess that's fine. But let's not pretend that adding code and branches and function calls are ever free.
I never pretended anything like that. Actually, that's what the "immediate values" are for : they allow to patch load immediate value instead of a memory read to decrease d-cache impact. They now allow to patch a jump instead of the memory read/immediate value read + test + conditional branch to skip the function call with fairly minimal impact. I agree with you that eating precious d-cache and jump prediction buffer entries can eventually slow down the system. But this will be _hard_ to show on a single macro benchmark, and the microbenchmark showing it will have to be taken in conditions which will exacerbate the d-cache and BPB impact.
Mathieu
Signature · 8 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 09/17] LTTng instrumentation - filemap
Quoted 21 lines · Mathieu Desnoyers
Quoted 20 lines · * Nick Piggin ([email protected]) wrote:
Quoted 10 lines · Mathieu Desnoyers
Instrumentation of waits caused by memory accesses on mmap regions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
BTW. this sort of test is practically useless to measure overhead. If a modern CPU is executing out of primed insn/data and branch prediction cache, then yes this sort of thing is pretty well free.
I see *real* workloads that have got continually and incrementally slower eg from 2.6.5 to 2.6.20+ as "features" get added. Surprisingly, none of them ever showed up individually on a microbenchmark.
Quoted 5 lines
Quoted 3 lines
OK, for this case if you can configure it out, I guess that's fine. But let's not pretend that adding code and branches and function calls are ever free.
I never pretended anything like that. Actually, that's what the
OK but saying "there is no detectable impact when running hackbench" is basically meaningless.
Quoted 9 lines
"immediate values" are for : they allow to patch load immediate value instead of a memory read to decrease d-cache impact. They now allow to patch a jump instead of the memory read/immediate value read + test + conditional branch to skip the function call with fairly minimal impact. I agree with you that eating precious d-cache and jump prediction buffer entries can eventually slow down the system. But this will be _hard_ to show on a single macro benchmark, and the microbenchmark showing it will have to be taken in conditions which will exacerbate the d-cache and BPB impact.
I'm not saying you have to reproduce it (although Intel's Oracle OLTP benchmark is very sensitive to that kind of thing and schedule() is near the top). But just acknowledge that it adds some cost. OK you're one of the few people really trying hard to count every cycle so I don't mean to pick on this code in particular.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 10/17 LTTng instrumentation - swap
In reply to Mathieu DesnoyersInstrumentation of waits caused by swap activity. Also instrumentation swapon/swapoff events to keep track of active swap partitions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/swap.h | 20 ++++++++++++++++++++ mm/memory.c | 2 ++ mm/page_io.c | 2 ++ mm/swapfile.c | 4 ++++ 4 files changed, 28 insertions(+)
mm/memory.c +2 -0
@@ -51,6 +51,7 @@#include <linux/init.h> #include <linux/writeback.h> #include <linux/memcontrol.h> +#include <trace/swap.h> #include <asm/pgalloc.h> #include <asm/uaccess.h>
@@ -2213,6 +2214,7 @@ static int do_swap_page(struct mm_struct/* Had to read the page from swap area: Major fault */ ret =VM_FAULT_MAJOR ;count_vm_event (PGMAJFAULT ); +trace_swap_in (page, entry); }if (mem_cgroup_charge (page, mm,GFP_KERNEL )) {
mm/page_io.c +2 -0
@@ -17,6 +17,7 @@#include <linux/bio.h> #include <linux/swapops.h> #include <linux/writeback.h> +#include <trace/swap.h> #include <asm/pgtable.h> static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,
@@ -114,6 +115,7 @@ int swap_writepage(struct page *page, st rw |= (1 <<BIO_RW_SYNC );count_vm_event (PSWPOUT );set_page_writeback (page); +trace_swap_out (page);unlock_page (page);submit_bio (rw, bio); out:
mm/swapfile.c +4 -0
@@ -32,6 +32,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <linux/swapops.h> +#include <trace/swap.h> DEFINE_SPINLOCK (swap_lock);unsigned int nr_swapfiles;
@@ -1310,6 +1311,7 @@ asmlinkage long sys_swapoff(const char _ swap_map = p->swap_map; p->swap_map =NULL ; p->flags =0 ; +trace_swap_file_close (swap_file);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex);vfree (swap_map);
@@ -1695,6 +1697,7 @@ asmlinkage long sys_swapon(const char __ }else { swap_info[prev].next = p - swap_info; } +trace_swap_file_open (swap_file, name);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex); error =0 ;
@@ -1796,6 +1799,7 @@ get_swap_info_struct(unsigned type) {return &swap_info[type]; } +EXPORT_SYMBOL_GPL (get_swap_info_struct);/* * swap_lock prevents swap_map being freed. Don't grab an extra
include/trace/swap.h new file +20 -0
@@ -0,0 +1,20 @@ +#ifndef _TRACE_SWAP_H +#define _TRACE_SWAP_H + +#include <linux/swap.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (swap_in, + TPPROTO(struct page *page, swp_entry_t entry), +TPARGS (page, entry)); +DEFINE_TRACE (swap_out, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (swap_file_open, + TPPROTO(struct file *file, char *filename), +TPARGS (file, filename)); +DEFINE_TRACE (swap_file_close, + TPPROTO(struct file *file), +TPARGS (file)); + +#endif
Signature · 9 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Peter Zijlstra
maintainerRe: [patch 10/17] LTTng instrumentation - swap
Quoted 99 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-swap.patch) Instrumentation of waits caused by swap activity. Also instrumentation swapon/swapoff events to keep track of active swap partitions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Dave Hansen <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/swap.h | 20 ++++++++++++++++++++ mm/memory.c | 2 ++ mm/page_io.c | 2 ++ mm/swapfile.c | 4 ++++ 4 files changed, 28 insertions(+)Index:
linux-2.6-lttng/mm/memory.c
===================================================================mm/memory.c +2
-0@@ -51,6 +51,7 @@#include <linux/init.h> #include <linux/writeback.h> #include <linux/memcontrol.h> +#include <trace/swap.h> #include <asm/pgalloc.h> #include <asm/uaccess.h> @@ -2213,6 +2214,7 @@ static int do_swap_page(struct mm_struct/* Had to read the page from swap area: Major fault */ ret =VM_FAULT_MAJOR ;count_vm_event (PGMAJFAULT ); +trace_swap_in (page, entry); }if (mem_cgroup_charge (page, mm,GFP_KERNEL )) {Index:
linux-2.6-lttng/mm/page_io.c
===================================================================mm/page_io.c +2
-0@@ -17,6 +17,7 @@#include <linux/bio.h> #include <linux/swapops.h> #include <linux/writeback.h> +#include <trace/swap.h> #include <asm/pgtable.h> static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,@@ -114,6 +115,7 @@ int swap_writepage(struct page *page, st rw |= (1 <<BIO_RW_SYNC );count_vm_event (PSWPOUT );set_page_writeback (page); +trace_swap_out (page);unlock_page (page);submit_bio (rw, bio); out:Index:
linux-2.6-lttng/mm/swapfile.c
===================================================================mm/swapfile.c +3
-0@@ -32,6 +32,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <linux/swapops.h> +#include <trace/swap.h> DEFINE_SPINLOCK (swap_lock);unsigned int nr_swapfiles;@@ -1310,6 +1311,7 @@ asmlinkage long sys_swapoff(const char _ swap_map = p->swap_map; p->swap_map =NULL ; p->flags =0 ; +trace_swap_file_close (swap_file);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex);vfree (swap_map);@@ -1695,6 +1697,7 @@ asmlinkage long sys_swapon(const char __ }else { swap_info[prev].next = p - swap_info; } +trace_swap_file_open (swap_file, name);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex); error =0 ;
mm/swapfile.c get_swap_info_struct(unsigned type) · line 1802
Quoted 4 lines
mm/swapfile.c +1
-0@@ -1796,6 +1799,7 @@ get_swap_info_struct(unsigned type) {return &swap_info[type]; } +EXPORT_SYMBOL_GPL (get_swap_info_struct);
I'm not too happy with this export.
Quoted 19 lines
mm/swapfile.c +0
-0/* * swap_lock prevents swap_map being freed. Don't grab an extra Index:
linux-2.6-lttng/include/trace/swap.h
===================================================================include/trace/swap.h new file +10
-0@@ -0,0 +1,20 @@ +#ifndef _TRACE_SWAP_H +#define _TRACE_SWAP_H + +#include <linux/swap.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (swap_in, + TPPROTO(struct page *page, swp_entry_t entry), +TPARGS (page, entry)); +DEFINE_TRACE(swap_out,
include/trace/swap.h line 20
Quoted 10 lines
include/trace/swap.h new file +10
-0+ TPPROTO(struct page *page), + TPARGS(page)); +DEFINE_TRACE (swap_file_open, + TPPROTO(struct file *file, char *filename), +TPARGS (file, filename)); +DEFINE_TRACE (swap_file_close, + TPPROTO(struct file *file), +TPARGS (file)); + +#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 10/17] LTTng instrumentation - swap
Quoted 98 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 97 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-swap.patch) Instrumentation of waits caused by swap activity. Also instrumentation swapon/swapoff events to keep track of active swap partitions.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Dave Hansen <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/swap.h | 20 ++++++++++++++++++++ mm/memory.c | 2 ++ mm/page_io.c | 2 ++ mm/swapfile.c | 4 ++++ 4 files changed, 28 insertions(+)Index:
linux-2.6-lttng/mm/memory.c
===================================================================mm/memory.c +2
-0@@ -51,6 +51,7 @@#include <linux/init.h> #include <linux/writeback.h> #include <linux/memcontrol.h> +#include <trace/swap.h> #include <asm/pgalloc.h> #include <asm/uaccess.h> @@ -2213,6 +2214,7 @@ static int do_swap_page(struct mm_struct/* Had to read the page from swap area: Major fault */ ret =VM_FAULT_MAJOR ;count_vm_event (PGMAJFAULT ); +trace_swap_in (page, entry); }if (mem_cgroup_charge (page, mm,GFP_KERNEL )) {Index:
linux-2.6-lttng/mm/page_io.c
===================================================================mm/page_io.c +2
-0@@ -17,6 +17,7 @@#include <linux/bio.h> #include <linux/swapops.h> #include <linux/writeback.h> +#include <trace/swap.h> #include <asm/pgtable.h> static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,@@ -114,6 +115,7 @@ int swap_writepage(struct page *page, st rw |= (1 <<BIO_RW_SYNC );count_vm_event (PSWPOUT );set_page_writeback (page); +trace_swap_out (page);unlock_page (page);submit_bio (rw, bio); out:Index:
linux-2.6-lttng/mm/swapfile.c
===================================================================mm/swapfile.c +3
-0@@ -32,6 +32,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <linux/swapops.h> +#include <trace/swap.h> DEFINE_SPINLOCK (swap_lock);unsigned int nr_swapfiles;@@ -1310,6 +1311,7 @@ asmlinkage long sys_swapoff(const char _ swap_map = p->swap_map; p->swap_map =NULL ; p->flags =0 ; +trace_swap_file_close (swap_file);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex);vfree (swap_map);@@ -1695,6 +1697,7 @@ asmlinkage long sys_swapon(const char __ }else { swap_info[prev].next = p - swap_info; } +trace_swap_file_open (swap_file, name);spin_unlock (&swap_lock);mutex_unlock (&swapon_mutex);
Quoted 9 lines
mm/swapfile.c get_swap_info_struct(unsigned type) · line 1802
Quoted 6 lines
mm/swapfile.c +1
-0error =0 ;@@ -1796,6 +1799,7 @@ get_swap_info_struct(unsigned type) {return &swap_info[type]; } +EXPORT_SYMBOL_GPL (get_swap_info_struct);I'm not too happy with this export.
Would it make more sense to turn get_swap_info_struct into a static inline in swap.h ?
Mathieu
Quoted 30 lines
Quoted 29 lines
mm/swapfile.c +0
-0/* * swap_lock prevents swap_map being freed. Don't grab an extra Index:
linux-2.6-lttng/include/trace/swap.h
===================================================================include/trace/swap.h new file +20
-0@@ -0,0 +1,20 @@ +#ifndef _TRACE_SWAP_H +#define _TRACE_SWAP_H + +#include <linux/swap.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (swap_in, + TPPROTO(struct page *page, swp_entry_t entry), +TPARGS (page, entry)); +DEFINE_TRACE (swap_out, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (swap_file_open, + TPPROTO(struct file *file, char *filename), +TPARGS (file, filename)); +DEFINE_TRACE (swap_file_close, + TPPROTO(struct file *file), +TPARGS (file)); + +#endif
Signature · 8 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Peter Zijlstra
maintainerRe: [patch 10/17] LTTng instrumentation - swap
Quoted 12 lines · Mathieu Desnoyers
Quoted 10 lines · * Peter Zijlstra ([email protected]) wrote:
mm/swapfile.c get_swap_info_struct(unsigned type) · line 1802
Quoted 5 lines · Mathieu Desnoyers
mm/swapfile.c +1
-0@@ -1796,6 +1799,7 @@ get_swap_info_struct(unsigned type) {return &swap_info[type]; } +EXPORT_SYMBOL_GPL (get_swap_info_struct);I'm not too happy with this export.
Quoted 2 lines
Would it make more sense to turn
get_swap_info_structinto a static inline inswap.h?
Seeing a consumer of it would go a long way towards discussing it ;-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 10/17] LTTng instrumentation - swap
Quoted 13 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 12 lines · Mathieu Desnoyers
Quoted 10 lines · * Peter Zijlstra ([email protected]) wrote:
mm/swapfile.c get_swap_info_struct(unsigned type) · line 1802
Quoted 5 lines · Mathieu Desnoyers
mm/swapfile.c +1
-0@@ -1796,6 +1799,7 @@ get_swap_info_struct(unsigned type) {return &swap_info[type]; } +EXPORT_SYMBOL_GPL (get_swap_info_struct);I'm not too happy with this export.
Quoted 5 lines
Quoted 2 lines
Would it make more sense to turn
get_swap_info_structinto a static inline inswap.h?Seeing a consumer of it would go a long way towards discussing it ;-)
The LTTng probe which connects to this tracepoint looks like :
+static void probe_swap_out(struct page *page)
+{
+ trace_mark(mm_swap_out, "pfn %lu filp %p offset %lu",
+ page_to_pfn(page),
+ get_swap_info_struct(swp_type(
+ page_swp_entry(page)))->swap_file,
+ swp_offset(page_swp_entry(page)));
+}
So, I need get_swap_info_struct to extract the swap file pointer from the swap entry.
Mathieu
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Re: [patch 10/17] LTTng instrumentation - swap
Hi
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Would it make more sense to turn
get_swap_info_structinto a static inline inswap.h?Seeing a consumer of it would go a long way towards discussing it ;-)
The LTTng probe which connects to this tracepoint looks like :
I have no objection to this exporting.
However, This is LTTng requirement.
but tracepoint is tracer independent mechanism.
then, split out is better IMHO.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 10/17] LTTng instrumentation - swap
Quoted 7 lines · * KOSAKI Motohiro ([email protected]) wrote:
Hi
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
Would it make more sense to turn
get_swap_info_structinto a static inline inswap.h?Seeing a consumer of it would go a long way towards discussing it ;-)
Quoted 8 lines
Quoted 1 line
The LTTng probe which connects to this tracepoint looks like :
I have no objection to this exporting.
However, This is LTTng requirement.
but tracepoint is tracer independent mechanism.
then, split out is better IMHO.
Good point. I'll move it to my following lttng-specific patches.
Mathieu
Signature · 8 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 11/17 LTTng instrumentation - memory page faults
In reply to Mathieu DesnoyersInstrument the page fault entry and exit. Useful to detect delays caused by page faults and bad memory usage patterns.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/memory.h | 14 ++++++++++++++ mm/memory.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 9 deletions(-)
mm/memory.c +24 -9
@@ -61,6 +61,7 @@#include <linux/swapops.h> #include <linux/elf.h> +#include <trace/memory.h> #ifndef CONFIG_NEED_MULTIPLE_NODES /* use the per-pgdat data instead for discontigmem - mbligh */
@@ -2664,30 +2665,44 @@ unlock:int handle_mm_fault (struct mm_struct *mm,struct vm_area_struct *vma,unsigned long address,int write_access) { +int res;pgd_t *pgd;pud_t *pud;pmd_t *pmd;pte_t *pte; +trace_memory_handle_fault_entry (mm, vma, address, write_access); +__set_current_state (TASK_RUNNING );count_vm_event (PGFAULT ); -if (unlikely (is_vm_hugetlb_page (vma))) -return hugetlb_fault (mm, vma, address, write_access); +if (unlikely (is_vm_hugetlb_page (vma))) { + res =hugetlb_fault (mm, vma, address, write_access); + goto end; + } pgd =pgd_offset (mm, address); pud =pud_alloc (mm, pgd, address); -if (!pud) -return VM_FAULT_OOM ; +if (!pud) { + res =VM_FAULT_OOM ; + goto end; + } pmd =pmd_alloc (mm, pud, address); -if (!pmd) -return VM_FAULT_OOM ; +if (!pmd) { + res =VM_FAULT_OOM ; + goto end; + } pte =pte_alloc_map (mm, pmd, address); -if (!pte) -return VM_FAULT_OOM ; +if (!pte) { + res =VM_FAULT_OOM ; + goto end; + } -return handle_pte_fault (mm, vma, address, pte, pmd, write_access); + res =handle_pte_fault (mm, vma, address, pte, pmd, write_access); +end: +trace_memory_handle_fault_exit (res); +return res; }#ifndef __PAGETABLE_PUD_FOLDED
include/trace/memory.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _TRACE_MEMORY_H +#define _TRACE_MEMORY_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (memory_handle_fault_entry, + TPPROTO(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, int write_access), +TPARGS (mm, vma, address, write_access)); +DEFINE_TRACE (memory_handle_fault_exit, + TPPROTO(int res), +TPARGS (res)); + +#endif
Signature · 9 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 12/17 LTTng instrumentation - page
In reply to Mathieu DesnoyersPaging activity instrumentation. Instruments page allocation/free to keep track of page allocation. This does not cover hugetlb activity, which is covered by a separate patch.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/page.h | 16 ++++++++++++++++ mm/page_alloc.c | 6 ++++++ 2 files changed, 22 insertions(+)
mm/page_alloc.c +6 -0
@@ -46,6 +46,7 @@#include <linux/page-isolation.h> #include <linux/memcontrol.h> #include <linux/debugobjects.h> +#include <trace/page.h> #include <asm/tlbflush.h> #include <asm/div64.h>
@@ -510,6 +511,8 @@ static void __free_pages_ok(struct pageint i;int reserved =0 ; +trace_page_free (page, order); +for (i =0 ; i < (1 << order) ; ++i) reserved +=free_pages_check (page + i);if (reserved)
@@ -966,6 +969,8 @@ static void free_hot_cold_page(struct pastruct per_cpu_pages *pcp;unsigned long flags; +trace_page_free (page,0 ); +if (PageAnon (page)) page->mapping =NULL ;if (free_pages_check (page))
@@ -1630,6 +1635,7 @@ nopage:show_mem (); } got_pg: +trace_page_alloc (page, order);return page; }
include/trace/page.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef _TRACE_PAGE_H +#define _TRACE_PAGE_H + +#include <linux/tracepoint.h> + +/* +* mm_page_alloc : page can be NULL. +*/ +DEFINE_TRACE (page_alloc, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); +DEFINE_TRACE (page_free, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Peter Zijlstra
maintainerRe: [patch 12/17] LTTng instrumentation - page
include/trace/page.h
Quoted 70 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-page.patch) Paging activity instrumentation. Instruments page allocation/free to keep track of page allocation. This does not cover hugetlb activity, which is covered by a separate patch.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Martin Bligh <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/page.h | 16 ++++++++++++++++ mm/page_alloc.c | 6 ++++++ 2 files changed, 22 insertions(+)Index:
linux-2.6-lttng/mm/page_alloc.c
===================================================================mm/page_alloc.c +6
-0@@ -46,6 +46,7 @@#include <linux/page-isolation.h> #include <linux/memcontrol.h> #include <linux/debugobjects.h> +#include <trace/page.h> #include <asm/tlbflush.h> #include <asm/div64.h> @@ -510,6 +511,8 @@ static void __free_pages_ok(struct pageint i;int reserved =0 ; +trace_page_free (page, order); +for (i =0 ; i < (1 << order) ; ++i) reserved +=free_pages_check (page + i);if (reserved)@@ -966,6 +969,8 @@ static void free_hot_cold_page(struct pastruct per_cpu_pages *pcp;unsigned long flags; +trace_page_free (page,0 ); +if (PageAnon (page)) page->mapping =NULL ;if (free_pages_check (page))@@ -1630,6 +1635,7 @@ nopage:show_mem (); } got_pg: +trace_page_alloc (page, order);return page; }Index:
linux-2.6-lttng/include/trace/page.h
===================================================================include/trace/page.h new file +0
-0
This name seems inconsitent with your other choices.
include/traec/page_alloc.h comes to mind
Quoted 18 lines
include/trace/page.h new file +16
-0@@ -0,0 +1,16 @@ +#ifndef _TRACE_PAGE_H +#define _TRACE_PAGE_H + +#include <linux/tracepoint.h> + +/* +* mm_page_alloc : page can be NULL. +*/ +DEFINE_TRACE (page_alloc, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); +DEFINE_TRACE (page_free, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); + +#endif
Re: [patch 12/17] LTTng instrumentation - page
Quoted 67 lines · * Peter Zijlstra ([email protected]) wrote:
Quoted 66 lines · Mathieu Desnoyers
plain text document attachment (lttng-instrumentation-page.patch) Paging activity instrumentation. Instruments page allocation/free to keep track of page allocation. This does not cover hugetlb activity, which is covered by a separate patch.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Signed-off-by Mathieu Desnoyers <[email protected]>CC Martin Bligh <[email protected]>CC Masami Hiramatsu <[email protected]>CC 'Peter Zijlstra' <[email protected]>CC "Frank Ch. Eigler" <[email protected]>CC 'Ingo Molnar' <[email protected]>CC 'Hideo AOKI' <[email protected]>CC Takashi Nishiie <[email protected]>CC 'Steven Rostedt' <[email protected]>CC Eduard - Gabriel Munteanu <[email protected]>--- include/trace/page.h | 16 ++++++++++++++++ mm/page_alloc.c | 6 ++++++ 2 files changed, 22 insertions(+)Index:
linux-2.6-lttng/mm/page_alloc.c
===================================================================mm/page_alloc.c +6
-0@@ -46,6 +46,7 @@#include <linux/page-isolation.h> #include <linux/memcontrol.h> #include <linux/debugobjects.h> +#include <trace/page.h> #include <asm/tlbflush.h> #include <asm/div64.h> @@ -510,6 +511,8 @@ static void __free_pages_ok(struct pageint i;int reserved =0 ; +trace_page_free (page, order); +for (i =0 ; i < (1 << order) ; ++i) reserved +=free_pages_check (page + i);if (reserved)@@ -966,6 +969,8 @@ static void free_hot_cold_page(struct pastruct per_cpu_pages *pcp;unsigned long flags; +trace_page_free (page,0 ); +if (PageAnon (page)) page->mapping =NULL ;if (free_pages_check (page))@@ -1630,6 +1635,7 @@ nopage:show_mem (); } got_pg: +trace_page_alloc (page, order);return page; }
Quoted 9 lines
include/trace/page.h
Quoted 4 lines
Index:
linux-2.6-lttng/include/trace/page.h
===================================================================include/trace/page.h new file +0
-0This name seems inconsitent with your other choices.
include/traec/page_alloc.hcomes to mind
Yes, good idea, will fix.
Mathieu
Quoted 19 lines
Quoted 18 lines
include/trace/page.h new file +16
-0@@ -0,0 +1,16 @@ +#ifndef _TRACE_PAGE_H +#define _TRACE_PAGE_H + +#include <linux/tracepoint.h> + +/* +* mm_page_alloc : page can be NULL. +*/ +DEFINE_TRACE (page_alloc, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); +DEFINE_TRACE (page_free, + TPPROTO(struct page *page, unsigned int order), +TPARGS (page, order)); + +#endif
Signature · 2 lines
Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 13/17 LTTng instrumentation - hugetlb
In reply to Mathieu DesnoyersInstrumentation of hugetlb activity (alloc/free/reserve/grab/release).
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
Changelog :
- instrument page grab, buddy allocator alloc, page release.
--- include/trace/hugetlb.h | 28 ++++++++++++++++++++++++++++ mm/hugetlb.c | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 12 deletions(-)
mm/hugetlb.c +29 -12
@@ -14,6 +14,7 @@#include <linux/mempolicy.h> #include <linux/cpuset.h> #include <linux/mutex.h> +#include <trace/hugetlb.h> #include <asm/page.h> #include <asm/pgtable.h>
@@ -123,6 +124,7 @@ static struct page *dequeue_huge_page_vmstatic void update_and_free_page (struct page *page) {int i; +trace_hugetlb_page_release (page); nr_huge_pages--; nr_huge_pages_node[page_to_nid (page)]--;for (i =0 ; i < (HPAGE_SIZE /PAGE_SIZE ); i++) {
@@ -141,6 +143,7 @@ static void free_huge_page(struct page *int nid =page_to_nid (page);struct address_space *mapping; +trace_hugetlb_page_free (page); mapping = (struct address_space *)page_private (page);set_page_private (page,0 );BUG_ON (page_count (page));
@@ -205,7 +208,8 @@ static struct page *alloc_fresh_huge_pagif (page) {if (arch_prepare_hugepage (page)) {__free_pages (page,HUGETLB_PAGE_ORDER ); -return NULL ; + page =NULL ; + goto end; }set_compound_page_dtor (page, free_huge_page);spin_lock (&hugetlb_lock);
@@ -214,7 +218,8 @@ static struct page *alloc_fresh_huge_pagspin_unlock (&hugetlb_lock);put_page (page);/* free it into the hugepage allocator */ } - +end: +trace_hugetlb_page_grab (page);return page; }
@@ -288,7 +293,8 @@ static struct page *alloc_buddy_huge_pagspin_lock (&hugetlb_lock);if (surplus_huge_pages >= nr_overcommit_huge_pages) {spin_unlock (&hugetlb_lock); -return NULL ; + page =NULL ; + goto end; }else { nr_huge_pages++; surplus_huge_pages++;
@@ -321,7 +327,8 @@ static struct page *alloc_buddy_huge_pag__count_vm_event (HTLB_BUDDY_PGALLOC_FAIL ); }spin_unlock (&hugetlb_lock); - +end: +trace_hugetlb_buddy_pgalloc (page);return page; }
@@ -510,6 +517,7 @@ static struct page *alloc_huge_page(struset_page_refcounted (page);set_page_private (page, (unsigned long ) mapping); } +trace_hugetlb_page_alloc (page);return page; }
@@ -1292,27 +1300,36 @@ out:int hugetlb_reserve_pages (struct inode *inode,long from,long to) { -long ret, chg; +int ret; +long chg; chg =region_chg (&inode->i_mapping->private_list, from, to); -if (chg <0 ) -return chg; +if (chg <0 ) { + ret = chg; + goto end; + } -if (hugetlb_get_quota (inode->i_mapping, chg)) -return -ENOSPC ; +if (hugetlb_get_quota (inode->i_mapping, chg)) { + ret = -ENOSPC ; + goto end; + } ret =hugetlb_acct_memory (chg);if (ret <0 ) {hugetlb_put_quota (inode->i_mapping, chg); -return ret; + goto end; }region_add (&inode->i_mapping->private_list, from, to); -return 0 ; +end: +trace_hugetlb_pages_reserve (inode, from, to, ret); +return ret; }void hugetlb_unreserve_pages (struct inode *inode,long offset,long freed) { -long chg =region_truncate (&inode->i_mapping->private_list, offset); +long chg; +trace_hugetlb_pages_unreserve (inode, offset, freed); + chg =region_truncate (&inode->i_mapping->private_list, offset);spin_lock (&inode->i_lock); inode->i_blocks -=BLOCKS_PER_HUGEPAGE * freed;spin_unlock (&inode->i_lock);
include/trace/hugetlb.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef _TRACE_HUGETLB_H +#define _TRACE_HUGETLB_H + +#include <linux/tracepoint.h> + +DEFINE_TRACE (hugetlb_page_release, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (hugetlb_page_grab, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (hugetlb_buddy_pgalloc, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (hugetlb_page_alloc, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (hugetlb_page_free, + TPPROTO(struct page *page), +TPARGS (page)); +DEFINE_TRACE (hugetlb_pages_reserve, + TPPROTO(struct inode *inode, long from, long to, int ret), +TPARGS (inode, from, to, ret)); +DEFINE_TRACE (hugetlb_pages_unreserve, + TPPROTO(struct inode *inode, long offset, long freed), +TPARGS (inode, offset, freed)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 14/17 LTTng instrumentation - net
In reply to Mathieu DesnoyersNetwork device activity instrumentation (xmit/receive). Allows to detect when a packet had arrived on the network card or when it is going to be sent. This is the instrumentation point outside of the drivers that is the closest to the hardware. It allows to detect the amount of time taken by a packet to go through the kernel between the system call and the actual delivery to the network card (given that system calls are instrumented).
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/net.h | 14 ++++++++++++++ net/core/dev.c | 3 +++ 2 files changed, 17 insertions(+)
net/core/dev.c +3 -0
@@ -121,6 +121,7 @@#include <linux/ctype.h> #include <linux/if_arp.h> #include <linux/if_vlan.h> +#include <trace/net.h> #include "net-sysfs.h"
@@ -1702,6 +1703,7 @@ int dev_queue_xmit(struct sk_buff *skb) } gso: +trace_net_dev_xmit (skb); txq = &dev->tx_queue;spin_lock_prefetch (&txq->lock);
@@ -2107,6 +2109,7 @@ int netif_receive_skb(struct sk_buff *sk__get_cpu_var (netdev_rx_stat).total++; +trace_net_dev_receive (skb);skb_reset_network_header (skb);skb_reset_transport_header (skb); skb->mac_len = skb->network_header - skb->mac_header;
include/trace/net.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _TRACE_NET_H +#define _TRACE_NET_H + +#include <net/sock.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (net_dev_xmit, + TPPROTO(struct sk_buff *skb), +TPARGS (skb)); +DEFINE_TRACE (net_dev_receive, + TPPROTO(struct sk_buff *skb), +TPARGS (skb)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 15/17 LTTng instrumentation - ipv4
In reply to Mathieu DesnoyersKeep track of interface up/down for ipv4. Allows to keep track of interface address changes in a trace.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
CC:
CC: Masami Hiramatsu <[email protected]>
CC: 'Peter Zijlstra' <[email protected]>
CC: "Frank Ch. Eigler" <[email protected]>
CC: 'Ingo Molnar' <[email protected]>
CC: 'Hideo AOKI' <[email protected]>
CC: Takashi Nishiie <[email protected]>
CC: 'Steven Rostedt' <[email protected]>
CC: Eduard - Gabriel Munteanu <[email protected]>
--- include/trace/ipv4.h | 14 ++++++++++++++ net/ipv4/devinet.c | 3 +++ 2 files changed, 17 insertions(+)
net/ipv4/devinet.c +3 -0
@@ -61,6 +61,7 @@#include <net/ip_fib.h> #include <net/rtnetlink.h> #include <net/net_namespace.h> +#include <trace/ipv4.h> static struct ipv4_devconf ipv4_devconf = { .data = {
@@ -257,6 +258,7 @@ static void __inet_del_ifa(struct in_devstruct in_ifaddr **ifap1 = &ifa1->ifa_next;while ((ifa = *ifap1) !=NULL ) { +trace_ipv4_addr_del (ifa);if (!(ifa->ifa_flags &IFA_F_SECONDARY ) && ifa1->ifa_scope <= ifa->ifa_scope) last_prim = ifa;
@@ -363,6 +365,7 @@ static int __inet_insert_ifa(struct in_i } ifa->ifa_flags |=IFA_F_SECONDARY ; } +trace_ipv4_addr_add (ifa); }if (!(ifa->ifa_flags &IFA_F_SECONDARY )) {
include/trace/ipv4.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _TRACE_IPV4_H +#define _TRACE_IPV4_H + +#include <linux/inetdevice.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (ipv4_addr_add, + TPPROTO(struct in_ifaddr *ifa), +TPARGS (ifa)); +DEFINE_TRACE (ipv4_addr_del, + TPPROTO(struct in_ifaddr *ifa), +TPARGS (ifa)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 16/17 LTTng instrumentation - ipv6
In reply to Mathieu DesnoyersInstrument addr_add and del of network interfaces. Lets a tracer know the interface address changes.
Those tracepoints are used by LTTng.
About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. See the "Tracepoints" patch header for performance result detail.
--- include/trace/ipv6.h | 14 ++++++++++++++ net/ipv6/addrconf.c | 4 ++++ 2 files changed, 18 insertions(+)
net/ipv6/addrconf.c +4 -0
@@ -85,6 +85,7 @@#include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <trace/ipv6.h> /* Set to 3 to get tracing... */ #define ACONF_DEBUG 2
@@ -650,6 +651,8 @@ ipv6_add_addr(struct inet6_dev *idev, co/* For caller */ in6_ifa_hold (ifa); +trace_ipv6_addr_add (ifa); +/* Add to big hash table */ hash =ipv6_addr_hash (addr);
@@ -2163,6 +2166,7 @@ static int inet6_addr_del(struct net *nein6_ifa_hold (ifp);read_unlock_bh (&idev->lock); +trace_ipv6_addr_del (ifp);ipv6_del_addr (ifp);/* If the last address is deleted administratively,
include/trace/ipv6.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _TRACE_IPV6_H +#define _TRACE_IPV6_H + +#include <net/if_inet6.h> +#include <linux/tracepoint.h> + +DEFINE_TRACE (ipv6_addr_add, + TPPROTO(struct inet6_ifaddr *ifa), +TPARGS (ifa)); +DEFINE_TRACE (ipv6_addr_del, + TPPROTO(struct inet6_ifaddr *ifa), +TPARGS (ifa)); + +#endif
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
PATCH 17/17 ftrace port to tracepoints
In reply to Mathieu DesnoyersPorting the trace_mark() used by ftrace to tracepoints. (cleanup)
Changelog :
- Change error messages : marker -> tracepoint
--- kernel/trace/trace_sched_switch.c | 120 ++++++--------------------------- kernel/trace/trace_sched_wakeup.c | 135 +++++++++----------------------------- 2 files changed, 58 insertions(+), 197 deletions(-)
kernel/trace/trace_sched_switch.c +24 -96
@@ -9,8 +9,8 @@#include <linux/debugfs.h> #include <linux/kallsyms.h> #include <linux/uaccess.h> -#include <linux/marker.h> #include <linux/ftrace.h> +#include <trace/sched.h> #include "trace.h"
@@ -19,16 +19,17 @@ static int __read_mostly tracer_enabled;static atomic_t sched_ref;static void -sched_switch_func (void *private,void *__rq,struct task_struct *prev, +probe_sched_switch (struct rq *__rq,struct task_struct *prev,struct task_struct *next) { -struct trace_array **ptr = private; -struct trace_array *tr = *ptr;struct trace_array_cpu *data;unsigned long flags;long disabled;int cpu; +if (!atomic_read (&sched_ref)) +return ; +tracing_record_cmdline (prev);tracing_record_cmdline (next);
@@ -37,95 +38,42 @@ sched_switch_func(void *private, void *_local_irq_save (flags); cpu =raw_smp_processor_id (); - data = tr->data[cpu]; + data = ctx_trace->data[cpu]; disabled =atomic_inc_return (&data->disabled);if (likely (disabled ==1 )) -tracing_sched_switch_trace (tr, data, prev, next, flags); +tracing_sched_switch_trace (ctx_trace, data, prev, next, flags);atomic_dec (&data->disabled);local_irq_restore (flags); } -static notrace void -sched_switch_callback (void *probe_data,void *call_data, -const char *format,va_list *args) -{ -struct task_struct *prev; -struct task_struct *next; -struct rq *__rq; - -if (!atomic_read (&sched_ref)) -return ; - -/* skip prev_pid %d next_pid %d prev_state %ld */ - (void )va_arg (*args, int); - (void )va_arg (*args, int); - (void )va_arg (*args, long); - __rq =va_arg (*args,typeof (__rq)); - prev =va_arg (*args,typeof (prev)); - next =va_arg (*args,typeof (next)); - -/* -* If tracer_switch_func only points to the local -* switch func, it still needs the ptr passed to it. -*/ -sched_switch_func (probe_data, __rq, prev, next); -} -static void -wakeup_func (void *private,void *__rq,struct task_struct *wakee,struct -task_struct *curr) +probe_sched_wakeup (struct rq *__rq,struct task_struct *wakee) { -struct trace_array **ptr = private; -struct trace_array *tr = *ptr;struct trace_array_cpu *data;unsigned long flags;long disabled;int cpu; -if (!tracer_enabled) +if (!likely (tracer_enabled))return ; -tracing_record_cmdline (curr); +tracing_record_cmdline (current);local_irq_save (flags); cpu =raw_smp_processor_id (); - data = tr->data[cpu]; + data = ctx_trace->data[cpu]; disabled =atomic_inc_return (&data->disabled);if (likely (disabled ==1 )) -tracing_sched_wakeup_trace (tr, data, wakee, curr, flags); +tracing_sched_wakeup_trace (ctx_trace, data, wakee, current, + flags);atomic_dec (&data->disabled);local_irq_restore (flags); } -static notrace void -wake_up_callback (void *probe_data,void *call_data, -const char *format,va_list *args) -{ -struct task_struct *curr; -struct task_struct *task; -struct rq *__rq; - -if (likely (!tracer_enabled)) -return ; - -/* Skip pid %d state %ld */ - (void )va_arg (*args, int); - (void )va_arg (*args, long); -/* now get the meat: "rq %p task %p rq->curr %p" */ - __rq =va_arg (*args,typeof (__rq)); - task =va_arg (*args,typeof (task)); - curr =va_arg (*args,typeof (curr)); - -tracing_record_cmdline (task); -tracing_record_cmdline (curr); - -wakeup_func (probe_data, __rq, task, curr); -} -static void sched_switch_reset (struct trace_array *tr) {int cpu;
@@ -140,60 +88,40 @@ static int tracing_sched_register(void) {int ret; - ret =marker_probe_register ("kernel_sched_wakeup" , -"pid %d state %ld ## rq %p task %p rq->curr %p" , - wake_up_callback, - &ctx_trace); + ret =register_trace_sched_wakeup (probe_sched_wakeup);if (ret) { -pr_info ("wakeup trace: Couldn't add marker" +pr_info ("wakeup trace: Couldn't activate tracepoint" " probe to kernel_sched_wakeup\n" );return ret; } - ret =marker_probe_register ("kernel_sched_wakeup_new" , -"pid %d state %ld ## rq %p task %p rq->curr %p" , - wake_up_callback, - &ctx_trace); + ret =register_trace_sched_wakeup_new (probe_sched_wakeup);if (ret) { -pr_info ("wakeup trace: Couldn't add marker" +pr_info ("wakeup trace: Couldn't activate tracepoint" " probe to kernel_sched_wakeup_new\n" ); goto fail_deprobe; } - ret =marker_probe_register ("kernel_sched_schedule" , -"prev_pid %d next_pid %d prev_state %ld " -"## rq %p prev %p next %p" , - sched_switch_callback, - &ctx_trace); + ret =register_trace_sched_switch (probe_sched_switch);if (ret) { -pr_info ("sched trace: Couldn't add marker" +pr_info ("sched trace: Couldn't activate tracepoint" " probe to kernel_sched_schedule\n" ); goto fail_deprobe_wake_new; }return ret; fail_deprobe_wake_new: -marker_probe_unregister ("kernel_sched_wakeup_new" , - wake_up_callback, - &ctx_trace); +unregister_trace_sched_wakeup_new (probe_sched_wakeup); fail_deprobe: -marker_probe_unregister ("kernel_sched_wakeup" , - wake_up_callback, - &ctx_trace); +unregister_trace_sched_wakeup (probe_sched_wakeup);return ret; }static void tracing_sched_unregister (void ) { -marker_probe_unregister ("kernel_sched_schedule" , - sched_switch_callback, - &ctx_trace); -marker_probe_unregister ("kernel_sched_wakeup_new" , - wake_up_callback, - &ctx_trace); -marker_probe_unregister ("kernel_sched_wakeup" , - wake_up_callback, - &ctx_trace); +unregister_trace_sched_switch (probe_sched_switch); +unregister_trace_sched_wakeup_new (probe_sched_wakeup); +unregister_trace_sched_wakeup (probe_sched_wakeup); }static void tracing_start_sched_switch (void )
kernel/trace/trace_sched_wakeup.c +34 -101
243 lines not on this page · raw message
Signature · 3 lines
Mathieu Desnoyers Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
Peter Zijlstra
maintainerQuoted 10 lines · Mathieu Desnoyers
Hi,
Here is the newest release of the Tracepoints, following the feedback from Peter Zijlstra. The main change is the creation of
include/trace/as a placeholder from tracepoint headers.The patchset applies over linux-next patch-v2.6.26-next-20080715 in this order :
#This a separate RCU update upon which the tracepoints depend rcu-read-sched.patch
ACK
Quoted 3 lines
tracepoints.patch
tracepoints-documentation.patch
tracepoints-samples.patch
3x ACK
Quoted 11 lines
lttng-instrumentation-irq.patch
lttng-instrumentation-scheduler.patch
lttng-instrumentation-timer.patch
lttng-instrumentation-kernel.patchlttng-instrumentation-filemap.patch
lttng-instrumentation-swap.patch
lttng-instrumentation-memory.patch
lttng-instrumentation-page.patch
lttng-instrumentation-hugetlb.patch
Quoted 3 lines
lttng-instrumentation-net.patch
lttng-instrumentation-ipv4.patch
lttng-instrumentation-ipv6.patch
posted individual comments where I saw some
Quoted 1 line
ftrace-port-to-tracepoints.patch
Nice cleanup..
Hi Mathieu,
As far as I can see, your patchset can be separated into several series of patches. Would you think this series of patches should be pushed at once, or could be pushed individually?
I think it is hard to push all of them into kernel at once, because it needs ACKs from several developers who maintain traced subsystems.
So, I'd like to suggest you to separate series of patches, and to push framework and instrumentation patches step by step. What would you think about it?
Thank you,
Quoted 34 lines · Mathieu Desnoyers
Hi,
Here is the newest release of the Tracepoints, following the feedback from Peter Zijlstra. The main change is the creation of
include/trace/as a placeholder from tracepoint headers.The patchset applies over linux-next patch-v2.6.26-next-20080715 in this order :
#This a separate RCU update upon which the tracepoints depend rcu-read-sched.patch
tracepoints.patch
tracepoints-documentation.patch
tracepoints-samples.patchlttng-instrumentation-irq.patch
lttng-instrumentation-scheduler.patch
lttng-instrumentation-timer.patch
lttng-instrumentation-kernel.patchlttng-instrumentation-filemap.patch
lttng-instrumentation-swap.patch
lttng-instrumentation-memory.patch
lttng-instrumentation-page.patch
lttng-instrumentation-hugetlb.patchlttng-instrumentation-net.patch
lttng-instrumentation-ipv4.patch
lttng-instrumentation-ipv6.patchftrace-port-to-tracepoints.patch
Mathieu
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected]